it-swarm.com.de

Java JTable-Einstellung Spaltenbreite

Ich habe eine JTable, in der ich die Spaltengröße wie folgt eingestellt habe:

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getColumnModel().getColumn(0).setPreferredWidth(27);
table.getColumnModel().getColumn(1).setPreferredWidth(120);
table.getColumnModel().getColumn(2).setPreferredWidth(100);
table.getColumnModel().getColumn(3).setPreferredWidth(90);
table.getColumnModel().getColumn(4).setPreferredWidth(90);
table.getColumnModel().getColumn(6).setPreferredWidth(120);
table.getColumnModel().getColumn(7).setPreferredWidth(100);
table.getColumnModel().getColumn(8).setPreferredWidth(95);
table.getColumnModel().getColumn(9).setPreferredWidth(40);
table.getColumnModel().getColumn(10).setPreferredWidth(400);

Das funktioniert gut, aber wenn die Tabelle maximiert ist, bekomme ich einen leeren Platz rechts von der letzten Spalte. Ist es möglich, die Größe der letzten Spalte an das Ende des Fensters anzupassen, wenn die Größe geändert wird?

Ich habe AUTO_RESIZE_LAST_COLUMN-Eigenschaft in docs gefunden, aber es funktioniert nicht.

Bearbeiten: JTable befindet sich in einer JScrollPane, deren bevorzugte Größe festgelegt ist.

84
Hamza Yerlikaya

Was passiert, wenn Sie setMinWidth(400) in der letzten Spalte statt von setPreferredWidth(400) aufrufen?

Lesen Sie die Anweisungen für doLayout() im JavaDoc für JTable sehr sorgfältig. Hier sind einige Auswahlbits:

Wenn die Methode als Ergebnis der Größenänderung eines umgebenden Fensters aufgerufen wird, wird die resizingColumn ist null. Dies bedeutet, dass die Größenänderung "außerhalb" der JTable .__ erfolgt ist. und die Änderung - oder das "Delta" - sollte unabhängig von .__ an alle Spalten verteilt werden. Der automatische Größenänderungsmodus dieser JTable. 

Dies könnte der Grund sein, warum AUTO_RESIZE_LAST_COLUMN Ihnen nicht geholfen hat.

Hinweis: Wenn eine JTable die Breite der Spalten anpasst, beachtet sie deren Minimal- und Maximalwerte absolut. 

Dies bedeutet, dass Sie Min == Max für alle außer den letzten Spalten festlegen möchten, dann Min = Preferred für die letzte Spalte und entweder Max nicht festlegen oder einen sehr großen Wert für Max festlegen.

41
Eddie

Mit JTable.AUTO_RESIZE_OFF ändert die Tabelle nicht die Größe einer der Spalten für Sie, daher wird Ihre bevorzugte Einstellung übernommen. Wenn es Ihr Ziel ist, die Spalten standardmäßig auf Ihre bevorzugte Größe zu setzen, mit der Ausnahme, dass die letzte Spalte den Rest des Bereichs ausfüllt, haben Sie die Möglichkeit, JTable.AUTO_RESIZE_LAST_COLUMN autoResizeMode zu verwenden, sie kann jedoch am effektivsten sein, wenn sie mit TableColumn.setMaxWidth() anstelle von verwendet wird TableColumn.setPreferredWidth () für alle außer der letzten Spalte. 

Sobald Sie überzeugt sind, dass AUTO_RESIZE_LAST_COLUMN tatsächlich funktioniert, können Sie mit einer Kombination aus TableColumn.setMaxWidth() und TableColumn.setMinWidth() experimentieren. 

22
akf

JTable.AUTO_RESIZE_LAST_COLUMN ist definiert als "Bei allen Größenänderungsoperationen werden Änderungen nur auf die letzte Spalte angewendet" was bedeutet, dass Sie den autoresizemode am Ende Ihres Codes setzen müssen , andernfalls wirkt sich setPreferredWidth () auf nichts aus !

In Ihrem Fall wäre dies der richtige Weg:

table.getColumnModel().getColumn(0).setPreferredWidth(27);
table.getColumnModel().getColumn(1).setPreferredWidth(120);
table.getColumnModel().getColumn(2).setPreferredWidth(100);
table.getColumnModel().getColumn(3).setPreferredWidth(90);
table.getColumnModel().getColumn(4).setPreferredWidth(90);
table.getColumnModel().getColumn(6).setPreferredWidth(120);
table.getColumnModel().getColumn(7).setPreferredWidth(100);
table.getColumnModel().getColumn(8).setPreferredWidth(95);
table.getColumnModel().getColumn(9).setPreferredWidth(40);
table.getColumnModel().getColumn(10).setPreferredWidth(400);
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
10
Rico Ocepek

Verwenden Sie diese Methode

public static void setColumnWidths(JTable table, int... widths) {
    TableColumnModel columnModel = table.getColumnModel();
    for (int i = 0; i < widths.length; i++) {
        if (i < columnModel.getColumnCount()) {
            columnModel.getColumn(i).setMaxWidth(widths[i]);
        }
        else break;
    }

Oder erweitern Sie die JTable-Klasse:

public class Table extends JTable {
    public void setColumnWidths(int... widths) {
        for (int i = 0; i < widths.length; i++) {
            if (i < columnModel.getColumnCount()) {
                columnModel.getColumn(i).setMaxWidth(widths[i]);
            }
            else break;
        }
    }
}

Und dann

table.setColumnWidths(30, 150, 100, 100);
5
Oleg Mikhailov

Ich lese die Bemerkung von Kleopatra (ihr zweites Mal schlug sie vor, javax.swing.JXTable anzusehen, und jetzt tut es mir leid, dass ich das erste Mal nicht geschaut habe :)) .__ Folge dem Link

Ich hatte diese Lösung für dasselbe Problem: (Ich schlage jedoch vor, dass Sie dem Link oben folgen.) Bei der Größenänderung der Tabelle skalieren Sie die Breiten der Tabellenspalten auf die aktuelle Gesamtbreite der Tabelle. Dazu verwenden Sie ein globales Array ints für die (relative) Spaltenbreite):

private int[] columnWidths=null;

Ich verwende diese Funktion, um die Spaltenbreiten der Tabelle festzulegen:

public void setColumnWidths(int[] widths){
    int nrCols=table.getModel().getColumnCount();
    if(nrCols==0||widths==null){
        return;
    }
    this.columnWidths=widths.clone();

    //current width of the table:
    int totalWidth=table.getWidth();

    int totalWidthRequested=0;
    int nrRequestedWidths=columnWidths.length;
    int defaultWidth=(int)Math.floor((double)totalWidth/(double)nrCols);

    for(int col=0;col<nrCols;col++){
        int width = 0;
        if(columnWidths.length>col){
            width=columnWidths[col];
        }
        totalWidthRequested+=width;
    }
    //Note: for the not defined columns: use the defaultWidth
    if(nrRequestedWidths<nrCols){
        log.fine("Setting column widths: nr of columns do not match column widths requested");
        totalWidthRequested+=((nrCols-nrRequestedWidths)*defaultWidth);
    }
    //calculate the scale for the column width
    double factor=(double)totalWidth/(double)totalWidthRequested;

    for(int col=0;col<nrCols;col++){
        int width = defaultWidth;
        if(columnWidths.length>col){
            //scale the requested width to the current table width
            width=(int)Math.floor(factor*(double)columnWidths[col]);
        }
        table.getColumnModel().getColumn(col).setPreferredWidth(width);
        table.getColumnModel().getColumn(col).setWidth(width);
    }

}

Beim Einstellen der Daten rufe ich an:

    setColumnWidths(this.columnWidths);

beim Ändern rufe ich den ComponentListener-Satz auf das übergeordnete Element der Tabelle auf (in meinem Fall das JScrollPane-Objekt, das der Container meiner Tabelle ist):

public void componentResized(ComponentEvent componentEvent) {
    this.setColumnWidths(this.columnWidths);
}

beachten Sie, dass die JTable-Tabelle auch global ist:

private JTable table;

Und hier habe ich den Hörer eingestellt:

    scrollPane=new JScrollPane(table);
    scrollPane.addComponentListener(this);
4
michel.iamit
fireTableStructureChanged();

wird das Größenänderungsverhalten standardmäßig festlegen ! Wenn diese Methode irgendwo in Ihrem Code aufgerufen wird, nachdem Sie die Spaltengrößeneigenschaften festgelegt haben, werden alle Ihre Einstellungen zurückgesetzt. Diese Nebenwirkung kann indirekt auftreten. F.e. Wenn das verknüpfte Datenmodell auf eine Weise geändert wird, wird diese Methode aufgerufen, nachdem die Eigenschaften festgelegt wurden.

1
count0

Verwenden Sie diesen Code. Es hat für mich funktioniert. Ich dachte für 3 Spalten. Ändern Sie den Schleifenwert für Ihren Code.

TableColumn column = null;
        for (int i = 0; i < 3; i++) {
            column = table.getColumnModel().getColumn(i);
            if (i == 0) 
                column.setMaxWidth(10);
            if (i == 2)
                column.setMaxWidth(50);
        }
0
Arijit