Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preserve JTable selection across TableModel change

We're seeing JTable selection get cleared when we do a fireTableDataChanged() or fireTableRowsUpdated() from the TableModel.

Is this expected, or are we doing something wrong? I didn't see any property on the JTable (or other related classes) about clearing/preserving selection on model updates.

If this is default behavior, is there a good way to prevent this? Maybe some way to "lock" the selection before the update and unlock after?

The developer has been experimenting with saving the selection before the update and re-applying it. It's a little slow.

This is Java 1.4.2 on Windows XP, if that matters. We're limited to that version based on some vendor code we use.

like image 259
John M Avatar asked Oct 31 '08 16:10

John M


2 Answers

You need to preserve the selection and then re-apply it.

First of all you will need to get a list of all the selected cells.

Then when you re-load the JTable with the new data you need to programmatically re-apply those same selections.

The other point I want to make is, if the number or rows or columns in your table are increasing or decreasing after each table model reload, then please don't bother preserving the selection.

The user could have selected row 2 column 1 having a value say "Duck", before model updation. But after model updation that same data can now occur in row 4 column 1, and your original cell row 2 column 1 could have new data such as "Pig". Now if you forcibly set the selection to what it was before the model updation, this may not be what the user wanted.

So programmatically selecting cells could be a double edged sword. Don't do it, if you are not sure.

like image 137
Swapnonil Mukherjee Avatar answered Sep 27 '22 21:09

Swapnonil Mukherjee


You can automatically preserve a table's selection if the STRUCTURE of that table hasn't changed (i.e. if you haven't add/removed any columns/rows) as follows.

If you've written your own implementation of TableModel, you can simply override the fireTableDataChanged() method:

@Override
public void fireTableDataChanged() {
    fireTableChanged(new TableModelEvent(this, //tableModel
        0, //firstRow
        getRowCount() - 1, //lastRow 
        TableModelEvent.ALL_COLUMNS, //column 
        TableModelEvent.UPDATE)); //changeType
}

and this should ensure that your selection is maintained provided that only the data and not the structure of the table has changed. The only difference between this, and what would be called if this method weren't overridden is that getRowCount() - 1 is passed for the lastRow argument instead of Integer.MAX_VALUE, the latter of which acts a signifier that not only has all the data in the table changed but that the number of rows may have as well.

like image 26
Peter Berg Avatar answered Sep 27 '22 21:09

Peter Berg