使用未知数量的Checkbox过滤TableView

时间:2019-03-23 20:22:28

标签: javafx filter stream predicate

我正在使用TableView编写JavaFX应用程序,应该使用复选框对其进行过滤。

但是,复选框的数量取决于表本身中的数据。 简短示例: 我有一张游戏的桌子。玩家人数可以从1至12不等。该表为每个玩家显示多个数据行,如下所示:

  • 玩家1 |动作A
  • 播放器2 |动作B
  • 播放器3 |动作C
  • 玩家1 |动作C
  • 播放器2 |动作C
  • 玩家1 |动作B

在这种情况下,玩家人数为3。 为了能够过滤特定玩家的动作,我在运行时添加了3个复选框:
-显示玩家1的动作,
-显示玩家2的动作,
-显示玩家3个动作。

我的软件中还有其他几张表,我已经使用ObjectPropertyObjectBinding进行了过滤,但是过滤器选项的数量是已知的,因此我可以轻松地链接它们。 这是一个已知的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)));

所以我需要的是一种将未知数量的过滤器组合到一个用于过滤列表的predicateProperty的绑定的方法。

我已经搜索了数小时的解决方案,我认为最接近我需要的解决方案可能与this post中的这段代码有关:

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

但是我无法使其适用于我的情况。

我希望我走了正确的道路,您可以帮助我,但是如果我可以用完全不同的方式解决整个问题,请告诉我。

谢谢!

0 个答案:

没有答案