I'm having a TreeView with a few nodes having CheckBoxes (see MWE).
When collapsing / expanding some node, the CheckBoxes of other nodes are checked or unchecked.
To reproduce the behaviour, just expand all the nodes, check ChildA
, collapse Block1
and ChildC
will be automatically checked.
package treeviewexample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.CheckBoxTreeCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class TreeViewExample extends Application {
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
/* example Treeview */
TreeView tw = new TreeView();
TreeItem rootNode = new TreeItem("Root");
TreeItem blockOne = new TreeItem("Block1");
TreeItem childA = new TreeItem("ChildA");
TreeItem childB = new TreeItem("ChildB");
blockOne.getChildren().add(childA);
blockOne.getChildren().add(childB);
TreeItem blockTwo = new TreeItem("Block2");
TreeItem childC = new TreeItem("ChildC");
TreeItem childD = new TreeItem("ChildD");
blockTwo.getChildren().add(childC);
blockTwo.getChildren().add(childD);
rootNode.getChildren().add(blockOne);
rootNode.getChildren().add(blockTwo);
tw.setRoot(rootNode);
/* add CheckBoxes */
tw.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
root.getChildren().add(tw);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
How can I prevent this behaviour? At a later point in my program, I want to go through the TreeView and get the status (checked or not) of the nodes to work with them.
From https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TreeCell.html I know the following:
Due to the fact that TreeCell extends from IndexedCell, each TreeCell also provides an index property. The index will be updated as cells are expanded and collapsed, and therefore should be considered a view index rather than a model index.
So is this intended behaviour? Why would anyone want to have that?
The behavior you are seeing is nothing to do with the index of the cell, but solely because you haven't provided any mechanism for the
CheckBoxTreeCell
to "know" whether or not it is supposed to be checked. Consequently, when you expand or collapse nodes in the tree, and the cells are reused for other items, they will likely maintain their checked status even though they are now supposed to be representing new data.The basic issue here is that the
CheckBoxTreeCell
is just the view: it does not maintain the selected state. You need to provide a mechanism for the cell to know whether the item it represents is selected or not. The API provides two ways to do this: either use aCheckBoxTreeItem
as the items in the tree, or use a model class that has aBooleanProperty
and provide a mapping to that boolean property.The first version looks like this (I also got rid of all your raw types: you really should not post code here that generates warnings and just ignore them):
The second option looks like: