Фильтр TableView с неизвестным количеством флажков - PullRequest
0 голосов
/ 23 марта 2019

Я пишу приложение JavaFX с TableView, которое должно быть отфильтровано с помощью флажков.

Однако количество флажков зависит от данных в самой таблице.Краткий пример: у меня есть таблица игроков в игре.Количество игроков может варьироваться от 1 до 12.Таблица отображает несколько строк данных для каждого игрока, например:

  • Player 1 |Действие A
  • Player 2 |действие B
  • Player 3 |Действие C
  • Игрок 1 |действие C
  • Player 2 |Действие C
  • Игрок 1 |действие B

В этом случае количество игроков равно 3. Поэтому, чтобы иметь возможность фильтровать действия конкретных игроков, я добавляю 3 флажка во время выполнения:
- показать действия игрока 1,
- показать действия игрока 2,
- показать действия игрока 3.

У меня есть несколько других таблиц в моем программном обеспечении, которые я уже фильтрую с ObjectProperty и ObjectBinding, но количество опций фильтраизвестны заранее, поэтому я могу легко связать их.Вот пример для известного количества 3 игроков:

FilteredList<TableEntry> filteredData = new FilteredList<>(tableItemsActions);
List<ObjectProperty<Predicate<TableEntry>>> filters = FXCollections.observableArrayList();
tableViewActions.setItems(filteredData);

//Initialize checkBox and filter for player
for (Player player : data.getPlayers()) {
    CheckBox checkBox = new CheckBox("Show " + player.getName() + " actions");
    checkBox.setPadding(new Insets(5));
    checkBox.setSelected(true);

    ObjectProperty<Predicate<TableEntry>> playerFilter = new SimpleObjectProperty<>();
    playerFilter.bind(Bindings.createObjectBinding(() -> 
    tableEntry -> {
        if (tableEntry.getPlayerName() == player.getName() && checkBox.isSelected()) {
            return true;
        } else {
            return false; 
        }
    },
    checkBox.selectedProperty()));
    filters.add(playerFilter);
    flowPanePlayerCheckboxes.getChildren().add(checkBox);
}

//Combine filters for list
filteredData.predicateProperty().bind(Bindings.createObjectBinding(
() -> 
filters.get(0).get()
.or(filters.get(1).get())
.or(filters.get(2).get()),
filters.get(0), filters.get(1), filters.get(2)));

Так что мне нужен способ объединить неизвестное количество фильтров в одну привязку для предиката свойства отфильтрованного списка.

Я уже часами искал решение, и я думаю, что самое близкое к тому, что мне нужно, вероятно, связано с этим кодом в этом сообщении :

filteredList.predicateProperty().bind(Bindings.createObjectBinding(() ->
filters.stream().reduce(x -> true, Predicate::and),
filters));

Однако я не могу 'я не могу заставить его работать в моем случае.

Я надеюсь, что я на правильном пути, и вы можете мне помочь, но если я смогу решить всю проблему совершенно по-другому, пожалуйста, скажите мне.

Заранее спасибо!

...