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

95

У меня есть 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желаемый размер.

Хамза Ерликая
источник

Ответы:

45

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

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

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

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

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

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

Эдди
источник
1
setMinWidth (400) по-прежнему приводит к тому, что правая часть таблицы остается пустой
Hamza Yerlikaya
2
Попробуйте добавить setMaxWidth (10000), чтобы увидеть, имеет ли это значение.
Эдди
1
Удалите строку table.setAutoResizeMode (JTable.AUTO_RESIZE_OFF); Это может помешать изменению размера, который вы хотите.
Эдди
Вы, вероятно, также захотите установить минимальный и максимальный размер в самом JTable, если вы еще этого не сделали,
Эдди
4
Убедитесь, что вы выполнили вызов setMinWidth после применения модели таблицы ... Это меня однажды сбило с толку .
Брайан Ноблауч
23

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

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

АКФ
источник
1
Когда используется AUTO_RESIZE_LAST_COLUMN, размер таблицы изменяется в соответствии с панелью прокрутки, моя цель - иметь таблицу определенного минимального размера, но увеличивать ее, если она больше моего минимального размера.
Хамза Ерликая
У вас может быть такое поведение, если вы используете TableColumn.setMinWidth () вместо TableColumn.setMaxWidth ().
akf 05
чтобы добавить к моему последнему комментарию: используйте TableColumn.setMinWidth () для каждого столбца в вашей таблице, включая последний столбец.
akf 05
установка минимальной и максимальной ширины решила проблему, но теперь полосы прокрутки отсутствуют.
Хамза Ерликая
16

JTable.AUTO_RESIZE_LAST_COLUMNопределяется как «Во время всех операций изменения размера применять настройки только к последнему столбцу», что означает, что вы должны установить режим автоматического изменения размера в конце вашего кода , иначе 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);
Рико Очепек
источник
5

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

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);
Олег Михайлов
источник
4

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

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

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);
michel.iamit
источник
1
Насколько я понимаю, это (очень хрупкий) хакер: он не обновляется при изменении пользователем ширины столбца. Опять же, я предлагаю вам изучить исходный код JXTable - у него есть дополнительное свойство horizontalScroll, которое запускает заполнение доступной ширины, если сумма параметров столбца меньше текущей ширины, и в противном случае показывает горизонтальную полосу прокрутки
kleopatra
Я знаю, что он не реагирует на изменение пользователем ширины таблицы вручную, таким образом, это взлом ... но опять же: это лучше, чем было предложено выше. Но вы меня заинтересовали JXTable .... Я посмотрю туда! (и приятно снова зайти к вам по теме стола :))
michel.iamit
Вы были правы, посмотрите мое замечание поверх моего ответа, я поддержал ваше замечание!
michel.iamit
По крайней мере, это было полезно для меня, я использовал этот подход для своего случая с принципом веса столбца.
Solostaran14 08
2
fireTableStructureChanged();

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

count0
источник
1

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

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);
Дэвид Ньюкомб
источник
0

Этот код у меня работает без setAutoResizeModes.

        TableColumnModel columnModel = jTable1.getColumnModel();
        columnModel.getColumn(1).setPreferredWidth(170);
        columnModel.getColumn(1).setMaxWidth(170);
        columnModel.getColumn(2).setPreferredWidth(150);
        columnModel.getColumn(2).setMaxWidth(150);
        columnModel.getColumn(3).setPreferredWidth(40);
        columnModel.getColumn(3).setMaxWidth(40);
Харша Сампатх
источник
-2

Используйте этот код. У меня это сработало. Считал за 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);
}
Ариджит
источник