javaswingjtableswingx

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


In Java 11 (with swingx 1.6.6) I have just implemented multi column sorting as follows:

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:

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);
        }
    }
}

Solution

  • Decided better to drop the cntl-click idea and instead restore the three stage cycle by modifying org.jdesktop.swingx.sort,DefaultSortController from

        private final static SortOrder[] DEFAULT_CYCLE 
         = new SortOrder[] {SortOrder.ASCENDING, SortOrder.DESCENDING};
    

    to

      private final static SortOrder[] DEFAULT_CYCLE 
       = new SortOrder[] {SortOrder.ASCENDING, SortOrder.DESCENDING,SortOrder.UNSORTED}; 
    

    and then this is my toggleSortOrder() method in my custom sort controller

    /**
     * If new sort key sort ascending as after other existing sort keys
     * If existing sort key and ascending cycle change to descending
     * If existing sort key and descending remove the sort key
     * If already at MAX_SORT_COLUMNS the ignore
     * 
     * @param column
     */
    @Override
    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> newKeys = new ArrayList(this.getSortKeys());
    
                //Look for any existing sort key for column user has clicked on
                SortKey sortKey = SortUtils.getFirstSortKeyForColumn(newKeys, column);
    
                //Existing Key
                if(sortKey!=null)
                {
                    //Get next in cycle
                    SortOrder nextSortOrder = this.getNextInCycle(sortKey.getSortOrder());
    
                    //Swap to descending/ascending
                    if(nextSortOrder==SortOrder.DESCENDING || nextSortOrder==SortOrder.ASCENDING)
                    {
                        newKeys.set((newKeys).indexOf(sortKey), new SortKey(column, nextSortOrder));
                    }
                    //Remove from sort
                    else
                    {
                        newKeys.remove(sortKey);
                    }
                }
                //New Key
                else
                {
                    (newKeys).add(new SortKey(column, this.getFirstInCycle()));
                }
    
                //Trim the number of keys if we have too many
                if ((newKeys).size() > this.getMaxSortKeys()) {
                    newKeys = ((List)newKeys).subList(0, this.getMaxSortKeys());
                }
                this.setSortKeys(newKeys);
            }
        }
    }