我有这些课:
class Parent {
BooleanProperty total = new SimpleBooleanProperty();
SimpleListProperty<Child> children = new SimpleListProperty<>(FXCollections.observableArrayList());
}
class Child {
BooleanProperty single = new SimpleBooleanProperty();
}
我想要的是,total
当且仅当所有孩子的single
s均为假时,才会为假。换句话说,当且仅当有一个孩子single
为true时,才total
为true。
我想出了这种绑定
total.bind(Bindings.createBooleanBinding(() -> {
return children.stream().filter(c -> c.isSingle()).findAny().isPresent();
}, children.stream().map(c -> c.single).collect(Collectors.toCollection(FXCollections::observableArrayList))));
这是最好的方法吗?
此外,我应该做total
只读,因为写一个绑定属性将抛出一个异常?
有明确绑定到每一个孩子的一个可能的问题single
性质,就是当这些绑定是由total.bind(...)
被调用语句。因此,如果随后将新Child
对象添加到列表中,则将不会观察那些子级的属性,并且如果更改了它们,绑定也不会无效。同样,如果一个孩子从列表中删除,它的属性不会松绑。single
single
作为替代方案,您可以创建具有列表提取。请注意,对于大多数使用情况,您不需要ListProperty
:,只需ObservableList
直接使用即可。所以你可以做
ObservableList<Child> children =
FXCollections.observableArrayList(c -> new Observable[]{c.singleProperty()});
现在,如果任何元素single
属性无效(以及将元素添加到列表或从列表添加元素),此列表将触发更新通知(并变为无效)。换句话说,列表本身观察每个孩子的single
属性,并且如果任何孩子的single
属性变为无效,则列表变为无效(导致与其绑定的任何内容变为无效)。名单中还可以确保其遵守新的儿童single
,当他们被添加到列表属性,并停止观察他们时,孩子被从列表中删除。
那你只需要
total.bind(Bindings.createBooleanBinding(() ->
children.stream().anyMatch(Child::isSingle), children);
最后,考虑使用aReadOnlyBooleanWrapper
来将属性公开为只读。这是整件事的正确封装版本:
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 ;
}
}
和
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);
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句