TaninDirect
TaninDirect

Reputation: 458

Preserve selected model row in sorted JTable across model update

I'm having difficulties getting the following code to preserve the logically selected row in the model if the JTable has been sorted.

It works as intended when no sorting is applied.

private void updateAccountTable() {
    accountsTable = guiFrame.getAccountsTable();

    // Preserve selected model row
    String accountNumber = "";
    int selectedRow = accountsTable.getSelectedRow();
    if(selectedRow >= 0){
        accountNumber = (String)accountsTable.getValueAt(selectedRow, 0);
    }

    // Preserve sort order
          // Keep eclipse happy.  better way??
    List <? extends SortKey> keys = accountsTable.getRowSorter().getSortKeys();

    // Update displayed accounts
    DefaultTableModel model = (DefaultTableModel) accountsTable.getModel();
    model.getDataVector().clear();

    Object[][] tableContents = accountList.getAccountsAsArray(true);
    model.setDataVector(tableContents, tableHeaders);
    model.fireTableDataChanged();

    // reset sort order
    accountsTable.getRowSorter().setSortKeys(keys);

    // If updated model contains previously selected account, reselect
    if (!accountNumber.equals("") && null != accountList.getAccount(accountNumber)){
        for (int row=0; row<accountsTable.getRowCount(); row++){
            String an = (String)accountsTable.getValueAt(row, 0);
            if (an.equalsIgnoreCase(accountNumber)){
                accountsTable.setRowSelectionInterval(row, row);
                break;
            }
        }
    }
    else {
        accountsTable.clearSelection();
    }
}

Unfortunately setRowSelectionInterval() doesn't updated the selected row as expected, despite being called with the correct view row number. It seems to do nothing.

.....So,

Why is setRowSelectionInterval() failing to updated the selection, or what have I missed?

Upvotes: 1

Views: 2665

Answers (2)

realpac
realpac

Reputation: 572

When you click on Jtable header to sort it, and click on a row (ex. 3rd row), you will get the value of unsorted JTable's row. To avoid this situation, use this LOC.(ik this is irrelvant to what you're trying to do but for others w/ similar problems)

int row = tblUser.getSelectedRow();
//Without below line, the value you get would be the row before sorting
int correctModel = tblUser.convertRowIndexToModel(row);
//Get username and use it to find its corresponding tuple
String username = (tblUser.getModel().getValueAt(correctModel, 1)).toString();

My table looks like this and Im trying to get the username of the selected row and w/o the 2nd LOC, I'd get the unsorted JTable's row value even after sorting it:

---------------------
|  id    |   username |
---------------------
|        |            | 

Upvotes: 0

trashgod
trashgod

Reputation: 205785

The row obtained from getSelectedRow() is in view coordinates, while the model coordinates have been changed by the intervening update. Quoting from the relevant tutorial section:

This distinction does not matter unless your viewed data has been rearranged by sorting, filtering, or user manipulation of columns.

You will need to use the conversion methods described near the end of Sorting and Filtering, which suggests:

When using a sorter, always remember to translate cell coordinates.

Upvotes: 2

Related Questions