【问题标题】:Create BooleanBinding binded with List/ObstableList values使用 List/ObstableList 值创建布尔绑定绑定
【发布时间】:2018-10-23 12:40:58
【问题描述】:

我正在尝试创建与Button#disableProperty() 绑定的BooleanBinding。我的目的是在从动态创建的面板列表更改TextField 时启用/禁用“确定”按钮。

这是面板列表(propertiesList)的初始化

<DialogPane prefWidth="900" prefHeight="600" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1">

    <fx:define>
        <FXCollections fx:id="propertiesList" fx:factory="observableArrayList">
            <DatabasePane name="База данни"/>
            <DatabasePane name="База данни 2"/>
        </FXCollections>
    </fx:define>

    ....

    <buttonTypes>
        <ButtonType fx:id="okButtonType" buttonData="OK_DONE" text="Готово" />
        <ButtonType buttonData="CANCEL_CLOSE" text="Затвори" />
    </buttonTypes>

</DialogPane>

每个DatabasePane 都包含名为change 的BooleanProperty 以及相应的getter 和setter。

在控制器中,我从propertiesList 中添加的面板属性创建了一个BooleanProperty 集合

List<BooleanProperty> list = propertiesList.stream()
    .map(pane -> pane.changeProperty())
    .collect(Collectors.toList());

BooleanBinding change = Bindings.createBooleanBinding(() -> true, (BooleanProperty[]) list.toArray());

Button button = (Button) dialogPane.lookupButton(okButtonType);
button.disableProperty().bind(change.not());
java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljavafx.beans.property.BooleanProperty; ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; [Ljavafx.beans.property.BooleanProperty; is in module javafx.base of loader 'app')

如果我使用ObservableList,则没有错误,但只会对列表本身进行更改

ObservableList<BooleanProperty> list = propertiesList.stream()
    .map(pane -> pane.changeProperty())
    .collect(Collectors.toCollection(() -> FXCollections.observableArrayList()));

BooleanBinding change = Bindings.createBooleanBinding(() -> true, list);

Button button = (Button) dialogPane.lookupButton(okButtonType);
button.disableProperty().bind(change.not());

【问题讨论】:

    标签: javafx binding observable


    【解决方案1】:

    List.toArray() 返回一个 Object[] 数组而不是一个 BooleanProperty[] 数组,但是您在此处将对象数组转换为 BooleanProperty:

    (BooleanProperty[]) list.toArray()
    

    我推荐使用Stream's toArray method taking a IntFunction:

    Observable[] dependencies = propertiesList.stream()
                                              .map(DatabasePane::changeProperty)
                                              .toArray(Observable[]::new);
    
    BooleanBinding change = Bindings.createBooleanBinding(() -> true, dependencies);
    

    除非您将 Callable&lt;Boolean&gt; 更改为更有意义的内容,否则您也可以忽略依赖项,因为绑定从不包含值,而是包含 true。


    BooleanBinding change = Bindings.createBooleanBinding(() -> true, list);
    

    不起作用,因为列表本身实现了Observable,因此您将一个仅包含列表的数组传递给可变参数参数,即它相当于

    BooleanBinding change = Bindings.createBooleanBinding(() -> true, new Observable []{ list });
    

    并且添加的唯一InvalidationListener 被添加到列表本身,而不是它的内容。

    【讨论】:

    • 您的解决方案非常完美。我给出的只是一个例子,所以我们让它返回了 true。 10x
    猜你喜欢
    • 2011-01-27
    • 1970-01-01
    • 2018-03-01
    • 2019-02-22
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 2021-04-02
    相关资源
    最近更新 更多