【问题标题】:JAVAFX SortedList doesn't sort. (and making it breaks column sort.)JAVAFX SortedList 不排序。 (并使其破坏列排序。)
【发布时间】:2021-05-10 08:09:18
【问题描述】:

使用 JavaFX (v15) 我想要一个 TableView,如果没有选择列,则按表中的整个行/对象排序,如果单击列标题,则按列排序。如果未单击列,则应返回按对象自然顺序或指定比较器显示行的排序。

比如:

@FXML TableView<Person> tableview;
ObserverableList<Person> list = FXCollections.observableArrayList<>();
SortedList<Person> sorted = new SortedList<>(list);
sorted.comparatorProperty().bind(tableview.comparatorProperty());
tableview.setItems(sorted);

它似乎没有排序。它只是获取项目在包装的 Observable 列表中迭代的任何顺序。这是因为没有比较器构造的 SortedList 实际上是一个未排序的列表吗? (这是我见过的最愚蠢的设计)。它将按列排序。为什么没有点击列时,给定 SortedList 的 TableView 实际不排序?

如果我改为:

@FXML TableView<Person> tableview;
ObserverableList<Person> list = FXCollections.observableArrayList<>();
SortedList<Person> sorted = new SortedList<>(list, (a,b) -> a.compareTo(b));
tableview.setItems(sorted);

然后 TableView 将出现排序...但是,单击列会产生:

2021 年 2 月 5 日下午 4:38:52 javafx.scene.control.TableView$3 调用 信息:TableView 项目列表是一个 SortedList,但 SortedList 比较器应绑定到 TableView 比较器以启用排序(例如 sortedList.comparatorProperty().bind(tableView.comparatorProperty());)。

如果我放回 SortedList 和 TableView 之间的属性绑定,那么我的比较器当然会被忽略。

如何实现一个表格视图,如果没有选择列进行排序,行将显示为按自然可比较顺序或比较器排序,但在选择这些列时将按单个列排序。

【问题讨论】:

  • Person 是否实现了Comparable&lt;Person&gt;
  • 不太明白你所说的 没有选择列 是什么意思 - 但即使:没有直接简单的(从未调查过 sortPolicy 也没有对 sortEvents 做出反应 :) 支持:你要么让默认排序(它基本上结合了 sortOrder 中列中的比较器)完成其工作或必须自己完成所有繁重的工作(如 fi 保持选择状态)。为了欺骗第一个使用每个项目的比较器,您可以使用一个隐藏列来承载项目,并将 sortOrder 设置为仅包含该隐藏列。
  • 我还找到了 setSortPolicy 选项。但这仍然引出了一个问题……为什么有这么多使用 SortedList 的“示例”。 SortedList 实际上是未排序的,没有使用比较器参数构造,如果您使用比较器参数构造它以进行排序,那么它不会绑定到 TableView 的比较器......这消除了按列排序的能力。傻。

标签: java sorting javafx tableview


【解决方案1】:

玩了一下,原来是我最初的评论

没有直接的简单(从未调查过 sortPolicy 也没有对 sortEvents 做出反应 :) 支持

具有误导性(委婉地说)- 尚未调查的 sortPolicy 看起来像是要走的路。

基本思想是自定义排序策略

  • 检查项目是否为 SortedList
  • 如果是并且 sortOrder 不为空,则将其比较器绑定到表的比较器并委托给默认策略
  • 如果没有,设置自定义比较器 (f.i. naturalOrder) 并返回

实用方法(注意:未经正式测试!)

public static <T> Callback<TableView<T>, Boolean> emptySortOrderPolicy(Comparator<? super T> comparator) {
    return cc -> {
        if (cc.getItems() instanceof SortedList) {
            SortedList<T> sortedItems = (SortedList<T>) cc.getItems();
            if (cc.getSortOrder().isEmpty()) {
                sortedItems.comparatorProperty().unbind();
                sortedItems.comparatorProperty().set(comparator);
                return true;
            } else {
                sortedItems.comparatorProperty().bind(cc.comparatorProperty());
            }
        }
        return TableView.DEFAULT_SORT_POLICY.call(cc);
    };
}

用法:

SortedList<ComparableItem> sorted = new SortedList<>(ComparableItem.items());
TableView<ComparableItem> table = new TableView<>(sorted);
table.setSortPolicy(emptySortOrderPolicy(Comparator.naturalOrder()));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多