Настройка Java JTable Ширина столбца

У меня есть JTable, в котором я устанавливаю размер столбца следующим образом:

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);

Это отлично работает, но когда таблица максимизирована, я получаю пустое пространство справа от последнего столбца. Можно ли изменить размер последнего столбца до конца окна при изменении размера?

Я нашел свойство AUTO_RESIZE_LAST_COLUMN в документах, но он не работает.

Изменить: JTable находится в JScrollPane, его размер задан.

Ответ 1

Что произойдет, если вы вызываете setMinWidth(400) в последнем столбце вместо setPreferredWidth(400)?

В JavaDoc для JTable внимательно прочитайте документы для doLayout(). Вот несколько битов выбора:

Когда метод вызывается в результате изменения размера закрывающего окна, resizingColumn - null. Это означает, что изменение размера произошло "вне" JTable и изменение - или "дельта" - должно быть распределено по всем столбцам независимо от этот режим автоматического изменения размера JTable.

Возможно, поэтому AUTO_RESIZE_LAST_COLUMN вам не помогло.

Примечание. Когда JTable корректирует ширину столбцов, он уважает их минимальные и максимальные значения.

Это говорит о том, что вы можете установить Min == Max для всех, кроме последних столбцов, затем установите Min = Preferred в последнем столбце и либо не установите Max, либо установите очень большое значение для Max.

Ответ 2

С JTable.AUTO_RESIZE_OFF таблица не изменит размер любого из столбцов для вас, так что это займет ваш предпочтительный параметр. Если ваша цель состоит в том, чтобы столбцы были по умолчанию для вашего предпочтительного размера, за исключением того, что последний столбец заполняет остальную часть панели, вы можете использовать JTable.AUTO_RESIZE_LAST_COLUMN autoResizeMode, но это может быть наиболее эффективно при использовании с TableColumn.setMaxWidth() вместо TableColumn.setPreferredWidth() для всех, кроме последнего столбца.

Как только вы убедитесь, что AUTO_RESIZE_LAST_COLUMN действительно работает, вы можете поэкспериментировать с комбинацией TableColumn.setMaxWidth() и TableColumn.setMinWidth()

Ответ 3

JTable.AUTO_RESIZE_LAST_COLUMN определяется как "Во время всех операций изменения размера применять корректировки только к последнему столбцу", что означает, что вы должны установить autoresizemode в конце вашего кода, в противном случае setPreferredWidth ( ) ни на что не повлияет!

Так что в вашем случае это будет правильный путь:

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);

Ответ 4

Используйте этот метод

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;
    }

Или расширьте класс JTable:

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;
        }
    }
}

И затем

table.setColumnWidths(30, 150, 100, 100);

Ответ 5

Считая замечание Клеопатры (ее второй раз она предложила взглянуть на javax.swing.JXTable, и теперь мне жаль, что я не посмотрел в первый раз:)) Я предлагаю вам перейти по ссылке

У меня было это решение для той же проблемы: (но я предлагаю вам перейти по ссылке выше) При изменении размера таблицы уменьшите ширину столбца таблицы до текущей общей ширины таблицы. для этого я использую глобальный массив ints для (относительных) ширины столбцов):

private int[] columnWidths=null;

Я использую эту функцию для установки ширины столбца таблицы:

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);
    }

}

При настройке данных я вызываю:

    setColumnWidths(this.columnWidths);

и при изменении Я вызываю ComponentListener, установленный родительским элементом таблицы (в моем случае JScrollPane, который является контейнером моей таблицы):

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

обратите внимание, что таблица JTable также глобальна:

private JTable table;

И здесь я устанавливаю слушателя:

    scrollPane=new JScrollPane(table);
    scrollPane.addComponentListener(this);

Ответ 6

fireTableStructureChanged();

по умолчанию изменит поведение! Если этот метод вызывается где-то в вашем коде ПОСЛЕ того, как вы установили свойства изменения размера столбца, все ваши настройки будут reset. Этот побочный эффект может происходить косвенно. F.E. как следствие изменения связанной модели данных способом, вызываемым этим методом после установки свойств.

Ответ 7

Используйте этот код. Это сработало для меня. Я рассмотрел для 3 столбцов. Измените значение цикла для вашего кода.

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);
        }

Ответ 8

Нет необходимости в этой опции, просто сделайте максимальную ширину последнего столбца максимальной, и она займет все дополнительное пространство.

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(Integer.MAX_INT);