JavaFX在控件中显示属性

par*_*zab 6 java javafx javafx-8

我正在自己完成Oracle的JavaFX教程.经过多年的摇摆(很久以前),我对新的智能功能很着迷,包括.属性.我很惊讶地发现这些例子(例如:https://docs.oracle.com/javafx/2/ui_controls/table-view.htm)并没有以我认为"正确"的方式使用它们.

该示例创建一个Person具有属性作为字段的类:

public static class Person {
    private final SimpleStringProperty firstName;
    ...
Run Code Online (Sandbox Code Playgroud)

但吸气剂不是属于物业,而是属于他们的价值观

    public String getFirstName() {
        return firstName.get();
    }
Run Code Online (Sandbox Code Playgroud)

所以当它将它们绑定到TableCell列中的s时,它会将它们包装在一个新属性中:

    emailCol.setCellValueFactory(
            new PropertyValueFactory<Person, String>("firstName"));
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎很复杂,并且错过了事件传播的真正优势,不仅仅是使用它:

    firstNameCol.setCellValueFactory( celldata -> 
        celldata.getValue().firstNameProperty());
Run Code Online (Sandbox Code Playgroud)

我的问题:这个例子是否有理由不直接在控件中公开和使用 bean的属性?我在这里错过了什么吗?

注意:我确实以这种方式更改了代码,并且示例运行得更好:Person其他控件对实体的更新立即传播,无需调用table.refresh()例如

Jam*_*s_D 7

首先,请注意,如果您遵循预期的模式:

public class Person {

    private final StringProperty firstName = new SimpleStringProperty();

    public StringProperty firstNameProperty() {
        return firstName ;
    }

    public final String getFirstName() {
        return firstNameProperty().get();
    }

    public final void setFirstName(String firstName) {
        firstNameProperty().set(firstName);
    }
}
Run Code Online (Sandbox Code Playgroud)

那么你的代码版本都可以在不调用的情况下工作table.refresh().PropertyValueFactory正如文档中相当清楚的那样,这是预期用途.

但是,你是正确的,lambda表达式是一种比它更好的方法PropertyValueFactory.除了引用的原因外,使用lambda表达式还有其他主要优点PropertyValueFactory.首先,最重要的是,PropertyValueFactory简单地将属性的名称作为a String,这意味着它没有编译时检查.所以,如果你拼错了房产的名称:

firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstname"));
Run Code Online (Sandbox Code Playgroud)

这会编译得很好,你最终会在列中找到空白单元格.这可能很难调试(正如本网站上的问题数量所证明的那样,需要帮助解决这类错误:例如Javafx PropertyValueFactory没有填充Tableview).

其次,PropertyValueFactory反射的作品,比lambda表达慢得多.这可能导致可测量的性能差异,例如在对具有大量数据的表进行排序时.

PropertyValueFactory引入的原因基本上是历史性的.在Java 8之前,当然没有lambda表达式,因此没有这个便利类的单元工厂的最小实现是通过匿名内部类:

firstNameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person, String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(TableColumn.CellDataFeatures<Person, String> cellData) {
        return cellData.getValue().firstNameProperty();
    }
});
Run Code Online (Sandbox Code Playgroud)

由于该代码非常可怕,JavaFX团队PropertyValueFactory简单地介绍了简化API以使API更易于使用的方法.

使用Java 8及更高版本时,PropertyValueFactory应该将其视为遗留类,并且应首选lambda表达式.当然,早于Java 8的文档仍然存在(事实上,你明确地链接了JavaFX 2中的文档 - 虽然最新的版本仍然没有更新),并且坦率地说 - 太多其他作者了在没有正确思考的情况下复制那种风格.PropertyValueFactory完全弃用该类可能有一个很好的例子.

(所以:TL; DR:不,你没有遗漏任何东西.)