监听 jtable 变化

Listen jtable change

我对 table 模型侦听器有疑问。它不起作用,我不知道为什么。我尝试了不同的方法,并在这里阅读了很多问题,但还没有找到解决方案。 我读过这个:Listening to JTable changes and this Row refreshing when cell is edited 但它不起作用。 我也看过 this and this 但结果是一样的。

这是我的代码。首先定义table:

private void prepareTable(JTable table, Map<String, String> tableData, int colsCount, int rowsCount, int nGram) {
        //Load data, set model, remove header
        NGramsTableModel nGramModel = new NGramsTableModel(tableData, allowedSymbols, colsCount, rowsCount, nGram);
        nGramModel.addTableModelListener(new NGramsTableListener());
        table.setModel(nGramModel);
        table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
        table.setTableHeader(null);

        //Set editor
        JTextField jtf = new JTextField();
        jtf.setDocument(new NGramsTableCellDocument(nGram));
        table.setDefaultEditor(String.class, new DefaultCellEditor(jtf));

        //Colorize rows
        for (int i = 0; i < table.getColumnModel().getColumnCount(); i++) {
            table.getColumnModel().getColumn(i).setCellRenderer(new NGramsTableCellRenderer());
        }
    }

这是模型监听器class:

public class NGramsTableListener implements TableModelListener {

    @Override
    public void tableChanged(TableModelEvent e) {
        System.out.println("something changed...");
        System.out.println(e);
    }
}

和 table 模型 class:

public class NGramsTableModel extends AbstractTableModel implements TableModel {
    private Set<TableModelListener> listeners = new HashSet<TableModelListener>();
    ...
    ...
    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        ...
        //it's OK, i see this message with entered symbols
        System.out.println("setValueAt: " + aValue);
        //I tried use every of this, but it doesn't work. A don't see any massage from NGramsTableListener class
        fireTableCellUpdated(rowIndex, columnIndex);
        fireTableDataChanged();
        fireTableRowsInserted(rowIndex, columnIndex);
        fireTableRowsUpdated(rowIndex, columnIndex);
    }

    @Override
    public void addTableModelListener(TableModelListener l) {
        listeners.add(l);
    }

    @Override
    public void removeTableModelListener(TableModelListener l) {
        listeners.remove(l);
    }
 }

实际上我需要用 coords(rowIndex, colIndex) 获取更新的对象,因为稍后我想用 coords(rowIndex-1, colIndex) 获取更新的对象和对象(如果存在的话)。

我的错误在哪里?

谢谢

您需要提供一个方法,让 fireXXX 通知所有已注册的侦听器,例如:

public class NGramsTableModel extends AbstractTableModel implements TableModel {
private LinkedList<TableModelListener> listeners = new LinkedList<TableModelListener>();
...
...
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    ...
    //it's OK, i see this message with entered symbols
    System.out.println("setValueAt: " + aValue);
    //Use your fireXXX method
    fireNGramTableChanged();
}

@Override
public void addTableModelListener(TableModelListener l) {
    listeners.add(l);
}

@Override
public void removeTableModelListener(TableModelListener l) {
    listeners.remove(l);
}

protected void fireNGramTableChanged(){
   for(TableModelListener next : listeners){
     next.tableChanged(new TableModelEvent());
   }
}

}

AbstractTableModel 已经实现了 table 模型侦听器方法。这就是扩展 AbstractTableModel 的好处。您的问题的解决方案是摆脱所有这些代码。

当您扩展 AbstractTableModel 时,您负责实现 TableModel 的其他方法,例如 getColumnClass()、getValueAt(...)、setValueAt(...) 等。