Как сделать столбцы в JTable невидимыми для Swing Java

Я разработал один графический интерфейс, в котором я использовал один JTable, из которого я должен сделать 2 столбца невидимыми. Как мне это сделать?


person om.    schedule 29.09.2009    source источник


Ответы (8)


Удалите TableColumn из TableColumnModel.

TableColumnModel tcm = table.getColumnModel();
tcm.removeColumn( tcm.getColumn(...) );

Если вам нужен доступ к данным, используйте table.getModel().getValueAt(...).

Более сложное решение, которое позволяет пользователю скрывать/показывать столбцы по своему усмотрению, можно найти в Диспетчер столбцов таблицы.

person camickr    schedule 29.09.2009
comment
это действительно правильный способ сделать это - установка ширины на 0 является своего рода подделкой. Таким образом, у вас все еще есть данные в вашей модели; вы просто скрываете часть представления. - person M1EK; 30.09.2009
comment
Даже при описанном выше подходе данные все еще находятся в модели, поэтому вы можете получить к ним доступ, как показано выше. Так работает MVC. Все, что мы делаем, это меняем представление. Когда вы устанавливаете ширину на 0, попробуйте табуляцию, когда вы нажмете на скрытый столбец, фокус исчезнет, ​​пока вы снова не нажмете табуляцию. Это запутает пользователей. - person camickr; 30.09.2009
comment
Это работает, за исключением одной вещи, которая делает этот подход бесполезным. Когда вы хотите узнать, какой столбец выбран, вы получите неправильный (сдвинутый) индекс столбца. Другими словами, выполнение table.getColumnModel().getSelectedColumns() даст вам неправильный столбец. - person Dima; 16.10.2011
comment
На самом деле я был неправ... Выполнение column.getModelIndex() дает правильную позицию в модели. Просто не используйте table.getSelectedColumn() - это даст неверный индекс. - person Dima; 16.10.2011
comment
@ Дима, ты должен понимать разницу между view и model. Табличные методы всегда относятся к представлению. JTable API имеет множество convertXXX методов, которые вы можете использовать. Таким образом, вы могли бы использовать convertColumnIndexToModel(...) - person camickr; 16.10.2011
comment
@xmedeko действительно полное решение — использовать SwingX :-) - person kleopatra; 19.08.2012

Сначала удалите столбец из представления

 table.removeColumn(table.getColumnModel().getColumn(4));

Затем извлеките данные из модели.

table.getModel().getValueAt(table.getSelectedRow(),4);

Следует отметить, что при извлечении данных они должны извлекаться из модели, а не из таблицы.

person zawhtut    schedule 21.03.2013
comment
Как удалить из модели? - person partho; 04.02.2016

Я попробовал 2 возможных решения, которые оба работают, но возникли проблемы с 1-м решением.

   table.removeColumn(table.getColumnModel().getColumn(4));

or

   table.getColumnModel().getColumn(4).setMinWidth(0);
   table.getColumnModel().getColumn(4).setMaxWidth(0);
   table.getColumnModel().getColumn(4).setWidth(0);

В моем недавнем случае я предпочел второе решение, потому что добавил TableRowSorter.

   TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
   table.setRowSorter(sorter);

При использовании table.removeColumn(table.getColumnModel().getColumn(4)) он физически удалит столбец из представления/таблицы, поэтому вы не можете использовать table.getValueAt(row, 4) — он возвращает ArrayIndexOutOfBounds. Единственный способ получить значение удаленного столбца — вызвать table.getModel().getValueAt(table.getSelectedRow(),4). Поскольку TableRowSorter сортирует только то, что находится в таблице, но не данные в объекте DefaultTableModel, проблема заключается в том, что вы получаете значение после сортировки записей. - он будет извлекать данные из DefaultModelObject, которые не отсортированы.

Поэтому я использовал второе решение, а затем использовал table.getValueAt(table.getSelectedRow(),4);

Единственная проблема, которую я вижу со вторым подходом, была упомянута @camickr: «Когда вы устанавливаете ширину на 0, попробуйте использовать табуляцию, когда вы нажимаете на скрытый столбец, фокус исчезает, пока вы снова не нажмете табуляцию. Это запутает пользователей». < /эм>

person Mr. Xymon    schedule 03.05.2012
comment
Используйте `table.getModel().getValueAt(table.convertRowIndexToModel(row), 4). - person xmedeko; 29.06.2012

у меня была та же проблема, и из-за того, что я использую TableColumnModel removColumn();, мне это не помогает, поэтому я использовал это

table.getColumnModel().getColumn(0).setWidth(0);
table.getColumnModel().getColumn(0).setMinWidth(0);
table.getColumnModel().getColumn(0).setMaxWidth(0); 

и у меня сработало нормально, он скрывает столбец 0, и я все еще могу получить от него значение

person Anti Atlas Dev    schedule 26.01.2016

Установите минимальную, максимальную и «нормальную» ширину на 0:

jTable.getColumn("ABC").setMinWidth(0); // Must be set before maxWidth!!
jTable.getColumn("ABC").setMaxWidth(0);
jTable.getColumn("ABC").setWidth(0);

Примечание. Поскольку вы не можете установить maxWidthminWidth, сначала необходимо изменить minWidth (javadoc). То же самое верно и для width.

Второй подход заключается в расширении TableColumnModel и переопределении всех методов, чтобы создать иллюзию (для JTable), что в вашей модели нет этих двух столбцов.

Поэтому, когда вы скрываете столбец, вы должны вернуть на один меньше, когда таблица запрашивает количество столбцов, а когда она запрашивает столбец X, вам, возможно, придется добавить +1 к индексу столбца (в зависимости от того, находится ли он слева). или справа от скрытого столбца) и т. д.

Пусть ваша новая табличная модель перенаправляет все вызовы методов (с исправленными индексами и т. д.) в фактическую модель столбцов и использует новую табличную модель в JTable.

person Aaron Digulla    schedule 29.09.2009
comment
Вы также должны установить минимальную и максимальную ширину. - person Aaron Digulla; 29.09.2009
comment
Почему порядок важен, я попробовал это первым, и я не использовал тот же порядок, поэтому он не работает, oec я использовал тот же порядок (ширина, минимум, максимум), он работает, так ПОЧЕМУ? - person Mohammed Housseyn Taleb; 05.11.2016
comment
@MohammedHousseynTaleb Интересно. Кажется, это не простые сеттеры. Я предполагаю, что прослушиватели устанавливаются для обновления макета, а макет в Swing ‹s›иногда‹/s›обычно удивляет. - person Aaron Digulla; 09.11.2016
comment
@MohammedHousseynTaleb, спасибо за комментарий. Я также сделал это в неправильном порядке и теперь посмотрел в коде: this.maxWidth = Math.max(minWidth, maxWidth); Теперь должно быть ясно. Если для minWidth установлено значение 10, а вы хотите установить для maxWidth значение 0, тогда потребуется minWidth... На самом деле это также упоминается в javadoc (но я тоже не читал) - person Tomate_Salat; 22.05.2019

Если вы удалите столбец из JTable, столбец все еще будет присутствовать в TableModel.

Например, чтобы удалить первый столбец идентификатора:

TableColumnModel tcm = table.getColumnModel();
tcm.removeColumn(tcm.getColumn(0));

Если вы хотите получить доступ к значению удаленного столбца, вы должны получить к нему доступ через функцию getValueAt TableModel, а не JTable. Но вам нужно преобразовать rowIndex обратно в rowIndex в модели.

Например, если вы хотите получить доступ к первому столбцу выбранной строки:

int modelRow = table.convertRowIndexToModel(table.getSelectedRow());
int value = (Integer)table.getModel().getValueAt(modelRow,0);
person Foltin    schedule 06.04.2019

Я пробовал их все: они не помогают. ЛУЧШИЙ способ - создать новую модель таблицы без столбца, который вы хотите удалить. Вот как вы это делаете:

table = (DefaultTableModel) <table name>.getModel();
DefaultTableModel table1 = new DefaultTableModel();
Vector v = table.getDataVector();
Vector v1 = newvector(v,<column index you want to delete>);

Vector newvector(Vector v,int j){
    Vector v1= new Vector();
    try{
        Vector v2;
        Object[] o = v.toArray();
        int i =0;
        while(i<o.length){
            v2 = (Vector) o[i];
            v2.remove(j);
            v1.add(v2);
            i++;
        }
    }
    catch(Exception e){
        JOptionPane.showMessageDialog(null,"Error in newvector \n"+e);
    }
    return v1;
}

Vector getColumnIdentifiers(int i) {
    Vector columnIdentifiers = new Vector();
    int j=0;
    while(j<i){
        columnIdentifiers.add(("c"+(j+1)));
        j++;
    }
    return columnIdentifiers;
}
table1.setDataVector(v1,getColumnIdentifiers((<column count>-1)));
<table name>.setModel(table1);
person Rijul Gupta    schedule 18.08.2012

Вы можете создать подкласс модели и переопределить TableModel.getColumnCount следующим образом:

int getColumnCount() {
    return super.getColumnCount()-2;
}

В этом случае последние два столбца не будут отображаться в таблице JTable.

person Maurice Perry    schedule 29.09.2009
comment
но могу ли я получить данные от них? - person om.; 29.09.2009
comment
вы только создаете иллюзию того, что столбцов нет, но они все еще есть, и поэтому вы должны иметь возможность получать данные по-прежнему - person dharga; 29.09.2009
comment
Но как мне скрыть их от GUI. - person om.; 29.09.2009
comment
Не уверен, что понимаю, что вы имеете в виду. Вы имеете в виду, что пользователь вашего приложения должен иметь возможность скрывать или показывать? - person Maurice Perry; 29.09.2009
comment
Привет, я решил эту проблему, используя следующий код: jtable.removeColumn(jtable.getColumnModel().getColumn()); Столбец скрывается от графического интерфейса, и мы также можем получить из него сохраненное значение. - person om.; 29.09.2009