2017-09-13 32 views
1

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

+0

给看看:https://stackoverflow.com/questions/33185073 /如何观察子节点的可见性 – Linuslabo

+0

相关:[JavaFX中的多布尔绑定](https://stackoverflow.com/questions/32192963/multiple-boolean-binding-in -javafx)。 – jewelsea

回答

3

您可以尝试大意如下的内容:

// 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); 
+0

现在轮到我发表评论[您正在使用的工厂方法](https://docs.oracle.com/javase/8/javafx/api/javafx/beans/binding/Bindings.html#bindContent-java。 util.List-javafx.collections.ObservableList-)states“一旦一个List绑定到一个ObservableList,该List不能直接被改变,这样做会导致意想不到的结果。”,所以'bindContentBidirectional'似乎是一个更安全的选择... – Itai

+0

@sillyfly但是'children'不会直接在这里改变(很容易使它成为局部变量,否则封装它,所以不能直接更改) –

+0

呃...我没有意识到这是相反的方式!这似乎有点反直觉,它是不可观察的列表被“绑定”到可观察的列表(因此可观察的列表是可以安全地更改的列表),但我想这是唯一有意义的方法。 – Itai

相关问题