JTable с JComboBox в качестве редактора - удаление текущей строки

Я хочу реализовать JTable, в котором есть один столбец с JComboBox в качестве редактора. Я хочу, чтобы в моей таблице изначально была только одна строка. После установки значения в ComboBox я хочу, чтобы моя таблица была заполнена некоторыми значениями в зависимости от выбранного элемента JComboBox. После выбора непустого элемента я хочу добавить новую строку в таблицу. Когда имеется несколько непустых строк и кто-то устанавливает значение n-го поля со списком пустым, я хочу удалить строку из таблицы.

Простое решение не работает:

TableColumn column = table.getColumnModel().getColumn(2);
JComboBox comboBox = new JComboBox();
comboBox.addItem("");
comboBox.addItem("1");
comboBox.addItem("2");
comboBox.addItem("3");
comboBox.addItem("4");
comboBox.addItem("5");
comboBox.addItemListener(new ItemListener() {
    public void itemStateChanged(ItemEvent e) {
        JComboBox combo = (JComboBox)e.getSource();
        if (combo.getSelectedItem() != null) {
            if (combo.getSelectedItem().equals("")) {
                table.getTableModel().removeRow(table.getSelectedRow());
            } else {
                table.getTableModel().addRow(new Object[] {null, null, null, null});
            }
        }
    }
});
column.setCellEditor(new DefaultCellEditor(comboBox));

person karex    schedule 25.02.2014    source источник
comment
вам нужно будет переопределить setValueAt в XxxTableModel вместо прослушивания ItemListener, тогда проблем с ....   -  person mKorbel    schedule 25.02.2014


Ответы (1)


В соответствии с рекомендациями mKorbel просто реализуйте эту логику в своем TableModel setValueAt(...) методе. вот простой пример:

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

public class Example extends JFrame {

    private JTable table;

    public Example(){
        table = getTable();
        add(new JScrollPane(table));

        pack();
        setVisible(true);
    }

    private JTable getTable() {
        table = new JTable(new DefaultTableModel(3,3){
            @Override
            public void setValueAt(Object aValue, int row, int column) {
                super.setValueAt(aValue, row, column);
                if(column == 2){
                    if(aValue.toString().isEmpty()){
                        removeRow(row);
                    } else {
                        addRow(new Object[] {null, null, null});
                    }
                }
            }
        });
        TableColumn column = table.getColumnModel().getColumn(2);
        JComboBox<String> comboBox = new JComboBox<>(new String[]{"","1","2","3","4","5"});
        column.setCellEditor(new DefaultCellEditor(comboBox));
        return table;
    }

    public static void main(String[] values){
        new Example();
    }

}
person alex2410    schedule 25.02.2014
comment
У меня сейчас нет доступа к моему ПК, поэтому у меня есть другой вопрос: вызывается ли setValueAt только при изменении значения или мне нужно добавить проверку, изменилось ли значение? - person karex; 25.02.2014
comment
Вам нужно проверить, изменилось ли значение, потому что setValueAt(...) вызывается всегда, когда вы заканчиваете редактировать ячейку. - person alex2410; 25.02.2014