Java Swing: шаблон модели таблицы
Java Swing устарел. Не настолько, чтобы стать ненужным, и не так, чтобы с ним было бы невозможно написать хороший интерфейс. Но он устарел достаточно, чтобы программирование интерфейсов стало рутинным и утомительным процессом. Таблицы используются часто, даже очень. Для создания кастомной модели реализуется интерфейс javax.swing.table.TableModel или (чаще) наследуются от javax.swing.table.AbstractTableModel. Но каша из столбцов, констант, индексов и наименований столбцов превращает поддержку модели в ад. Самой ненавистной мною частью является хранение наименований и типов классов в отдельных переменных. Такое можно увидеть и в официальной документации:
class MyTableModel extends AbstractTableModel {
private String[] columnNames = ...//same as before...
private Object[][] data = ...//same as before...
...
}
Из-за этого в других частях кода я часто вижу использование неименованных индексов столбцов и сравнение их по имени. Вот вам совет: используйте перечисления для работы с колонками таблицы:
public enum IntegerFormatColumns {
/**
* Значение, как оно есть.
*/
SIMPLE {
@Override
public Object getValue(Integer i) {
return i;
}
// переопределяем тип возвращаемого значения
@Override
public Class<?> getColumnClass() {
return Integer.class;
}
},
/**
* Шестнадцатиричное представление числа.
*/
HEX {
@Override
public Object getValue(Integer i) {
return Integer.toHexString(i);
}
},
/**
* Двоичное представление числа.
*/
BINARY {
@Override
public Object getValue(Integer i) {
return Integer.toBinaryString(i);
}
}
;
/**
* Метод, который извлекает показываемое значение из исходных данных
* @param i исходные данные
* @return отображаемый в таблице результат
*/
public abstract Object getValue(Integer i);
/**
* Метод извлечения названия столбца таблицы.
*
* Для примера название извлекается из именования элемента перечисления.
*
* @return название столбца таблицы.
*/
public String getColumnName() {
return name();
}
/**
* Метод извлечения класса отображаемого результата.
*
* По умолчанию, это класс {@link String}.
*
* @return класс отображаемого результата
*/
public Class<?> getColumnClass() {
return String.class;
}
}
Используем этот класс в модели:
public static class IntegerFormatModel extends AbstractTableModel {
private final List<Integer> values = new ArrayList<>();
@Override
public int getRowCount() {
return values.size();
}
@Override
public int getColumnCount() {
return IntegerFormatColumns.values().length;
}
@Override
public String getColumnName(int column) {
return IntegerFormatColumns.values()[column].getColumnName();
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return IntegerFormatColumns.values()[columnIndex].getColumnClass();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return IntegerFormatColumns.values()[columnIndex].getValue(values.get(rowIndex));
}
}
Бесплатно вы получите возможность добавлять/изменять/удалять столбцы без вмешательства в саму модель и простой способ получения индекса столбца:
int index = IntegerFormatColumns.HEX.ordinal();
Ещё по теме: