是否可以将ObjectProperty内的ObservableList的非空状态与Bindings API绑定?

时间:2014-02-06 20:09:08

标签: java binding javafx javafx-2 observable

我有一种情况,我希望将BooleanProperty绑定到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类中使用构建器,而不是实现一系列自定义绑定。

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

3 个答案:

答案 0 :(得分:5)

我没有看到使用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)));

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

但是你必须创建的自定义绑定链非常简单:

SimpleListProperty lstProp = new SimpleListProperty();
lstProp.bind(obp);
hasStuff.bind(lstProp.emptyProperty());

答案 1 :(得分:1)

可以使用更少的变量来完成:

SimpleListProperty<String> listProperty = new SimpleListProperty<>(myObservableList);

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

答案 2 :(得分:0)

真的是否必须是ObjectProperty<ObservableList<String>>?如果是这样,这个答案并没有解决你的问题......

但是,我认为如果你改变obp这样的类型:

Property<ObservableList<String>> obp = new SimpleListProperty<>();

你应该可以使用:

hasStuff.bind(Bindings.isEmpty((ListProperty<String>) obp));