Reputation: 3628
I have a javafx checkbox tree. I need to select the checkbox when the tree item is clicked. I have added a listener for the selection property of the tree view. But the listener gets fired only when the tree item is clicked. The above listener is not fired when the checkbox is clicked.
Required: A listener that fires when a tree item or checkbox is clicked in the treeview.
Code:
String memberArray = {"subChild1", "subChild2", "childSub1"}
Group groupRoot = new Group();
Scene scene = new Scene(groupRoot, Color.ALICEBLUE);
HBox hBox = new HBox();
hBox.setMaxWidth(fxPanel.getWidth());
final Label royalLabel = new Label("Select a item");
TreeSet<String> prefixMember = new TreeSet<String>();
String tmpName = null;
LinkedHashSet<CheckBoxTreeItem<String>> treeItems = new LinkedHashSet<CheckBoxTreeItem<String>>();
LinkedHashSet<CheckBoxTreeItem<String>> treeSubItems = new LinkedHashSet<CheckBoxTreeItem<String>>();
for (String item : memberArray) {
if (!item.isEmpty()) {
tmpName = item.substring(0, 3);
prefixMember.add(tmpName);
}
}
// Create and empty TreeView
TreeView<String> duckTree = new TreeView<String>();
// Create TreeItems for the Hierarchy of the TreeView
CheckBoxTreeItem<String> root = new CheckBoxTreeItem<String>("Parent");
CheckBoxTreeItem<String> lm1 = new CheckBoxTreeItem<String>("Child1");
CheckBoxTreeItem<String> lm2 = new CheckBoxTreeItem<String>("Child2");
for (String item : prefixMember) {
CheckBoxTreeItem<String> treeItem = new CheckBoxTreeItem<String>(item.toString());
for (String subItem : memberArray) {
if (!subItem.isEmpty() && subItem.substring(0, 3).equals(item)) {
CheckBoxTreeItem<String> treeSubItem = new CheckBoxTreeItem<String>(
subItem.toString());
treeSubItems.add(treeSubItem);
}
}
treeItems.add(treeItem);
treeItem.getChildren().addAll(treeSubItems);
treeSubItems.clear();
}
root.getChildren().addAll(treeItems);
treeItems.clear();
// Create a TreeView using the root TreeItem
TreeView<String> royalTree = new TreeView<String>(root);
royalTree.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
// Set a ChangeListener to handle events that occur with a Treeitem
// is selected
royalTree.getSelectionModel().selectedItemProperty()
.addListener(new ChangeListener<TreeItem<String>>() {
public void changed(
ObservableValue<? extends TreeItem<String>> observableValue,
TreeItem<String> oldItem, TreeItem<String> newItem) {
// Gets fired only on selection of tree item
// Need to get fired on selection of check box too
// Select the respective checkbox on selection of tree item
}
});
hBox.getChildren().add(royalTree);
groupRoot.getChildren().add(hBox);
fxPanel.setScene(scene);
Upvotes: 1
Views: 5450
Reputation: 14317
Yes, adding an event handler to the tree item works. Here is some example code (Java 8) with a TreeView with items as CheckBoxTreeItem:
CheckBoxTreeItem<Path> rootItem = new CheckBoxTreeItem<>(rootDirPath);
rootItem.addEventHandler(
CheckBoxTreeItem.<Path>checkBoxSelectionChangedEvent(),
(TreeModificationEvent<Path> e) -> {
CheckBoxTreeItem<Path> item = e.getTreeItem();
if (item.isSelected() || item.isIndeterminate()) {
System.out.println("Some items are checked");
}
else {
System.out.println("Some items are unchecked");
}
});
TreeView<Path> tree = new TreeView<>(rootItem);
tree.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
Upvotes: 1
Reputation: 228
You could just add an EventHandler to your root item in the tree:
rootItem.addEventHandler(CheckBoxTreeItem.checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<Object>>() {
@Override
public void handle(TreeModificationEvent<Object> event) {
// Your code here.
}
});
Upvotes: 2
Reputation: 2438
i had the same problem and searched looong time. Sadly there is not offical documentation for this from oracle.
The answer is to set the CellFactory and call the getSelectedStateCallback().call(this.getTreeItem());
for your treeItem in the updateItem:
// set cellFactory
royalTree.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>() {
@Override
public TreeCell<String> call(TreeView<String> p) {
// return new CheckBoxTreeCell, you also can make a new class with this
return new CheckBoxTreeCell<String>() {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
// call the selectedStat Callback for treeitem
ObservableValue<Boolean> selectedState = getSelectedStateCallback().call(this.getTreeItem());
if (selectedState != null) {
// do something here
}
}
}
};
}
});
i have tested this in fx 8, but it should also work in fx 2.2
happy coding,
kalasch
Upvotes: 1
Reputation: 186
Do you require an event for each selection immediately? If not you can create an arraylist of all your checkboxtreeitems and iterate through that to check for selected or not selected when you need it.
Upvotes: 0