Установите динамически созданный флажок, если выбран другой динамически созданный флажок - PullRequest
0 голосов
/ 25 июня 2018

Можно ли выбрать флажки (созданные динамически), если установлен другой флажок (также динамически созданный)?

Что я хочу сделать, это сгруппировать флажки на основе их имен.

Например: '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 голосов
/ 25 июня 2018

Используйте Collectors.groupingBy, чтобы получить Map<String, List<Permission>>.Это позволяет вам легко создавать соответствующие CheckBox es для группы и вложенных элементов в одной и той же итерации цикла путем итерации набора записей.

Создать List вложенных элементов CheckBox esв группе, чтобы позволить вам обновить их при изменении выбранного состояния группы CheckBox и проверить, если все, ни один или некоторые CheckBox es выбраны для обновления группы CheckBox.

Чтобы правильно выровнять все CheckBox независимо от длины названий групп, я рекомендую использовать GridPane btw.

Вам необходимо настроить это немного, чтобы учесть тот факт, что ваш список содержит Permissions:

@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 в соответствии с количеством выбранных CheckBox es в группе.:

  • не выбран, если не выбрано CheckBox, выбрано
  • , если выбрано все CheckBox,
  • не определено иначе
0 голосов
/ 25 июня 2018

Поскольку вы добавляете все дочерние флажки к HBox, вы можете добавить цикл ForEach к слушателю на флажке parent:

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

Это будет проходить через каждый узелв HBox приведите его к CheckBox и выберите его.

Если вы хотите, чтобы все флажки переключались, выбирались / не выбирались на основе selectedProperty из parent, у вас есть дваoptions.

Один из них - использовать тот же цикл, что и выше, но вызвать setSelected() в зависимости от выбранного статуса родителя:

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

Другой вариант - привязать значение нового флажка кэто из родителей.Для этого не требуется цикл:

cbPerm.selectedProperty().bind(parent.selectedProperty());

Какой метод вы выберете, зависит от того, как структурирована остальная часть вашего приложения;предоставленный вами код не дает достаточно подробностей, но это должно привести вас в правильном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...