JavaFX:TreeView selectedItems的bindContent

时间:2017-05-11 19:06:10

标签: javafx binding treeview selecteditem

我想绑定TreeView所选项目列表的内容,并在删除元素时碰到所选项目更改值的奇怪行为。我写了一些测试应用程序:

public class TreeViewSelectedItemsBindingTest extends Application {

    public class Item extends TreeItem<Integer> {
        public Item(Integer... value) {
            Arrays.stream(value).forEach(v -> getChildren().add(new TreeItem<Integer>(v)));
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        TreeView<Integer> treeView = new TreeView<>();
        treeView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        treeView.setRoot(new Item(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
        treeView.getRoot().setExpanded(true);
        treeView.setShowRoot(false);

        ListView<TreeItem<Integer>> listView = new ListView<>();

        Bindings.bindContent(listView.getItems(), treeView.getSelectionModel().getSelectedItems());

        treeView.getSelectionModel().getSelectedItems()
                .addListener((ListChangeListener<? super TreeItem<Integer>>) change -> {
                    System.out.println("Change: " + change);
                    System.out.println("TreeView size: " + treeView.getSelectionModel().getSelectedItems().size());
                    System.out.println("ListView size: " + listView.getItems().size());
                    System.out.println("-------------------");
                });

        HBox box = new HBox();
        box.getChildren().addAll(treeView, listView);
        primaryStage.setScene(new Scene(box));
        primaryStage.show();
    }

    static public void main(String[] args) {
        launch(args);
    }
}

此应用程序将TreeView个选定项目绑定到ListView个项目。在树视图中选择从0到9的所有元素,然后按SHIFT +元素5,例如,将选择从0更改为5个元素。你会得到一个例外:

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: toIndex = 9

这是因为ListChangeListener.Change从索引相对于初始未修改列表报告,而不是相对于先前更改的列表:

-------------------
Change: { [TreeItem [ value: 6 ]] removed at 6,  }
TreeView size: 9
ListView size: 9
-------------------
Change: { [TreeItem [ value: 7 ]] removed at 7,  }
TreeView size: 8
ListView size: 8
-------------------

你可以看到&#34;在6&#34;然后&#34;在7&#34;删除,但基础列表的大小也发生了变化,所以索引不应该在这里增加,即所有&#34;删除&#34;应该是6.因此,Bindings.bindContent失败。

1 个答案:

答案 0 :(得分:0)

这是一个错误JDK-8180359。作为一种解决方法,绑定列表应该整体更新:

treeView.getSelectionModel().getSelectedItems().addListener(
    (ListChangeListener<? super TreeItem<Model>>) change -> {
            while (change.next()) {
                listView.setAll(change.getList().stream()
                        .filter(Objects::nonNull)
                        .map(i -> i.getValue())
                        .collect(toList()));
            }
        });