Используйте Collectors.groupingBy
, чтобы получить Map<String, List<Permission>>
.Это позволяет вам легко создавать соответствующие CheckBox
es для группы и вложенных элементов в одной и той же итерации цикла путем итерации набора записей.
Создать List
вложенных элементов CheckBox
esв группе, чтобы позволить вам обновить их при изменении выбранного состояния группы CheckBox
и проверить, если все, ни один или некоторые CheckBox
es выбраны для обновления группы CheckBox
.
Чтобы правильно выровнять все CheckBox
независимо от длины названий групп, я рекомендую использовать GridPane
btw.
Вам необходимо настроить это немного, чтобы учесть тот факт, что ваш список содержит Permission
s:
@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
, - не определено иначе