0

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

Community
  • 1
  • 1
Alexander
  • 357
  • 4
  • 20

2 Answers2

1

The AbstractTableModel already implements the table model listener methods. That is the benefit of extending AbstractTableModel. The solution to your problem is to get rid of all that code.

When you extend AbstractTableModel you are responsible for implementing the other methods of TableModel, like getColumnClass(), getValueAt(...), setValueAt(...) etc.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • What do you mean any examples? You just remove the code from your class related to the TableModelListener. So basically of the code you posted get rid of all the methods except the `setValueAt(...)` method. – camickr May 05 '15 at 16:48
  • I removed everything related to listeners and "implements tableModel" now it works fine without any additional methods. – Alexander May 05 '15 at 18:19
  • @Alex, so if this is the proper solution you should "accept" this answer so people reading this question don't get confused about which solution to use. – camickr May 05 '15 at 19:26
0

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

}

Lexover
  • 96
  • 1
  • 4
  • awesome! It works, thanks! But why so? I've add only 1 listener. TableModel doesn't know which one? – Alexander May 05 '15 at 14:26
  • There is no need to implement the table model listener code, the AbstractTableModel does this for you. That is the benefit of extending AbstractTableModel. – camickr May 05 '15 at 15:11