JTable возвращает значения JComboBox и JCheckBox в значения после выбора - PullRequest
0 голосов
/ 03 ноября 2018

У меня есть JTable со столбцом JComboBox<Integer> с и столбцом JCheckBox с. JTable устанавливается с соответствующими средствами визуализации и редакторами. Вначале таблица выглядит хорошо, но после выбора значения из поля со списком или флажка ячейки возвращаются к значениям Integer и Boolean. Эта проблема выглядит не просто косметической, так как методы, которые ожидают, что ячейка с комбобоксом или флажком выдают ошибки при поиске целого числа или логического значения.

Вот изображение того, на что это похоже:

enter image description here

А вот и код:

    dataTable.removeAll();
    numberOfVariables = 7;
    Object[] header = new Object[numberOfVariables];
    header[0] = new String("Ring Number");
    header[1] = new String("Radius (cm)");
    header[2] = new String("Plume Distribution");
    header[3] = new String("Thickness (A)");
    header[4] = new String("Deposition Time (s)");
    header[5] = new String("Rate (A/s)");
    header[6] = new String("Optimize (y/n)");

    Object[][] data = new Object[numberOfRings][numberOfVariables];
    for(int k=0;k<numberOfRings;++k){
        Object[] row = new Object[numberOfVariables];
        row[0] = Integer.toString(k+1);
        row[1] = String.format("%.2f", plume.getRingRadius(k));
        row[2] = createDistributionComboBoxForRing(k);
        row[3] = String.format("%.2f", plume.getThicknessOfRing(k));
        row[4] = String.format("%.2f", plume.getTimeForRing(k));
        row[5] = String.format("%.2f", plume.getRateForRing(k));
        row[6] = new JCheckBox();
        ((JCheckBox) row[6]).setSelected(true);
        data[k] = row;
    }
    tableModel = new DefaultTableModel(data,header);
    dataTable.setModel(tableModel);
    dataTable.getColumnModel().getColumn(2).setCellRenderer(new ControlTableRenderer());
    //dataTable.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor( createDistributionComboBoxForRing(0) ));
    dataTable.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor( (JComboBox<Integer>) data[0][2] ));
    dataTable.getColumnModel().getColumn(6).setCellRenderer(new ControlTableRenderer());
    dataTable.getColumnModel().getColumn(6).setCellEditor(new DefaultCellEditor( (JCheckBox) data[0][6] ));
    dataTable.updateUI();

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018
row[2] = createDistributionComboBoxForRing(k);
row[3] = String.format("%.2f", plume.getThicknessOfRing(k));
row[4] = String.format("%.2f", plume.getTimeForRing(k));
row[5] = String.format("%.2f", plume.getRateForRing(k));
row[6] = new JCheckBox();
((JCheckBox) row[6]).setSelected(true);

TableModel для JTable хранит данные, а не компоненты.

Таким образом, если столбец 3 содержит объект Integer, тогда вы сохраняете Integer в TableModel и устанавливаете редактор для столбца как поле со списком, содержащим список допустимых целых чисел.

То же самое для столбца, содержащего флажок рендерер / редактор. В этом случае вы сохраняете объект Boolean.

Например:

row[2] = new Integer(1);
row[6] = Boolean.TRUE

Теперь в TableModel вы должны указать таблице, какой тип данных в каждом столбце, поэтому вам нужно переопределить метод getColumnClass(...). Что-то вроде:

tableModel = new DefaultTableModel(data,header)
{
    @Override
    public Class getColumnClass(int column)
    {
        switch (column)
        {
            case 2: return Integer.class;
            case 6: return Boolean.class;
            default: return Object.class;
        }
    }
};

Теперь в таблице можно выбрать соответствующий рендерер и редактор для каждого столбца.

Однако в случае поля со списком вам необходимо создать пользовательский редактор со значениями для поля со списком. См. Раздел из учебника Swing по Использование комбинированного окна в качестве редактора для рабочего примера того, как это сделать.

Кроме того, вы неправильно используете другие методы:

dataTable.removeAll();

Не уверен, для чего это. Это метод контейнера для удаления компонентов с панели. Все, что вам нужно, это оператор setModel(...) для сброса таблицы.

dataTable.updateUI();

Нет необходимости использовать метод updateUI (). Этот метод используется внутри, когда изменяется LAF. Вы не меняете LAF, поэтому избавьтесь от этого утверждения.

0 голосов
/ 03 ноября 2018

Идея средств визуализации и редактирования ячеек состоит в том, что у вас есть только один компонент, который перемещается и данные меняются для каждой строки. Код использует различный экземпляр JComponent для каждой ячейки. Просто поместите данные в табличную модель и позвольте средствам визуализации ячеек и редакторам управлять компонентами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...