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

Ещё по теме:

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: