我有这些课程:
class Parent {
BooleanProperty total = new SimpleBooleanProperty();
SimpleListProperty<Child> children = new SimpleListProperty<>(FXCollections.observableArrayList());
}
class Child {
BooleanProperty single = new SimpleBooleanProperty();
}
Run Code Online (Sandbox Code Playgroud)
我想要的是,total当且仅当所有孩子single都是假的时候,这将是假的.换句话说,当且仅当有一个孩子single为真时,total才是真的.
我想出了这个绑定
total.bind(Bindings.createBooleanBinding(() -> {
return children.stream().filter(c -> c.isSingle()).findAny().isPresent();
}, children.stream().map(c -> c.single).collect(Collectors.toCollection(FXCollections::observableArrayList))));
Run Code Online (Sandbox Code Playgroud)
这是最好的方法吗?
我也应该total只读,因为写入绑定属性会抛出异常吗?
显式绑定到每个子single属性的一个可能问题是,在total.bind(...)调用语句时会产生这些绑定.因此,如果随后将新Child对象添加到列表中,则不会观察到这些子对象的属性,并且如果它们发生更改,则绑定将不会失效.同样,如果从列表中删除子项,则其属性将不会被解除绑定.singlesingle
或者,您可以使用提取器创建列表.请注意,对于大多数用例,您不需要ListProperty:只需ObservableList直接使用即可.所以你可以做到
ObservableList<Child> children =
FXCollections.observableArrayList(c -> new Observable[]{c.singleProperty()});
Run Code Online (Sandbox Code Playgroud)
如果任何元素single属性无效(以及在列表中添加元素的时候),此列表现在将触发更新通知(并变为无效).换句话说,列表本身会观察每个子项的single属性,如果任何子项的single属性变为无效,列表将变为无效(导致绑定到它的任何内容无效).该列表还确保它single在添加到列表时观察新子项的属性,并在从列表中删除子项时停止观察它们.
那你就需要了
total.bind(Bindings.createBooleanBinding(() ->
children.stream().anyMatch(Child::isSingle), children);
Run Code Online (Sandbox Code Playgroud)
最后,考虑使用a ReadOnlyBooleanWrapper以将属性公开为只读.这是整个事物的正确封装版本:
public class Parent {
private ReadOnlyBooleanWrapper total = new ReadOnlyBooleanWrapper();
private ObservableList<Child> children =
FXCollections.observableArrayList(c -> new Observable[] {c.singleProperty()});
public Parent() {
total.bind(Bindings.createBooleanBinding(() ->
children.stream().anyMatch(Child::isSingle), children);
}
public ReadOnlyBooleanProperty totalProperty() {
return total.getReadOnlyProperty();
}
public ObservableList<Child> getChildren() {
return children ;
}
}
Run Code Online (Sandbox Code Playgroud)
和
public class Child {
private final BooleanProperty single = new SimpleBooleanProperty();
public BooleanProperty singleProperty() {
return single ;
}
public final boolean isSingle() {
return singleProperty().get();
}
public final void setSingle(boolean single) {
singleProperty().set(single);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
253 次 |
| 最近记录: |