It seems like what you want is to be able to sort the table but then be able to add more rows without the table sort order being changed. Even though it is possible, you'll have to rewrite the DefaultRowSorter
and TableRowSorter
(source available for both). The reason is that the current implementation is designed to keep a consistent sort order (without considering when the rows were added). You probably won't be able to extend TableRowSorter to overcome this issue since it's parent class has a lot of private functions tied to the design I just described.
What I described above is the clean way. Here is another way you can do it, do this each time you want to insert a new row:
Save the current sort order of the view in a map. I used a hashmap (postion
) to map each object in row i of the sort column to it's position in the view. position.put(tableModel.getValueAt(i, column), sorter.convertRowIndexToView(i));
Create a comparator that will use the map created above to sort the incoming data. Set the column comparator of the TableRowSorter to the newly created comparator. Then call sorter.sort()
, which is necessary because DefaultRowSorter
needs to cache the comparator. The comparator will put the existing objects in their current position and put new objects (created during insertion) at the end.
Perform the row insertion into the table model. In my code I add 3 random Integer, Boolean, and Double values to the 3 columns in my table.
Remove the comparator added in #3 by setting value to null, sorter.setComparator(sortKeys.get(0).getColumn(), null);
This way the next time the sort is toggled on the column, it will use the default comparator instead of the dummy one.
Complete code is below. It is intended to add a row to the table each time the button is pressed. Please note I have not tested this with sortkeys > 1 or filters (I'll leave that to you). Let me know what you think of this hack.
private void insertRowButtonActionPerformed(java.awt.event.ActionEvent evt) {
TableRowSorter<TableModel> sorter = (TableRowSorter<TableModel>)jTable1.getRowSorter();
final HashMap<Object, Integer> position = new HashMap<Object, Integer>();
List<? extends SortKey> sortKeys = sorter.getSortKeys();
if(!sortKeys.isEmpty()){
SortKey sortKey = sortKeys.get(0);
int column = sortKey.getColumn();
TableModel tableModel = sorter.getModel();
int n = sorter.getModelRowCount();
final SortOrder sortOrder = sortKey.getSortOrder();
for(int i=0;i<n;i++){
position.put(tableModel.getValueAt(i, column), sorter.convertRowIndexToView(i));
}
//add dummy comparator
sorter.setComparator(column, new Comparator<Object>(){
public int compare(Object o1, Object o2) {
int obj1Position = position.containsKey(o1) ? position.get(o1):position.size();
int obj2Position = position.containsKey(o2) ? position.get(o2):position.size();
return sortOrder == SortOrder.DESCENDING ? obj2Position - obj1Position:obj1Position - obj2Position;
}
});
sorter.sort();
}
/////////////insert row///////////////////
DefaultTableModel tableModel = (DefaultTableModel)jTable1.getModel();
tableModel.addRow(new Object[]{rand.nextInt(), rand.nextBoolean(), rand.nextDouble()});
/////////////end insert row///////////////
//remove dummy comparator
if(!sortKeys.isEmpty()){
sorter.setComparator(sortKeys.get(0).getColumn(), null);
}
}