Итак, для начала я не ожидаю, что вы реализуете этот точный код в своем приложении, это просто для того, чтобы дать вам представление о том, как реализовать что-то подобное. Это работает путем передачи родителя в функцию, которая строит CheckBoxTreeItem (я понимаю, вы, вероятно, не делаете этого, продолжайте чтение), чтобы каждый слушатель имел доступ к своему собственному родителю, и, делая это, мы можем проверить
- Текущий checkBoxTreeItem выбран
- Родитель не является нулевым, то есть он не является вершиной дерева
- Родитель не выбран, и он не будет выбран проверка текущего checkBoxTreeItem
, который позволяет нам принять решение о том, следует ли нам выполнить необходимый код. Важной частью является то, что слушатель кода, который вы хотите проверить, имеет доступ к родительскому элементу, чтобы он мог выяснить, нужно ли ему запускать.
Вот мое решение
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
CheckBoxTreeItem rootItem = buildNewCheckBoxTreeItem("Root", null);
CheckBoxTreeItem aItem = buildNewCheckBoxTreeItem("A", rootItem);
CheckBoxTreeItem a1Item = buildNewCheckBoxTreeItem("A_1", aItem);
CheckBoxTreeItem a2Item = buildNewCheckBoxTreeItem("A_2", aItem);
CheckBoxTreeItem bItem = buildNewCheckBoxTreeItem("B", rootItem);
CheckBoxTreeItem cItem = buildNewCheckBoxTreeItem("C", rootItem);
aItem.getChildren().addAll(a1Item, a2Item);
rootItem.getChildren().addAll(aItem, bItem, cItem);
rootItem.setExpanded(true);
TreeView<String> treeView = new TreeView<>(rootItem);
treeView.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
aItem.setExpanded(true);
VBox vBox = new VBox(treeView);
Scene scene = new Scene(vBox, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private CheckBoxTreeItem buildNewCheckBoxTreeItem(String text, CheckBoxTreeItem parentCheckBoxTreeItem){
CheckBoxTreeItem<String> checkBoxTreeItem = new CheckBoxTreeItem<>(text);
checkBoxTreeItem.selectedProperty().addListener((observable) -> {
if(shouldFireListener(checkBoxTreeItem, parentCheckBoxTreeItem))
System.out.println(checkBoxTreeItem.getValue());
});
return checkBoxTreeItem;
}
private boolean shouldFireListener(CheckBoxTreeItem checkBoxTreeItem, CheckBoxTreeItem parentCheckBoxTreeItem){
if(checkBoxTreeItem.isSelected()){
if(parentCheckBoxTreeItem!=null) {
if (!parentCheckBoxTreeItem.isSelected() && !goingToBeSelected(parentCheckBoxTreeItem))
return true;
}
else
return true;
}
return false;
}
private boolean goingToBeSelected(CheckBoxTreeItem parent){
ArrayList<CheckBoxTreeItem> childrenArraylist = new ArrayList<>();
for (Object child : parent.getChildren()) {
if(child instanceof CheckBoxTreeItem)
childrenArraylist.add(((CheckBoxTreeItem) child));
}
return childrenArraylist.stream().allMatch(CheckBoxTreeItem::isSelected);
}
}
РЕДАКТИРОВАТЬ: я столкнулся с ошибкой, когда, например, вы выбираете A_1 и A_2 A будет выбирать и запускать, но снятие отметки и перепроверка либо A_1 или A_2 не перезапустит A