10

I'm building and app with multiple JTables and I need to detect when cell value change occurs so I can update it in the database. I tried TableModelListener and overriding tableChanged, but it fires only when I click away (click on another row) after I have edited a cell.

Any other way to do this?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Igor
  • 1,532
  • 4
  • 23
  • 44
  • I think that is possible to add Listener, everything depends of your XxxCellEditor, but safer way could be waiting after cell is validated on StopCellEdit (the same with MsExcell, without VBA/VBE), otherwise you have in risk – mKorbel Oct 10 '12 at 16:01
  • @mKorbel what kind of listener? I already tried TableModelListener. – Igor Oct 10 '12 at 16:09
  • not to add proper listener to the JComponent that representing Editor, – mKorbel Oct 10 '12 at 16:10
  • 1
    If possible, I'd try and wait till `setValueAt` on the table model is called, personally – MadProgrammer Oct 10 '12 at 19:32

4 Answers4

21

You can implement the CellEditorListener interface, as shown in this example. Note that JTable itself is a CellEditorListener.

It may also be convenient to terminate the edit when focus is lost, as shown here:

table.putClientProperty("terminateEditOnFocusLost", true);

More Swing client properties may be found here.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • +1 ooo... I like. Too bad these properties are annoying/difficult to find documentation on. – Nick Rippe Oct 10 '12 at 21:36
  • 1
    Do you think it's a good idea to use `TableModelListener and `tableChanged()`? – Igor Nov 01 '12 at 19:31
  • Out of context, _good_ is hard to measure. Try to cover all normal exit paths and use a UPS. – trashgod Nov 01 '12 at 19:39
  • @trashgod And how about `JTextArea`/`JTextPane`? Is there an event listener similar to this, where I don't have to use `DocumentListener` and update the database every time a character is entered? An event that fires on "`JTextArea` end edit" if what I'm after. – Igor Nov 06 '12 at 16:56
  • You could stash a working copy of the content in `java.util.Preferences`, as a hedge, and clear it on database commit. `VK_Enter` is bound to `insert-break`, so you'd need another gesture. – trashgod Nov 06 '12 at 17:50
5

I'm agreeing with @mKorbel - unless all your input is checkboxes and dropdowns, you're going to want to wait until the cell editing is stopped (you don't want to commit to the database every time a letter is typed in a textbox).

If the problem is that it's not committing after focus has gone to another component, add a FocusListener that stops editing the table when focus is lost on the table:

Example:

final JTable table = new JTable();
table.addFocusListener(new FocusAdapter() {
    @Override
    public void focusLost(FocusEvent e) {
        TableCellEditor tce = table.getCellEditor();
        if(tce != null)
            tce.stopCellEditing();
    }
});
Nick Rippe
  • 6,465
  • 14
  • 30
  • Thanks, this looks promising. I'll try it out. But, what if the program is closed before focus is lost? – Igor Oct 10 '12 at 20:23
  • Unless it's a natural closing (not killed by the task manager or someone using System.exit in the code), I'm 90% sure the focus lost adapter will fire. If not there's also the `WindowListener` that listens for the window closing. – Nick Rippe Oct 10 '12 at 21:21
  • Nope, it doesn't fire. But, I stop Cell Edit on app exit :) for all tables. I used @trashgod's simpler code to stop the editng when focus is lost and I now I just can't decide if I should save all changes on exit, or use the table model listener. I'm sure both will work now, but, which answer do I choose? I used trahsgod's code to sop cell editing and your idea to stick with not commiting everytime a letter is typed in. – Igor Oct 11 '12 at 08:53
  • 1
    Strange - It's seems I need to be more than 90% sure about things. Good to know! – Nick Rippe Oct 11 '12 at 16:12
  • @Igor: For reference, `java.util.Preferences` makes a (platform-specific) best effort to record the last value `put()`. – trashgod Oct 15 '12 at 15:53
0

I use the enter key so everytime a user hit enter the cell will update.

    DefaultTableModel dtm = new DefaultTableModel(data, columnNames);
    JTable table = new JTable(dtm);

    table.addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ENTER) {

                int row = table.getSelectedRow();
                int column = table.getSelectedColumn();

                // resul is the new value to insert in the DB
                String resul = table.getValueAt(row, column).toString();
                // id is the primary key of my DB
                String id = table.getValueAt(row, 0).toString();

                // update is my method to update. Update needs the id for
                // the where clausule. resul is the value that will receive
                // the cell and you need column to tell what to update.
                update(id, resul, column);

            }
        }
    });
Jan Ziesse
  • 469
  • 6
  • 9
0

This is also handy if you want to stop the editing on an event handler from selection change or save button.

if (table.isEditing())
    table.getCellEditor().stopCellEditing();