Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a JXTreeTable sort its top elements

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!

like image 273
ixM Avatar asked Feb 29 '12 12:02

ixM


2 Answers

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 hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description here

like image 91
mKorbel Avatar answered Oct 26 '22 08:10

mKorbel


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.

like image 30
Alex Burdusel Avatar answered Oct 26 '22 08:10

Alex Burdusel