代码之家  ›  专栏  ›  技术社区  ›  parszab

JavaFX在控件中显示属性

  •  6
  • parszab  · 技术社区  · 7 年前

    我正在自学Oracle的JavaFX教程。在做了很多年(很久以前)Swing之后,我对包括属性在内的新智能功能着迷。我惊讶地看到这些例子(例如: https://docs.oracle.com/javafx/2/ui_controls/table-view.htm )不要以我认为“恰当”的方式使用它们。

    该示例创建 Person 使用属性作为字段初始化:

    public static class Person {
        private final SimpleStringProperty firstName;
        ...
    

    但是getter不是用于属性,而是用于它们的值

        public String getFirstName() {
            return firstName.get();
        }
    

    所以当它将这些绑定到 TableCell 在列中,它将它们包装在新属性中:

        emailCol.setCellValueFactory(
                new PropertyValueFactory<Person, String>("firstName"));
    

    在我看来,这似乎很复杂,并且由于不简单地使用以下内容,而忽略了事件传播的真正优势:

        firstNameCol.setCellValueFactory( celldata -> 
            celldata.getValue().firstNameProperty());
    

    我的问题是:这个示例没有公开和 使用 该bean的属性是否直接位于控件中?我错过什么了吗?

    NB:我确实用这种方式修改了代码,而且这个示例的效果更好:在 其他控件的实体被立即传播,不调用 table.refresh() 例如

    1 回复  |  直到 7 年前
        1
  •  7
  •   James_D    7 年前

    首先,请注意,如果您按照 expected pattern :

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

    那么您的任一版本的代码都可以在不调用 table.refresh() . 这是 PropertyValueFactory ,从 documentation .

    但是,lambda表达式比 PropertyValue工厂 . 除了您引用的原因之外,使用lambda表达式还有其他主要优点 PropertyValue工厂 . 首先,也是最重要的是 PropertyValue工厂 只需将属性的名称作为 String ,这意味着它没有编译时检查。因此,如果您将物业名称拼写错误:

    firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstname"));
    

    这将很好地编译,您只需在列中使用空白单元格即可。这可能很难调试(这可以从该网站上要求帮助解决此类错误的问题的数量中得到证明:例如。 Javafx PropertyValueFactory not populating Tableview ).

    其次 PropertyValue工厂 通过反射工作,这比lambda表达式慢得多。这可能会导致可测量的性能差异,例如在对包含大量数据的表进行排序时。

    原因 PropertyValue工厂 基本上是历史性的。在Java 8之前,当然没有lambda表达式,因此没有这个方便类的cell factory的最小实现是通过匿名内部类实现的:

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

    由于该代码非常可怕,JavaFX团队引入了 PropertyValue工厂 只是为了使API更易于使用。

    使用Java 8及更高版本时, PropertyValue工厂 应该真正将其视为遗留类,并且应该首选lambda表达式。当然,早于Java 8的文档仍然存在(事实上,您明确链接了来自JavaFX 2的文档-尽管 most recent version 坦率地说,还有太多其他作家在没有正确思考的情况下复制了这种风格。可能有一个很好的理由来反对 PropertyValue工厂 完全初始化。

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