布尔属性如何与createBooleanBinding一起使用

时间:2019-05-20 03:10:19

标签: java javafx binding observable

我有以下代码:

public class Test {
    public static void main(String [] args) {

        ObservableList<Integer> l = FXCollections.observableArrayList();
        l.add(1);
        l.add(2);
        l.add(3);
        BooleanProperty isPlayable = new SimpleBooleanProperty();
        isPlayable.bind(Bindings.createBooleanBinding(() -> 
        {
            System.out.println("List has changed");

            return l.contains(2);
        },l
        ));
l.remove(1);

我不明白为什么这段代码只显示一次“列表已更改”?它应该两次,一次在绑定中,然后在删除中,因为该列表是可观察的。为什么列表更改不影响boolean属性?

(我在长代码中遇到了更大的问题,但是这种情况说明了我对布尔型属性绑定的误解)

谢谢!

1 个答案:

答案 0 :(得分:2)

ObservableValue的{​​{3}}(BindingProperty都继承):

  

ObservableValue的实现可能支持惰性求值,这意味着在更改后不会立即重新计算该值,而在下次请求该值时会延迟进行计算。该库中的所有绑定和属性都支持惰性评估。

     

ObservableValue生成两种类型的事件:更改事件和无效事件。更改事件表示该值已更改。如果当前值不再有效,则会生成一个无效事件。如果ObservableValue支持惰性求值,这一区别就变得很重要,因为对于惰性求值而言,直到重新计算无效值,才知道它是否真的已经改变。因此,生成变更事件需要进行急切的评估,而对于急切和懒惰的实现可以生成无效事件。

     

此类的实现应努力生成尽可能少的事件,以避免在事件处理程序中浪费太多时间。当第一个失效事件发生时,该库中的实现将自己标记为无效。在重新计算其值并再次使其有效之前,它们不再生成无效事件。

     

ObservableValue可以附加两种类型的侦听器:InvalidationListener侦听无效事件,ChangeListener侦听变更事件。

     

重要说明:即使ChangeListener的实现支持惰性求值,附加ObservableValue也会强制执行急切的计算。

请注意,Property#bindBindings#createXXXBinding都在相关性上注册了InvalidationListener,而不是ChangeListener

如您所见,核心JavaFX中的绑定和属性是惰性的。从ObservableList中删除元素后,您再也不会查询该值,因此永远不会重新计算该值。由于永远不会重新计算该值,因此不会再次调用您的Callable

我真的很惊讶您竟然看到"List has changed"。您的代码都不要求该值,因此我不会期望要计算该值。但是,从实现的角度来看,注册InvalidationListener 的行为使ObservableValue得到验证(即查询值),并且{{1} }添加一个#bind。我不确定实现为什么要这样做,但是确实可以。