JavaFX : Get the selected value when CheckBoxTreeI

2019-07-22 19:49发布

问题:

I want to get all the selected values in TreeView containing CheckBoxTreeItems.

How to accomplish this?

回答1:

You can listen to the events on the root to keep a Set<TreeItem> up to date or you can do a DFS for selected items starting at the root.

Note that the DFS approach certainly requires the smaller amount of code, but the other approach allows you to keep the set up to date during modifications...

@Override
public void start(Stage primaryStage) {
    CheckBoxTreeItem<String> root = new CheckBoxTreeItem<>("root");
    CheckBoxTreeItem<String> c1 = new CheckBoxTreeItem<>("c1");
    c1.getChildren().addAll(
            new CheckBoxTreeItem<>("c1.1"),
            new CheckBoxTreeItem<>("c1.2"),
            new CheckBoxTreeItem<>("c1.3")
    );
    CheckBoxTreeItem<String> c2 = new CheckBoxTreeItem<>("c2");
    c2.getChildren().addAll(
            new CheckBoxTreeItem<>("c2.1"),
            new CheckBoxTreeItem<>("c2.2"),
            new CheckBoxTreeItem<>("c2.3")
    );
    CheckBoxTreeItem<String> c3 = new CheckBoxTreeItem<>("c3");
    c3.getChildren().addAll(
            new CheckBoxTreeItem<>("c3.1"),
            new CheckBoxTreeItem<>("c3.2"),
            new CheckBoxTreeItem<>("c3.3")
    );
    root.getChildren().addAll(c1, c2, c3);

    TreeView<String> treeView = new TreeView<>(root);
    treeView.setCellFactory(CheckBoxTreeCell.forTreeView());
    Set<TreeItem<String>> selected = new HashSet<>();

    // listen for selection change
    root.addEventHandler(CheckBoxTreeItem.checkBoxSelectionChangedEvent(), (CheckBoxTreeItem.TreeModificationEvent<String> evt) -> {
        CheckBoxTreeItem<String> item = evt.getTreeItem();

        if (evt.wasIndeterminateChanged()) {
            if (item.isIndeterminate()) {
                selected.remove(item);
            } else if (item.isSelected()) {
                selected.add(item);
            }
        } else if (evt.wasSelectionChanged()) {
            if (item.isSelected()) {
                selected.add(item);
            } else {
                selected.remove(item);
            }
        }
    });

    // listen for subtree add/remove
    root.addEventHandler(TreeItem.childrenModificationEvent(), (TreeItem.TreeModificationEvent<String> evt) -> {
        if (evt.wasAdded()) {
            for (TreeItem<String> added : evt.getAddedChildren()) {
                addSubtree(selected, (CheckBoxTreeItem<String>) added);
            }
        }
        if (evt.wasRemoved()) {
            for (TreeItem<String> removed : evt.getRemovedChildren()) {
                removeSubtree(selected, (CheckBoxTreeItem<String>) removed);
            }
        }
    });

    Button button = new Button("print selected");
    button.setOnAction(evt -> {
        System.out.println("----------------");
        selected.stream().map(TreeItem::getValue).forEach(System.out::println);
    });

    Button button2 = new Button("print dfs");
    button2.setOnAction(evt -> {
        System.out.println("----------------");
        print(root);
    });

    Button remove = new Button("remove");
    remove.setOnAction(evt -> {
        root.getChildren().remove(c3);
    });

    Scene scene = new Scene(new VBox(treeView, button, button2, remove));

    primaryStage.setScene(scene);
    primaryStage.show();
}

private static <T> void removeSubtree(Collection<TreeItem<T>> collection, CheckBoxTreeItem<T> item) {
    if (item.isSelected()) {
        collection.remove(item);
    } else if (!item.isIndeterminate() && !item.isIndependent()) {
        return;
    }
    for (TreeItem<T> child : item.getChildren()) {
        removeSubtree(collection, (CheckBoxTreeItem<T>) child);
    }
}

private static <T> void addSubtree(Collection<TreeItem<T>> collection, CheckBoxTreeItem<T> item) {
    if (item.isSelected()) {
        collection.add(item);
    } else if (!item.isIndeterminate() && !item.isIndependent()) {
        return;
    }
    for (TreeItem<T> child : item.getChildren()) {
        addSubtree(collection, (CheckBoxTreeItem<T>) child);
    }
}

private static <T> void print(CheckBoxTreeItem<T> item) {
    if (item.isSelected()) {
        System.out.println(item.getValue());
    } else if (!item.isIndeterminate() && !item.isIndependent()) {
        return;
    }
    for (TreeItem<T> child : item.getChildren()) {
        print((CheckBoxTreeItem<T>) child);
    }
}


回答2:

If you're using a TreeView, you can get the item selected like this:

treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem<String>>() {

        @Override
        public void changed(ObservableValue<? extends TreeItem<String>> observable, TreeItem<String> oldValue,
                TreeItem<String> newValue) {

            System.out.println("The selected item is : "newValue.getValue()); 


        }
});