Настройка Java JTable Ширина столбца - PullRequest
86 голосов
/ 05 июня 2009

У меня есть 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 установлен его предпочтительный размер.

Ответы [ 7 ]

42 голосов
/ 05 июня 2009

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

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

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

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

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

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

22 голосов
/ 05 июня 2009

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

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

11 голосов
/ 23 января 2014

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 голосов
/ 01 июня 2016

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

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 голосов
/ 12 декабря 2011

Чтение замечания Клеопатры (во второй раз она предложила взглянуть на 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);
1 голос
/ 06 июня 2012
fireTableStructureChanged();

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

0 голосов
/ 19 мая 2014

Используйте этот код. Это сработало для меня. Я считал за 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);
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...