Lets consider the following situation. There is a Pane parentPane
and there are Pane firstChildPane, secondChildPane, thirdChildPane ...
. Child panes a
You can try something along the following lines:
// 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);
Another approach is to create your own BooleanBinding
directly:
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);