gpt4 book ai didi

JavaFX CheckboxTreeItem : only handle the selected checkbox

转载 作者:行者123 更新时间:2023-12-01 10:22:39 27 4
gpt4 key购买 nike

假设我有一个类似于示例中的 treeView。当我选中一片叶子的复选框(例如 a1Item、a2Item)时,控制台中只会打印一行。当我选择一个 parentItem(例如 rootItem、aItem)时,项目的行和 childItems 的行将被打印,因为 childItems 将被自动选择。
我正在寻找的是一种只处理选中的复选框,但保留 treeView 的结构和功能(子项的自动选择)的方法。

public class Main extends Application {
public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage primaryStage) {
CheckBoxTreeItem<String> rootItem = createCheckBoxTreeItem("Root");
CheckBoxTreeItem<String> aItem = createCheckBoxTreeItem("A");
CheckBoxTreeItem<String> a1Item = createCheckBoxTreeItem("A_1");
CheckBoxTreeItem<String> a11Item = createCheckBoxTreeItem("A_1_1");
CheckBoxTreeItem<String> a12Item = createCheckBoxTreeItem("A_1_2");
CheckBoxTreeItem<String> a111Item = createCheckBoxTreeItem("A_1_1_1");
CheckBoxTreeItem<String> a2Item = createCheckBoxTreeItem("A_2");
CheckBoxTreeItem<String> a21Item = createCheckBoxTreeItem("A_2_1");
CheckBoxTreeItem<String> a211Item = createCheckBoxTreeItem("A_2_1_1");
CheckBoxTreeItem<String> a22Item = createCheckBoxTreeItem("A_2_2");
CheckBoxTreeItem<String> bItem = createCheckBoxTreeItem("B");
CheckBoxTreeItem<String> cItem = createCheckBoxTreeItem("C");

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<String> createCheckBoxTreeItem(String value) {
CheckBoxTreeItem<String> checkBoxTreeItem = new CheckBoxTreeItem<>(value);
checkBoxTreeItem.selectedProperty().addListener((observable, oldValue, newValue) -> {
System.out.println(checkBoxTreeItem.getValue() + " - selected: " + newValue);
});
return checkBoxTreeItem;
}
}

编辑

我将树扩展了 2 个级别,希望这能帮助我找到解决方案。当我选择 rootItem/parentItem 时,我注意到输出将从底部(叶)打印到所选项目。但是当我选择例如叶子 A_1_1_1, A_1_1 将首先打印。

最佳答案

因此,首先我不希望您在您的应用程序中实现这个确切的代码,这只是为了让您了解如何实现这样的事情。它的工作方式是将父级传递给构建 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

关于JavaFX CheckboxTreeItem : only handle the selected checkbox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59641574/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com