Java JTable,JComboBox作为编辑器-删除当前行

Java JTable,JComboBox作为编辑器-删除当前行,java,swing,jtable,jcombobox,tablecelleditor,Java,Swing,Jtable,Jcombobox,Tablecelleditor,我想实现一个JTable,其中有一列使用JComboBox作为编辑器。我希望我的表最初只有一行。在ComboBox中设置值后,我希望根据JComboBox的选定元素,用一些值填充我的表。选择非空元素后,我想向表中添加新行。当有多行不为空,并且有人将第n个combobox的值设置为空时,我想从表中删除该行 简单的解决方案不起作用: TableColumn column = table.getColumnModel().getColumn(2); JComboBox comboBox = new J

我想实现一个
JTable
,其中有一列使用
JComboBox
作为编辑器。我希望我的表最初只有一行。在
ComboBox
中设置值后,我希望根据
JComboBox
的选定元素,用一些值填充我的表。选择非空元素后,我想向表中添加新行。当有多行不为空,并且有人将第n个combobox的值设置为空时,我想从表中删除该行

简单的解决方案不起作用:

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

正如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();
    }

}
import javax.swing.DefaultCellEditor;
导入javax.swing.JComboBox;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.table.DefaultTableModel;
导入javax.swing.table.TableColumn;
公共类示例扩展了JFrame{
专用JTable表;
公共示例(){
table=getTable();
添加(新JScrollPane(表));
包装();
setVisible(真);
}
私有JTable getTable(){
表=新的JTable(新的DefaultTableModel(3,3){
@凌驾
public void setValueAt(对象有效、整行、整列){
super.setValueAt(aValue、row、column);
如果(列==2){
if(aValue.toString().isEmpty()){
(世界其他地区);
}否则{
addRow(新对象[]{null,null,null});
}
}
}
});
TableColumn column=table.getColumnModel().getColumn(2);
JComboBox组合框=新的JComboBox(新字符串[]{“,”1“,”2“,”3“,”4“,”5“});
column.setCellEditor(新的DefaultCellEditor(组合框));
返回表;
}
公共静态void main(字符串[]值){
新例子();
}
}

您需要在XxxTableModel中覆盖setValueAt,而不是通过ItemListener进行监听,这样就没有问题了……我现在无法访问我的PC程序,所以我有另一个问题:setValueAt是否仅在值发生更改时调用,或者我需要添加检查值是否发生更改的选项?您需要检查值是否发生了更改,因为编辑完单元格后,
setValueAt(…)
始终调用。