是否可以在JavaFX中创建动态Bindings.OR?

时间:2017-09-13 14:50:34

标签: java javafx

让我们考虑以下情况。有一个Pane parentPane,有Pane firstChildPane, secondChildPane, thirdChildPane ...。子窗格将添加到父窗格。如果可以看到任何子窗格,并且可以动态添加和删除子窗格而没有任何限制和任何顺序,那么如何才能使parentPane可见。当然,childPane可见状态也可以随时更改。是否有可能创建动态Bindings.OR以便我可以动态添加/删除子可见属性?如果是,那怎么样?如果没有,那么在这种情况下使用什么解决方案?

1 个答案:

答案 0 :(得分:4)

您可以尝试以下几行:

// 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

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);