Search code examples
javaswingjtabletablemodel

Listen jtable change


I have a problem with table model listener. It doesn't work, and I don't know why. I have tried different methods, and read a lot of questions here, but haven't found the solution. I've read this: Listening to JTable changes and this Row refreshing when cell is edited but it doesn't work. I also have read this and this but result is the same.

Here is my code. First of all definition of the 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());
        }
    }

Here is the model listener class:

public class NGramsTableListener implements TableModelListener {

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

And the table model 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);
    }
 }

Actually I need to get updated object with coords(rowIndex, colIndex), because later I want get updated object and object with coords(rowIndex-1, colIndex) if exists.

Where is my mistake?

Thanks


Solution

  • You need to provide a method which will fireXXX notified all registered listeners for example:

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

    }