处理 TableModelEvent 时是否允许修改 JTable 的模型?

Is modifying model of JTable allowed while processing TableModelEvent?

我想知道如何实现这样的行为,当该行的特定列中的值更改为某个固定值时,我可以从 JTable 中删除该行。

我尝试使用 TableModelListener 来做到这一点,但没有达到预期效果。我的问题与以下事实有关:当我在处理 UPDATE TableModelEvent 时修改模型时,我谴责自己处理可能修改的模型(事件源)与事件本身之间的不一致。换句话说,可以根据 table.

模型的不同状态生成事件
void onTableChanged(TableModelEvent tableModelEvent)
{
    MyTableModel model = (MyTableModel)e.getSource();
    if ( e.getType() == TableModelEvent.UPDATE){
        MyObject myObject = (MyObject)model.getValueAt(e.getFirstRow(), e.getColumn());
        if ( myObject.getSomeProperty().equals("DELETE ME")){
          model.removeRow(e.getFirstRow()); // does it look like asking for troubles?
        }            
    }
}

现在想象一下,我们有一种方法可以让我们一次更新多行。

class MyObject {
    private String someProperty;

    //...getters/setters
}

class MyTableModel extends AbstractTableModel {
    private static int SOME_PROPERTY_COL = 1;     
    private final List<MyObject> data;

    public MyTableModel(List<MyObject> data)
    {
        this.data = data;
    }

    //...

    void update(int[] modelIndices, String newSomePropertValue)
    {
        for (int i = 0; i < modelIndices.length; i++){
            data[modelIndices[i]].setSomeProperty(newSomePropertyValue);
            fireCellUpdated(modelIndices[i], SOME_PROPERTY_COL);
        }
    }
}

TableModelEvent 中的 rowIndex、colIndex 与模型在第二时间的状态以及由于在 MyTableModel 对象上调用 update(int[], String) 方法而收到的后续事件在此类实现中存在不一致。

我认为问题来自于这样一个事实,即我尝试在接收基于此源的某些特定状态生成的事件时修改事件源,但这也不是问题,例如,如果任何事件指示模式的改变与模型的修改交织在一起,以及根据模型的旧状态生成的其他一些事件?

我最终想要实现的是允许我根据 table 中某些列的值将行从一个 table 移动到另一个 table 的实现。

所以假设其中一个单元格是一个组合框,有 2 个值,我们有两个 tables,当单元格中的值更改为 table1 时,行从当前 table 至 table1。我认为使用 TableModelListener 是正确的解决方案,但我可以看到在此方法中修改模型不是一个好主意,不是吗?

model.removeRow(e.getFirstRow()); // does it look like asking for troubles?

将代码包装在 SwingUtilities.invokeLater(...) 中。

现在代码将添加到事件调度线程 (EDT) 的末尾,因此 table 处理和 table 模型侦听器处理可以在行删除完成之前正常完成。

SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        model.removeRow(e.getFirstRow());
    }
});

此外,在您的 update() 方法中,您需要以相反的模型行顺序更新模型的数据。这样,当您删除行时,索引不正确就没有问题了。