Java 如何将属性绑定到列表属性中对象的属性?

Java 如何将属性绑定到列表属性中对象的属性?,java,javafx,Java,Javafx,我有以下课程: class Parent { BooleanProperty total = new SimpleBooleanProperty(); SimpleListProperty<Child> children = new SimpleListProperty<>(FXCollections.observableArrayList()); } class Child { BooleanProperty single = new Si

我有以下课程:

class Parent {

    BooleanProperty total = new SimpleBooleanProperty();
    SimpleListProperty<Child> children = new SimpleListProperty<>(FXCollections.observableArrayList());
}

class Child {

    BooleanProperty single = new SimpleBooleanProperty();
}
这是最好的方式吗


我还应该将
total
设置为只读,因为写入绑定属性将引发异常?

显式绑定到每个子级的
单个
属性的一个可能问题是,这些绑定是在调用
total.bind(…)
语句时进行的。因此,如果随后将新的
Child
对象添加到列表中,则不会观察到这些子对象的
单个属性,并且如果这些属性发生更改,绑定也不会失效。类似地,如果从列表中删除子项,则其
single
属性将不会解除绑定

作为替代方案,您可以使用创建列表。请注意,对于大多数用例,您不需要使用
ListProperty
:直接使用
ObservableList
就足够了。所以你可以这么做

ObservableList<Child> children = 
    FXCollections.observableArrayList(c -> new Observable[]{c.singleProperty()});
<>最后,考虑使用<代码> RealOnLyBooLangWraseP< <代码>,以便将属性公开为只读。这是一个完整的封装版本:

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 ;
    }

}

创建绑定后列表是否会更改?@James\u D yes。我现在正在阅读您的答案,这当然是一个我不知道的好观点。因此,这种方法的工作原理是,更改子对象的
单个
属性会导致列表属性向其所有观察者“触发更新事件”(绑定属性)?当我将依赖项列为
children
时,如果
children
本身发生了变化(列表被替换),或者如果构造函数中列出的任何可观察项发生了变化,那么绑定属性将被更新。。。嗯,只有在新列表附加了提取器的情况下才有效,这显然可能是个问题。只要列表有一个提取器,那么列表本身就会观察提取器返回的属性,如果任何属性无效,列表就会变得无效。您真的需要子列表是可变的吗(即
setChildren()
方法);对于大多数用例,有一个不可变(但可修改)的列表就足够了(即没有
setChildren()
方法,但是有
getChildren()
方法,所以你可以做
getChildren().setAll(…)
),例如)。不,
children
本身不会被替换,也没有
setChildren
。我想了解绑定-绑定更新的条件是什么。如果没有
setChildren()
,则不需要
ListProperty
;直接使用
可观察列表即可。让我更新一下…@Mark只需使用一个带有getter的
ObservableList
属性(例如)。
total.bind(Bindings.createBooleanBinding(() -> 
    children.stream().anyMatch(Child::isSingle), children);
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);
    }
}