【发布时间】:2016-03-18 00:34:56
【问题描述】:
问题
从ObservableList 中删除项目时,会触发change event,其中getFrom() 提供删除位置,getRemoved() 提供已删除项目的列表。 The documentation 说:
getRemoved()方法返回已被替换或从列表中删除的元素列表。
没有这样说明,但我认为它暗示项目列表是原始列表的连续子列表。我已经用这个假设编写了很多代码,但现在遇到了TreeTableView's selection model 的问题,它的行为方式并非如此。
示例
以一个包含三个“节点”行的简单树表为例。如果我选择这三行...
...然后单击并仅选择中间行...
...treeTableView.getSelectionModel().getSelectedItems() 上触发的更改事件如下所示:
{ [TreeItem [ value: Node 1 ], TreeItem [ value: Node 3 ]] removed at 0, }
在单个更改事件中,它报告“节点 1”和“节点 3”已从 selectedItems 列表的索引 0 中删除。
我本来希望 Change 对象有两个单独的删除事件,由 next() 调用分隔。第一次调用 next() 会告诉我“节点 1”在索引 0 处被删除,第二次调用 next() 会告诉我“节点 3”在索引 1 处被删除。但不,我得到一个两行同时列出的事件。
问题
getRemoved() 真的可以返回不连续的项目吗?这是我对列表更改事件如何工作的误解,还是TreeTableView 中的错误?
通常我会犹豫归咎于标准库,但这不会是我在 JavaFX 中发现的第一个错误,因此并非不可想象。
更新
如果我添加对setShowRoot(false) 的调用,行为会发生变化。我得到了我的期望,删除分为两部分:
{ [TreeItem [ value: Node 1 ]] removed at 0, [TreeItem [ value: Node 3 ]] removed at 1, }
另外,这是我的MCVE:
import java.util.*;
import javafx.application.*;
import javafx.beans.property.*;
import javafx.collections.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.stage.*;
public class TreeTableSelectionEvents extends Application {
public void start(Stage stage) {
// Root node.
TreeItem<String> root = new TreeItem<>("Root");
root.setExpanded(true);
root.getChildren().setAll(Arrays.asList(
new TreeItem<>("Node 1"),
new TreeItem<>("Node 2"),
new TreeItem<>("Node 3")
));
// Single column.
TreeTableColumn<String, String> column = new TreeTableColumn<>("Column");
column.setPrefWidth(150);
column.setCellValueFactory((TreeTableColumn.CellDataFeatures<String, String> p) -> {
return new ReadOnlyStringWrapper(p.getValue().getValue());
});
// Tree table.
TreeTableView<String> table = new TreeTableView<>(root);
table.getColumns().add(column);
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
// table.setShowRoot(false);
table.getSelectionModel().getSelectedItems().addListener(
(ListChangeListener.Change<? extends TreeItem<String>> change) -> {
System.out.printf("item change = %s, list is now %s%n", change, change.getList());
}
);
table.getSelectionModel().getSelectedIndices().addListener(
(ListChangeListener.Change<? extends Integer> change) -> {
System.out.printf("index change = %s, list is now %s%n", change, change.getList());
}
);
// Stage.
stage.setScene(new Scene(table));
stage.show();
}
}
【问题讨论】:
-
getTo()在那种情况下会返回什么? -
getTo()=getFrom()=0。 -
那至少与当时的文档一致。似乎答案很简单“是的,
getRemoved()可以返回不连续的项目”。有什么理由相信这是一个错误吗?我在文档中没有看到任何地方表明这是不允许的。 -
列表可以包含重复项。如果
getRemoved()中的项目不连续,那么我无法明确确定删除了哪些项目。它可以是任何重复项。我怀疑但不确定这是文档中的缺陷和TreeTableViewSelectionModel中的错误。 -
明白。可能是 API 设计的缺陷……
标签: java javafx observablelist treetableview