Reputation: 21
I have a Java JTable which stores about 8000 rows, with 10 columns, and all works well.
When I click on a column header, the whole JTable will be sorted by the data in that column in ascending order in the first instance, clicking again will then sort the data in descending order.
I would like to change this behaviour on one specific column (double column - stores %'s) so that the first click will sort the data in descending order, and the second click will then be ascending - as I am most interested in the entries with the highest %s.
This is not about changing the original sort order when the table is first presented. The table is originally sorted by ID number (first column) ascending which is what I want.
This is about changing the behaviour when re-sorting based on other columns, so that the first click will be descending order.
Any one got any ideas?
Upvotes: 2
Views: 3042
Reputation: 1594
I extended the TableRowSorter class to get the desired effect. In my case I wanted to sort all columns descending first, except for the first column. The following code allows to specify which columns should be sorted ascending first.
/** Class sorting table descending on first click unless column is specified
* in constructor to follow standard behaviour (ascending on first click).
* @author Adam Jagosz */
class NormallyDescendingSorter extends TableRowSorter {
/** columns to be sorted in a standard way, ascending on first click */
ArrayList<Integer> ascendingColumns;
/** Constructor
* @param model table model to be sorted
* @param ascendingColumns columns to follow ascending sort on first click */
public NormallyDescendingSorter(TableModel model, int... ascendingColumns) {
super(model);
this.ascendingColumns = new ArrayList<>();
for (int index = 0; index < ascendingColumns.length; index++)
{
this.ascendingColumns.add(ascendingColumns[index]);
}
}
/**
* Method sorting table rows upon clicking on column header
* @param column column to sort by */
@Override
public void toggleSortOrder(int column) {
if(ascendingColumns.contains(column)) {
super.toggleSortOrder(column);
return;
}
ArrayList<SortKey> sortKeys = new ArrayList<>(getSortKeys());
if(sortKeys.isEmpty() || sortKeys.get(0).getColumn() != column) {
sortKeys.add(0, new RowSorter.SortKey(column, SortOrder.DESCENDING));
}
else if (sortKeys.get(0).getSortOrder() == SortOrder.ASCENDING) {
sortKeys.removeIf(key -> key.getColumn() == column);
sortKeys.add(0, new RowSorter.SortKey(column, SortOrder.DESCENDING));
}
else {
sortKeys.removeIf(key -> key.getColumn() == column);
sortKeys.add(0, new RowSorter.SortKey(column, SortOrder.ASCENDING));
}
setSortKeys(sortKeys);
}
}
You can use this like that:
DocumentTableModel model = new DocumentTableModel(document);
JTable table = new JTable(model);
NormallyDescendingSorter sorter = new NormallyDescendingSorter(model, 0);
table.setRowSorter(sorter);
(I specified 0 as column index to be sorted ascending).
Upvotes: 1
Reputation: 2989
int noOfClicks = 1;
public void arrange(){
TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel());
table.setRowSorter(sorter);
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
int columnIndexToSort = 1;
if (noOfClicks%2==0){
//firstClick
sortKeys.add(new RowSorter.SortKey(columnIndexToSort, SortOrder.ASCENDING));
}else{
sortKeys.add(new RowSorter.SortKey(columnIndexToSort, SortOrder.DESCENDING));
}
++noOfClicks;
sorter.setSortKeys(sortKeys);
sorter.sort();
}
you can do it with above approach.if you can store the noOfclicks then you can check whether you should arrange it by assending order or descending order. if the noOfclicks is a even number then you can arrange the table on assending order.no of clicks will be incremented by +1 on each click.
Upvotes: 2