如果选择了另一个动态创建的复选框,请选择动态创建的复选框

时间:2018-06-25 00:04:03

标签: java javafx

如果选中了另一个复选框(也是动态创建的),是否可以选择复选框(动态创建的)?

我要做的是根据复选框的名称对复选框进行分组。

例如:'create family', 'edit family', 'delete family' 将按字符串family分组。

然后,使用这些字符串创建复选框,并在它们之间添加事件侦听器,因此,如果选择了parent,则也选择了其他监听器。

例如:如果选择了family,则应该选择'create family', 'edit family', 'delete family'

这就是我在做什么:

public void fillPermisions() {
    System.out.println("filling up the permissions");
    Call<List<Permission>> permCall = retro.getPermissionList();
    permCall.enqueue(new Callback<List<Permission>>() {
        @Override
        public void onResponse(Call<List<Permission>> call, Response<List<Permission>> response) {
            int statusCode = response.code();

            if(response.isSuccessful()){
                Platform.runLater(()->{
                    permList =  response.body();
                    numPermissions = permList.size();
                    HBox hbox = null;
                    VBox vbox = null;
                    CheckBox parent = null;
                    String xx = "";

                    /*
                    Here, permList is a list like this:
                    ['create family', 'edit family', 'delete family', 'create users', 'edit users', ...]
                    So, I'm grouping these by the second string.
                    */

                    for(int i=0; i<numPermissions; i++){
                        String[] parts = permList.get(i).getName().split(" ");

                        if (!xx.equals(parts[1])) {
                            xx = parts[1];

                            if (i!=0) {
                                vBoxPermissions.getChildren().add(hbox);
                            }

                            hbox = new HBox();
                            vbox = new VBox();

                            System.out.println(xx);
                            parent = new CheckBox();
                            parent.setMinWidth(200);
                            parent.setText(xx);

                            /* HERE! if parent is checked, check all the others generated dynamically */

                            hbox.getChildren().add(parent);

                            CheckBox cbPerm = new CheckBox();
                            cbPerm.setMinWidth(20);
                            cbPerm.setText(permList.get(i).getName());
                            cbPerm.setUserData(permList.get(i));
                            vbox.getChildren().add(cbPerm);
                            hbox.getChildren().add(vbox);


                        } else {
                            CheckBox cbPerm = new CheckBox();
                            cbPerm.setMinWidth(20);
                            cbPerm.setText(permList.get(i).getName());
                            cbPerm.setUserData(permList.get(i));
                            vbox.getChildren().add(cbPerm);
                        }
                    }

                });
            }
        }
        @Override
        public void onFailure(Call<List<Permission>> call, Throwable t) {
            System.out.println("Error fill table Role");
        }
    });

}

这就是我想要做的: 如果选中左侧复选框,则基本上选择右侧的复选框。

Dinamically created checkboxes

2 个答案:

答案 0 :(得分:0)

由于要将所有子复选框都添加到HBox,因此可以在ForEach复选框上向监听器添加parent循环:

for (Node cb :
    hbox.getChildren()) {
    ((CheckBox)cb).setSelected(true);
}

这将遍历HBox中的每个节点,并将其转换为CheckBox并选择它。

如果您希望基于selectedProperty的{​​{1}}切换所有复选框的选择/取消选择,则有两个选择。

一种方法是使用与上述相同的循环,但是根据父级的选定状态调用parent

setSelected()

另一个选择是将新复选框的值绑定到父复选框的值。这不需要循环:

parent.selectedProperty().addListener((observableValue, wasSelected, isSelected) -> {
    for (Node cb :
        hbox.getChildren()) {
        ((CheckBox)cb).setSelected(isSelected);
    }
});

选择哪种方法取决于应用程序其余部分的结构。您提供的代码并未提供足够的详细信息,但这应该使您朝正确的方向前进。

答案 1 :(得分:0)

使用Collectors.groupingBy获得一个Map<String, List<Permission>>。这样,您可以通过迭代条目集轻松地在循环的同一迭代中为组和子元素创建相应的CheckBox es。

在组中的子List中创建CheckBox,以便在更改组CheckBox的选定状态时进行更新,并检查是否全部或选择了一些CheckBox以更新组CheckBox

要独立于组名的长度正确对齐所有CheckBox,我建议使用GridPane btw。

您需要对此进行一些调整以适应列表中包含Permission的事实:

@Override
public void start(Stage primaryStage) {
    List<String> permList = Arrays.asList("1 a", "2 a", "3 a", "1 b", "2 b", "3 b");

    // group strings by second word
    Map<String, List<String>> groups = permList.stream()
                                               .collect(Collectors.groupingBy(s -> s.split(" ")[1],
                                                                              LinkedHashMap::new,
                                                                              Collectors.toList()));

    GridPane grid = new GridPane();
    grid.setHgap(20);

    int index = 0;
    for (Map.Entry<String, List<String>> entry : groups.entrySet()) {
        // create CheckBox for group
        CheckBox groupBox = new CheckBox(entry.getKey());
        grid.add(groupBox, 0, index);

        List<String> value = entry.getValue();

        // list of CheckBoxes for sub elements of group
        List<CheckBox> checkBoxes = new ArrayList<>(value.size());

        // select/unselect CheckBoxes from group when group box is selected/unselected
        groupBox.selectedProperty().addListener((o, oldValue, newValue) -> {
            for (CheckBox cb : checkBoxes) {
                cb.setSelected(newValue);
            }
        });

        // create sub CheckBoxes
        for (String s : value) {
            CheckBox cb = new CheckBox(s);
            cb.selectedProperty().addListener((o, oldValue, newValue) -> {
                // update group CheckBox to unselected, selected or indeterminate
                // respectively if all, none or some CheckBoxes are selected.
                long count = checkBoxes.stream().filter(CheckBox::isSelected).count();
                groupBox.setIndeterminate(false);
                if (count == 0) {
                    groupBox.setSelected(false);
                } else if (count == checkBoxes.size()) {
                    groupBox.setSelected(true);
                } else {
                    groupBox.setIndeterminate(true);
                }
            });
            checkBoxes.add(cb);
            grid.add(cb, 1, index++);
        }
    }

    final Scene scene = new Scene(grid);

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

通过上述实现,您不仅可以更新子CheckBox,还可以根据组中所选CheckBox es的数量来设置组CheckBox的状态:< / p>

  • 未选中,如果未选择CheckBox,则
  • 已选择,如果所有CheckBox被选中
  • 否则确定