2017-09-13 61 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

相關問題