我有一种情况,我想将BooleanProperty绑定(bind)到包装在ObservableList中的ObjectProperty的非空状态。

这是我要寻找的行为的基本概要:

    ObjectProperty<ObservableList<String>> obp = new SimpleObjectProperty<ObservableList<String>>();

    BooleanProperty hasStuff = new SimpleBooleanProperty();

    hasStuff.bind(/* What goes here?? */);

    // ObservableProperty has null value
    assertFalse(hasStuff.getValue());

    obp.set(FXCollections.<String>observableArrayList());

    // ObservableProperty is no longer null, but the list has not contents.
    assertFalse(hasStuff.getValue());

    obp.get().add("Thing");

    // List now has something in it, so hasStuff should be true
    assertTrue(hasStuff.getValue());

    obp.get().clear();

    // List is now empty.
    assertFalse(hasStuff.getValue());

我想在Bindings类中使用构建器,而不是实现一系列自定义绑定(bind)。

理论上,Bindings.select(...)方法可以满足我的要求,只是没有Bindings.selectObservableCollection(...),并且将通用select(...)的返回值强制转换为Bindings.isEmpty(...)并不可行。也就是说,其结果是:
    hasStuff.bind(Bindings.isEmpty((ObservableList<String>) Bindings.select(obp, "value")));

导致ClassCastException:
java.lang.ClassCastException: com.sun.javafx.binding.SelectBinding$AsObject cannot be cast to javafx.collections.ObservableList

仅使用Bindings API可以使用这种用例吗?

解决方案

根据@fabian的回答,以下是有效的解决方案:
    ObjectProperty<ObservableList<String>> obp = new SimpleObjectProperty<ObservableList<String>>();

    ListProperty<String> lstProp = new SimpleListProperty<>();
    lstProp.bind(obp);

    BooleanProperty hasStuff = new SimpleBooleanProperty();
    hasStuff.bind(not(lstProp.emptyProperty()));

    assertFalse(hasStuff.getValue());

    obp.set(FXCollections.<String>observableArrayList());

    assertFalse(hasStuff.getValue());

    obp.get().add("Thing");

    assertTrue(hasStuff.getValue());

    obp.get().clear();

    assertFalse(hasStuff.getValue());

最佳答案

我没有看到仅使用Bindings API做到这一点的方法。 ObservableList没有空属性,因此您不能使用

Bindings.select(obp, "empty").isEqualTo(true)


ObjectBinding<ObservableList<String>> lstBinding = Bindings.select(obp);
hasStuff.bind(lstBinding.isNotNull().and(lstBinding.isNotEqualTo(Collections.EMPTY_LIST)));

之所以不起作用,是因为它仅在列表更改时才更新,而不是在内容更改时才更新(即第三个断言失败)。

但是您必须创建的自定义绑定(bind)链非常简单:
SimpleListProperty lstProp = new SimpleListProperty();
lstProp.bind(obp);
hasStuff.bind(lstProp.emptyProperty());

关于java - 是否可以使用Bindings API将ObservableList的非空状态绑定(bind)到ObjectProperty中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21612969/

10-10 21:19