How to make a JXTreeTable sort its top elements
Asked Answered
B

2

8

I'm aware (I've looked at the sources ;) ) that sorting on JXTreeTable has been disabled.

However, I would like to allow sorting on all columns based only on the values of the direct children of the root node.

Say I have a structure like this:

Name       / Date       / File UID
(Root)
|- Mr. X   / 1996/10/22 / AE123F6D
|--- File1 / 2012/01/10 / DFC2345Q
|--- File2 / 2012/01/11 / D321FEC6
|- Mrs. Y  / 1975/03/03 / G2GF35EZ
|--- File3 / 2012/02/29 / 35GERR32
|--- File4 / 2012/01/22 / LKJY2342
.
.
.

What I want to achieve is sorting on the 3 columns only on first level nodes. Say I want to sort it by ascending date, it would end up like that:

Name       / Date       / File UID
(Root)
|- Mrs. Y  / 1975/03/03 / G2GF35EZ
|--- File3 / 2012/02/29 / 35GERR32
|--- File4 / 2012/01/22 / LKJY2342
|- Mr. X   / 1996/10/22 / AE123F6D
|--- File1 / 2012/01/10 / DFC2345Q
|--- File2 / 2012/01/11 / D321FEC6
.
.
.

As I see it, it ressembles to simple table sorting (so the hierarchical limitation invoked for disabling sorting is lifted).

I see 2 possibilities to do that:

  1. Re-enable the sorting mechanism available in JXTable to benefit from everything that is already implemented (sorter, sorting by clicking on the headers,...) and only sort nodes of the first level (as their children would still have the same parent).
  2. Implement the basic stuff I need (sorting by clicking on the headers mostly), have a list of model-row-ids in JXSortableTreeModel that I sort and override convertRowIndexToModel which would allow (I think) to display my item sorted as I want.

My favourite is of course the first one but I don't know how to achieve it. The first limitation is that I don't know how to re-enable sorting as JXTreeTable overrides setSortable() (and all related methods) and I don't know how to directly access the implementation of the method in JXTable (that's a Java problem). I could simply copy the code of JXTreeTable and remove the overrides but that's not an option in my opinion.

Say I solve this, how would I limit the sorting to the first-level nodes? Even after looking at the source, I'm rather clueless about how to do that.

With the second one, I loose all the benefits of existing code but I see a practical way to achieve what I want (for now, at least. Who knows if won't want to filter the data on all rows?).

Is there another way to go? If not, which one of my solutions should I choose? Any insightful comments?

Many thanks in advance!

Bluegill answered 29/2, 2012 at 12:53 Comment(0)
P
3

maybe sorting TreeTable following way(s), by aephyr, btw this Swing Guru played with Nimbus Look and Feel too, code for funny Nimbus included

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

Pyrology answered 1/3, 2012 at 14:29 Comment(5)
Thanks! I've browsed the sources of the TreeTable and I must say, this looks promising. I'll try to have a better look at it later :)Bluegill
Aephyr's solution works well, but the source code contains virtually no documentation or comments. The demo is a good example, but I still ran into several Exceptions being thrown on the EDT. The headaches of debugging and supporting these and future issues in code like this is a big thumbs down for me.Genni
@nate this is code exhibition by one of great Swing guru, code depots for several forums where aephyr are member of, no idea about EDT exceptions nor violations, there must be secondary issue from your code:-)Pyrology
The link is brokenToth
@Markus Weninger seems like as author of the code it gave up (forever)Pyrology
K
2

I managed to do it by playing with at the nodes level. This is a method I created in my tree table node that extends AbstractMutableTreeTableNode:

/**
 * This method recursively (or not) sorts the nodes, ascending, or descending by the specified column.
 * @param sortColumn Column to do the sorting by.
 * @param sortAscending Boolean value of weather the sorting to be done ascending or not (descending).
 * @param recursive Boolean value of weather or not the sorting should be recursively applied to children nodes.
 * @author Alex Burdu Burdusel
 */
public void sortNode(int sortColumn, boolean sortAscending, boolean recursive) {
    mLastSortAscending = sortAscending;
    mLastSortedColumn = sortColumn;
    mLastSortRecursive = recursive;

    int childCount = this.getChildCount();
    TreeMap<Object, BRFTreeTableNode> nodeData = new TreeMap(String.CASE_INSENSITIVE_ORDER);

    for (int i = 0; i < childCount; i++) {
        BRFTreeTableNode child = (BRFTreeTableNode) this.getChildAt(i);
        if (child.getChildCount() > 0 & recursive) {
            child.sortNode(sortColumn, sortAscending, recursive);
        }
        Object key = child.getData()[sortColumn];
        nodeData.put(key, child);
    }

    Iterator<Map.Entry<Object, BRFTreeTableNode>> nodesIterator;
    if (sortAscending) {
        nodesIterator = nodeData.entrySet().iterator();
    } else {
        nodesIterator = nodeData.descendingMap().entrySet().iterator();
    }

    while (nodesIterator.hasNext()) {
        Map.Entry<Object, BRFTreeTableNode> nodeEntry = nodesIterator.next();
        this.add(nodeEntry.getValue());
    }
}

Hope this helps someone else, since I think the thread opener already figured it out.

Kew answered 9/8, 2013 at 17:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.