Как заставить 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 и удалить переопределения, но, на мой взгляд, это не вариант.

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

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

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

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


person ixM    schedule 29.02.2012    source источник


Ответы (2)


может быть, сортировка TreeTable следующим образом, по aephyr, кстати, этот Swing Guru играл с Nimbus Посмотри и почувствуй тоже, код для забавного Nimbus включен

введите здесь описание изображениявведите здесь описание изображения введите здесь описание изображениявведите здесь описание изображения введите здесь описание изображения введите здесь описание изображения

person mKorbel    schedule 01.03.2012
comment
Спасибо! Я просмотрел исходники TreeTable и должен сказать, что это выглядит многообещающе. Позже постараюсь рассмотреть получше :) - person ixM; 01.03.2012
comment
Решение Aephyr работает хорошо, но исходный код практически не содержит документации или комментариев. Демонстрация — хороший пример, но я все же столкнулся с несколькими исключениями, выдаваемыми на EDT. Головная боль, связанная с отладкой и поддержкой этих и будущих проблем в коде, подобном этому, для меня большой палец вниз. - person Nate; 26.07.2012
comment
@nate это демонстрация кода одного из великих гуру Swing, хранилища кода для нескольких форумов, членами которых являются aephyr, понятия не имею об исключениях или нарушениях EDT, в вашем коде должна быть вторичная проблема :-) - person mKorbel; 26.07.2012
comment
Ссылка не работает - person Markus Weninger; 29.11.2016
comment
@Markus Weninger кажется автором кода, от которого он отказался (навсегда) - person mKorbel; 04.12.2016

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

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

person Alex Burdusel    schedule 09.08.2013