In Java 11 (with swingx 1.6.6) I have just implemented multi column sorting as follows:
- Click on first Column, sorts by that columns ascending
- Click on second Column, secondary sort by that column ascending
- and so on, if user clicks on a column they have already clicked on the sort order changes i.e ascending to descending
But I don't have a way to reset the sort and looking at some other applications I think I want it to work in the following way:
- Click on first Column, sorts by that columns ascending
- Click on second Column, resets sort to primary sort by just that column ascending (same as default sort works)
- But, cntl-click on second Column, then secondary sorts by that column and so on, if user clicks on a column they have already clicked on the sort order changes i.e ascending to descending
So whenever anyone click or cntl-clicks that causes a call to toggleSort()
, but how do I capture that the user has cntl-clicked rather than clicked and know that so accessible to toggleSort()
For reference, modified toggleSort()
method extends
org.jdesktop.swingx.sort.TableSortController
and I modified swingx code so I could access previous private methods getFirstInCycle()
and getNextInCycle()
)
public void toggleSortOrder(int column)
{
//Are we allowed to this sort column
if (this.isSortable(column))
{
SortOrder firstInCycle = this.getFirstInCycle();
//If all already a column in sort cycle
if (firstInCycle != null)
{
//Make a copy of existing keys
List<SortKey> keys = new ArrayList(this.getSortKeys());
//Look for any existing sort key for column user has clicked on
SortKey sortKey = SortUtils.getFirstSortKeyForColumn((List)keys, column);
//If its the first one
if (((List)keys).indexOf(sortKey) == 0)
{
//Swap the sort order of to next one, i.e ascending to descending
((List)keys).set(0, new SortKey(column, this.getNextInCycle(sortKey.getSortOrder())));
}
else
{
//Add new final sort key for this column
((List)keys).add(new SortKey(column, this.getFirstInCycle()));
}
//Trim the number of keys if we have to many
if (((List)keys).size() > this.getMaxSortKeys()) {
keys = ((List)keys).subList(0, this.getMaxSortKeys());
}
this.setSortKeys((List)keys);
}
}
}
CodePudding user response:
Sooo, I've been digging around in the code and I think you're in for a bag of issues. The handling of the mouse clicked is performed by the UI delegate (specifically the BaseTableHeaderUI
), which calls TableRowSorter#toggleSortOrder
directly. So the table and table header aren't involved at all, so there's no injection point through which you might be able to control this workflow.
I then thought about simply adding a MouseListener
to the JTableHeader
itself. My original concern was this would interface with the existing MouseListener
been used by the TableHeaderUI
, but if all we want to do is remove a SortKey
when the header is Control Clicked, then it "should" be okay, BUT, you'll get two calls to toggleSortOrder
Now, I'm not using SwingX, this is pure Swing only, but the concept should work