对javaFX树表视图项进行排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对javaFX树表视图项进行排序相关的知识,希望对你有一定的参考价值。

我有麻烦排序我的JFXTreeTableView(来自Jfoenix)。 我创建了一个名为ScanModel的对象,它扩展了Jfoenix的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(包含多个SeriesModel)覆盖Jfoenix RecursiveTreeObject的getChildren()方法,并返回其系列可观察列表。

这是我如何将包含项目的可观察列表绑定到表本身:

    protected void createTree(JFXTreeTableView<ScanModel> tree, ObservableList<ScanModel> elements) {
        tree.setRoot(new RecursiveTreeItem<ScanModel>(elements, RecursiveTreeObject::getChildren));
        tree.setShowRoot(false);
        tree.getSelectionModel().clearSelection();
    }

到目前为止,一切都运行良好,我已将新的ScanModel项添加到可观察列表中,并且它在UI中自动显示。

现在我的问题: 客户端请求排序表: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();
}

已排序的可观察列表确实已排序,但它不会反映在UI中 Tree table view problem

我在这里错过了什么? 谢谢。

更新 以防万一,这是表格的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>
答案

问题问题已经有一段时间了,我看到有些人看过这个主题。 这是一个答案。肯定不是最好的 - 但它确实有效。

首先,在创建树时 - 需要树的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

以上是关于对javaFX树表视图项进行排序的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX排序ListView

JavaFX窗口拖动

启用排序时,JavaFX Tableview标题颜色

片段 A 的列表视图中的片段 B 中的新列表视图,单击 A 的列表项

JavaFX自定义窗口标题栏

不要在片段中显示列表视图项