让我们考虑以下情况。有一个Pane parentPane,有一个Pane firstChildPane, secondChildPane, thirdChildPane ...。子窗格将添加到父窗格。考虑到可以动态地添加和删除子窗格而没有任何限制和顺序的情况下,如何才能仅在可见子窗格的情况下使parentPane可见。当然childPane的可见状态也可以随时更改。是否可以创建动态Bindings.OR,以便我可以动态向其添加/删除子可见属性?如果是,那怎么办?如果没有,那么在这种情况下使用什么解决方案?
Pane parentPane
Pane firstChildPane, secondChildPane, thirdChildPane ...
您可以按照以下方式尝试操作:
// list that fires updates if any members change visibility: ObservableList<Node> children = FXCollections.observableArrayList(n -> new Observable[] {n.visibleProperty()}); // make the new list always contain the same elements as the pane's child list: Bindings.bindContent(children, parentPane.getChildren()); // filter for visible nodes: ObservableList<Node> visibleChildren = children.filter(Node::isVisible); // and now see if it's empty: BooleanBinding someVisibleChildren = Bindings.isNotEmpty(visibleChildren); // finally: parentPane.visibleProperty().bind(someVisibleChildren);
另一种方法是BooleanBinding直接创建自己的:
BooleanBinding
Pane parentPane = ... ; BooleanBinding someVisibleChildren = new BooleanBinding() { { parentPane.getChildren().forEach(n -> bind(n.visibleProperty())); parentPane.getChildren().addListener((Change<? extends Node> c) -> { while (c.next()) { c.getAddedSubList().forEach(n -> bind(n.visibleProperty())); c.getRemoved().forEach(n -> unbind(n.visibleProperty())) ; } }); bind(parentPane.getChildren()); } @Override public boolean computeValue() { return parentPane.getChildren().stream() .filter(Node::isVisible) .findAny() .isPresent(); } } parentPane.visibleProperty().bind(someVisibleChildren);