Как заставить 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 возможности сделать это:
- Повторно включите механизм сортировки, доступный в JXTable, чтобы извлечь выгоду из всего, что уже реализовано (сортировка, сортировка нажатием на заголовки,...) и только сортировать узлы первого уровня (так как у их потомков все еще будет тот же родитель),
- Реализовать базовые вещи, которые мне нужны (сортировка, в основном, щелкая по заголовкам), иметь список идентификаторов-строк-моделей в 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());
}
}
Надеюсь, что это поможет кому-то еще, так как я думаю, что новичок уже понял это.