Как заставить JXTreeTable сортировать его верхние элементы

Я знаю (я посмотрел на источники;)), что сортировка на JXTreeTable была отключена.

Однако я хотел бы разрешить сортировку по всем столбцам только на основе значений прямых потомков корневого узла.

Скажем, у меня есть такая структура:

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
.
.
.

Я хочу добиться сортировки по 3 столбцам только на узлах первого уровня. Скажем, я хочу отсортировать его по возрастанию, в итоге это будет выглядеть так:

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
.
.
.

На мой взгляд, это напоминает простую сортировку таблиц (поэтому иерархическое ограничение, вызываемое для отключения сортировки, снято).

Я вижу 2 возможности сделать это:

  1. Повторно включите механизм сортировки, доступный в JXTable, чтобы извлечь выгоду из всего, что уже реализовано (сортировка, сортировка нажатием на заголовки,...) и только сортировать узлы первого уровня (так как у их потомков все еще будет тот же родитель),
  2. Реализовать базовые вещи, которые мне нужны (сортировка, в основном, щелкая по заголовкам), иметь список идентификаторов-строк-моделей в JXSortableTreeModel, который я сортирую и переопределяю convertRowIndexToModel, который позволит (я думаю) отображать мой элемент, отсортированный так, как я хочу.

Мой любимый, конечно, первый, но я не знаю, как этого добиться. Первое ограничение заключается в том, что я не знаю, как повторно включить сортировку, поскольку JXTreeTable переопределяет setSortable() (и все связанные методы), и я не знаю, как получить прямой доступ к реализации метода в JXTable (это проблема Java).). Я мог бы просто скопировать код JXTreeTable и удалить переопределения, но, на мой взгляд, это не вариант.

Скажем, я решаю это, как бы я ограничил сортировку узлами первого уровня? Даже посмотрев на источник, я не знаю, как это сделать.

Со вторым я теряю все преимущества существующего кода, но я вижу практический способ достичь того, чего я хочу (на данный момент, по крайней мере. Кто знает, не захочет ли фильтровать данные по всем строкам?).

Есть ли другой путь? Если нет, какое из моих решений мне выбрать? Какие-нибудь проницательные комментарии?

Спасибо заранее!

2 ответа

Решение

возможно сортировка TreeTable следующим образом, по aephyr, кстати, этот Swing Guru играл с Nimbus Look and Feel тоже, код для смешного Nimbus включен

Мне удалось сделать это, играя на уровне узлов. Это метод, который я создал в своем узле таблицы дерева, который расширяет 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());
    }
}

Надеюсь, что это поможет кому-то еще, так как я думаю, что новичок уже понял это.

Другие вопросы по тегам