Home > database >  In Java want to implement multi column sorting vai the table header in a sensible way
In Java want to implement multi column sorting vai the table header in a sensible way

Time:02-12

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

  • Related