Налаштування 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 JTableдля doLayout()дуже уважно читайте документи . Ось декілька варіантів вибору:

Коли метод викликається в результаті зміни розміру вікна, що додається, розмір колонки є нульовим. Це означає, що зміна розміру відбулося "поза" JTable, а зміна - або "дельта" - повинна бути розподілена на всі стовпці незалежно від режиму автоматичного зміни розміру цього JTable.

Це може бути, чому вам AUTO_RESIZE_LAST_COLUMNне допомогли.

Примітка: Коли JTable вносить корективи в ширину стовпців, він абсолютно поважає їх мінімальні та максимальні значення.

Це говорить про те, що ви можете встановити Min == Max для всіх, крім останніх стовпців, а потім встановити Min = Бажано в останньому стовпці, або не встановити Max, або встановити дуже велике значення для Max.


1
setMinWidth (400) все ще спричиняє порожнє право таблиці
Hamza Yerlikaya

2
Спробуйте додати setMaxWidth (10000), щоб побачити, чи це має значення.
Едді

1
Видаліть рядок table.setAutoResizeMode (JTable.AUTO_RESIZE_OFF); Це може запобігти зміні розміру, який потрібно.
Едді

Ви, мабуть, також хочете встановити мінімальний та максимальний розміри на самому JTable, якщо ви ще цього не зробили,
Едді

3
Переконайтеся, що ви здійснили виклик 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, таблиця змінюється відповідно до панелі прокрутки, моя мета - мати таблицю з певним розміром хв, але змусити її зростати, якщо вона більша, ніж мін.
Hamza Yerlikaya

Ви можете мати таку поведінку, якщо замість TableColumn.setMaxWidth () використовуєте TableColumn.setMinWidth ().
akf

щоб додати до мого останнього коментаря: використовуйте TableColumn.setMinWidth () для кожного стовпця вашої таблиці, включаючи останній стовпець.
akf

встановлення як мінімальної, так і максимальної ширини вирішило проблему, але тепер смуги прокрутки є місін.
Hamza Yerlikaya

14

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

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 , і тепер мені шкода, що я не подивився перший раз :)) Я пропоную вам перейти за посиланням

У мене було таке рішення для тієї ж проблеми: (але я пропоную вам перейти за посиланням вище). Змініть розмір стовпчика таблиці до загальної ширини поточної таблиці. для цього я використовую глобальний масив 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);

1
наскільки я бачу, це (дуже крихкий) злом: він не оновлюється при зміні користувачем ширини стовпця. Знову я б запропонував заглянути в вихідний код JXTable - у нього є додаткове властивість horizontalScroll, яке запускає заповнення доступної ширини, якщо сума префіксів стовпців менша за поточну ширину і показує горизонтальну смугу прокрутки в іншому випадку
kleopatra

Я знаю, що він не реагує на те, що користувач змінює ширину таблиці вручну, таким чином це зламання ... але знову ж таки: це краще, ніж було запропоновано вище. Але ти мене цікавив JXTable .... я буду дивитись там! (і приємно знову
завітати

Ви мали рацію, дивіться мою зауваження поверх моєї відповіді, я підтримав ваше зауваження!
michel.iamit

Принаймні, це було корисно для мене, я використовував такий підхід для свого випадку з принципом ваги стовпців.
Солостаран14

2
fireTableStructureChanged();

за замовчуванням поведінка зміни розміру ! Якщо цей метод викликається десь у вашому коді ПІСЛЯ ви встановили властивості зміни розміру стовпця, усі ваші налаштування будуть скинуті. Цей побічний ефект може статися побічно. Fe як наслідок зміни пов'язаної моделі даних способом виклику цього методу після встановлення властивостей.


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

-1

Використовуйте цей код. У мене це спрацювало. Я розглядав 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);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.