【问题标题】:JavaFX: Bindings with presentation modelJavaFX:与表示模型的绑定
【发布时间】:2017-04-26 12:59:51
【问题描述】:

我的 JavaFX 应用程序应如下所示:

现在我想确保在我从表格视图中选择另一个人时,详细信息视图会立即适应。

到目前为止我的课程:

public class Person {
    private final StringProperty name = new SimpleStringProperty();
    private final StringProperty title = new SimpleStringProperty();
    private final IntegerProperty age = new SimpleIntegerProperty();

    public Person(String name, String title, int age) {
        setName(name);
        setTitle(title);
        setAge(age);
    }
    // Getters and Setters
}

public class PresentationModel {

    private final ObservableList<Person> persons = FXCollections.observableArrayList();
    private final ObjectProperty<Person> selectedPerson = new SimpleObjectProperty<>();

    public PresentationModel() {
        // add some users to persons list
    }

  // Getters/Setters

}

在带有表格的 UI 类中,我设置了这样的侦听器:

personsTable.getSelectionModel().selectedItemProperty().addListener((observable, oldPerson, newPerson) -> {
    model.setSelectedPerson(newPerson);
});

在带有详细信息视图的 UI 类中,我设置了一个绑定:

nameLabel.textProperty().bind(model.getSelectedPerson().nameProperty());

PresentationModel model 属性在应用程序启动时创建一次,然后通过构造函数传递给所有 UI 类。

但是这个绑定没有按预期工作。 我可以更改什么以使绑定正常工作并更改属性?

【问题讨论】:

    标签: java javafx presentation-model


    【解决方案1】:

    绑定不起作用,因为getSelectedPerson 只返回当前 选定的人,如果选定的人发生变化,则不会重新计算。

    只需使用标准 API,您就可以做到

    nameLabel.textProperty().bind(Bindings.selectString(
        model.selectedPersonProperty(), "name"));
    

    这个 API 在很多方面都不太令人满意。一方面,没有编译时检查selectedPersonProperty() 是否有nameProperty(),并且它的类型是否正确。其次,它使用反射,在您经常调用它的情况下效果不佳(此处不适用)。最后,如果所选人员为空,这会将大量多余的警告转储到标准输出(尽管 API 文档表明这是受支持的用例!!!)。

    ReactFX framework 提供了另一种选择:

    nameLabel.textProperty().bind(Val.selectVar(
        model.selectedPersonProperty(), Person::nameProperty));
    

    【讨论】:

    • 完美适用于单向绑定。但是我怎样才能以这种方式双向绑定属性呢?我使用标准 API 尝试了您的方法:nameTextField.textProperty().bindBidirectional(Bindings.selectString(model.selectedPersonProperty(), "name")); 例如,这不适用于文本字段的双向绑定。
    • @Robin 反向绑定不是唯一定义的,因为至少在理论上,您可以做两种完全不同的事情之一(更新所选人员的名称属性,或更新所选人员成为具有指定名称的新人)。因此Bindings.selectString() 不支持双向绑定(Bindings.selectString 返回StringBinding,而不是StringPropertyStringBinding 没有setsetValue 方法)。也就是说,ReactFX 框架版本会做你想做的事,因为它返回一个Var,它是Property 的一个实现。
    • @Robin 当然,另一个选择是使用监听器:nameTextField.textProperty().addListener((obs, oldName, newName) -&gt; model.getSelectedPerson().setName(newName));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多