Сортировать элементы дерева таблицы javaFX
У меня проблемы с сортировкой JFXTreeTableView
(из Jfoenix).
Я создал объект с именем ScanModel, который расширяет Jfoenix's RecursiveTreeObject<ScanModel>
,
Одно из многих моих свойств:private IntegerProperty id;
Вот его геттеры и сеттеры
public final IntegerProperty idProperty() {
if (id == null) {
id = new SimpleIntegerProperty();
}
return id;
}
public final int getId() {
return idProperty().get();
}
public void setId(int value) {
idProperty().set(value);
}
Два класса расширяют абстрактный класс ScanModel: StudyModel и SeriesModel.
StudyModel (который содержит несколько SeriesModels) переопределяет getChildren()
метод Jfoenix RecursiveTreeObject и возвращает его список наблюдаемых серий.
Вот как я связываю наблюдаемый список, содержащий элементы, с самой таблицей:
protected void createTree(JFXTreeTableView<ScanModel> tree, ObservableList<ScanModel> elements) {
tree.setRoot(new RecursiveTreeItem<ScanModel>(elements, RecursiveTreeObject::getChildren));
tree.setShowRoot(false);
tree.getSelectionModel().clearSelection();
}
До сих пор все работало отлично, я добавил новые элементы ScanModel в список наблюдаемых, и он автоматически отображался в пользовательском интерфейсе.
Теперь для моего вопроса:
Клиент запрашивает отсортированную таблицу: Descending StudyModels и Ascending SeriesModels.
Для первой попытки я только попытался отсортировать StudyModels.
Я изменил метод createTree для этой реализации:
protected void createTree(JFXTreeTableView<ScanModel> tree, ObservableList<ScanModel> elements) {
SortedList<ScanModel> sortedElements = elements.sorted((l, r) -> Integer.compare(l.getId(), r.getId()));
tree.setRoot(new RecursiveTreeItem<ScanModel>(sortedElements, RecursiveTreeObject::getChildren));
tree.setShowRoot(false);
tree.getSelectionModel().clearSelection();
}
Сортированный наблюдаемый список действительно отсортирован, но он не отражается в пользовательском интерфейсе
Что мне здесь не хватает?
Благодарю.
Обновить
На всякий случай, вот fxml таблицы
<JFXTreeTableView fx:id="_treeTableView">
<placeholder>
<Label text="No Normal Studies to display" />
</placeholder>
<columnResizePolicy>
<JFXTreeTableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
<columns>
<JFXTreeTableColumn text="ID" sortable="false"
minWidth="150" maxWidth="150">
<cellValueFactory>
<TreeTableErrorIndicationCellFactory value="id" />
</cellValueFactory>
</JFXTreeTableColumn>
<JFXTreeTableColumn text="Scan Time" sortable="false"
minWidth="140" maxWidth="140">
<cellValueFactory>
<TreeTableErrorIndicationCellFactory value="formattedScanTime" />
</cellValueFactory>
</JFXTreeTableColumn>
<JFXTreeTableColumn text="Selected" sortable="false"
minWidth="60" maxWidth="60">
<cellValueFactory>
<ScanSelectedValueFactory />
</cellValueFactory>
</JFXTreeTableColumn>
<JFXTreeTableColumn sortable="false">
</JFXTreeTableColumn>
<JFXTreeTableColumn text="Archived" sortable="false"
style="-fx-alignment: CENTER-RIGHT;" minWidth="60" maxWidth="60">
<cellValueFactory>
<IsArchivedCellFactory />
</cellValueFactory>
</JFXTreeTableColumn>
</columns>
</JFXTreeTableView>
1 ответ
Прошло много времени с тех пор, как был задан вопрос, и я вижу, что некоторые люди просмотрели эту тему.
Вот ответ. Конечно, не самый лучший - но это работает.
Прежде всего, при создании дерева - нужно setSortPolicy
дерева.
Вот как это выглядит в моем проекте:
protected void createTree(JFXTreeTableView<ScanModel> tree, ObservableList<ScanModel> elements) {
tree.setRoot(new RecursiveTreeItem<ScanModel>(elements, RecursiveTreeObject::getChildren));
tree.setShowRoot(false);
tree.getSelectionModel().clearSelection();
// set sort policy for the table in two levels
tree.setSortPolicy(t -> {
Comparator<TreeItem<ScanModel>> studiesComparator = (r1, r2) -> {
try {
int r1Value = Integer.parseInt(r1.getValue().getDisplayName());
int r2Value = Integer.parseInt(r2.getValue().getDisplayName());
return Integer.compare(r2Value, r1Value);
} catch (NumberFormatException e) {
return r2.getValue().getDisplayName().compareToIgnoreCase(r1.getValue().getDisplayName());
}
};
FXCollections.sort(tree.getRoot().getChildren(), studiesComparator);
for (TreeItem<ScanModel> series : tree.getRoot().getChildren()) {
Comparator<TreeItem<ScanModel>> seriesComparator = (r1, r2) -> {
try {
int r1Value = Integer.parseInt(r1.getValue().getDisplayName());
int r2Value = Integer.parseInt(r2.getValue().getDisplayName());
return Integer.compare(r1Value, r2Value);
} catch (NumberFormatException e) {
return r1.getValue().getDisplayName().compareToIgnoreCase(r2.getValue().getDisplayName());
}
};
series.getChildren().sort(seriesComparator);
}
return true;
});
}
Во-вторых, для каждого нового элемента, добавленного в дерево - я называю sort
метод.
/**
* Sort the table according to the configured sort policy
*
* @param tree
*/
protected void sortTree(JFXTreeTableView<ScanModel> tree) {
// Keep selected row and set it again after sort
TreeItem<ScanModel> selectedRow = tree.getSelectionModel().getSelectedItem();
tree.sort();
tree.getSelectionModel().select(selectedRow);
}
Надеюсь, что это поможет некоторым будущим зрителям.
Naor