【问题标题】:Is there some use case addressable only by PropertyValueFactory?是否有一些只能由 PropertyValueFactory 寻址的用例?
【发布时间】:2018-10-27 02:13:26
【问题描述】:

以下是在 JavaFX 中将 CellValueFactory 分配给 TableColumn 的三种方法。第一个使用匿名类,第二个使用 lambda,第三个使用 PropertyValueFactory

我的问题是关于第三种方式,使用PropertyValueFactory

查看源代码:

PropertyValueFactory

我看不出使用这个类有什么好处。

PropertyValueFactory的源代码中,有一个注释,他们通过缓存一个'PropertyReference'成员变量来“尝试提高大型表的性能”。与本说明相关,提到了对 RT-13937 的引用。我再也无法在网上找到这个 RT。

下面的事情在我的脑海中很混乱。

是否有一些使用PropertyValueFactory 技术无法使用其他两种技术解决的特定用例?

PropertyReference 成员变量的缓存是为了解决在大型表中使用 PropertyValueFactory 类的缓慢问题,这种缓慢是由该类使用反射引起的,还是“PropertyValueFactory”类本身旨在解决大表一般慢吗?

 /**
   First using an anonymous class
    */

        TableColumn<Person,String> firstNameCol = new TableColumn<Person,String>("First Name");

         firstNameCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() {
             public ObservableValue<String> call(CellDataFeatures<Person, String> p) {
                 // p.getValue() returns the Person instance for a particular TableView row
                 return p.getValue().firstNameProperty();
             }
          });


    /**Second using lambda
    */


        TableColumn<Person, String> firstNameCol =new TableColumn<>("First Name");

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


    /**Finally using PropertyValue
    */
        TableColumn<Person, String> firstNameCol =new TableColumn<>("First Name");

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

【问题讨论】:

  • 这是在 Java 7 中唯一不冗长的方法。在 Java 8 及更高版本中,它几乎是多余的。
  • 匿名类会产生更多的.class 文件。 Lambdas 应该产生一个更大的类文件。字节码的大小应该是最小的使用PropertyValueFactory...
  • 供您参考和上下文,RT-13937 错误已迁移到 jdk 错误跟踪器:bugs.openjdk.java.net/browse/JDK-8112885 并引用 Oracle 论坛问题线程:community.oracle.com/thread/2232797
  • James_D 谢谢!我发现了解其他开发人员如何详细考虑 API 很有帮助。
  • jewelsea:谢谢你的链接!非常有用!

标签: java javafx tablecolumn


【解决方案1】:

在您的用例中,使用 PropertyValueFactory 与使用 lambda/匿名类没有任何显着差异。

据我所知,这些是使用PropertyValueFactory的原因:

  1. 它更短,据说更方便,但我发现使用 lambda 也没有那么长。
  2. 它具有缓存,就像您提到的那样,但它适用于非 JavaFX 属性(即使用反射)。

因此,如果您正在寻找 PropertyValueFactory 的用例,那么最合适的用例是当您的属性是普通 POJO 属性时。

考虑一下:

public class Person {
    private String firstName;
    private String lastName;

    public final String getFirstName() { return firstName; }
    public final void setFirstName(String firstName) { this.firstName = firstName; }

    public final String getLastName() { return lastName; }
    public final void setLastName(String lastName) { this.lastName = lastName; }
}

TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() {
    public ObservableValue<String> call(CellDataFeatures<Person, String> p) {
        return new SimpleStringProperty(getPropertyReflectively(p.getValue(), "firstName", String.class));
    }
});

private static <T> T getPropertyReflectively(Object bean, String propertyName, Class<T> propertyType) {
    // Implementation to get property value reflectively
}

所以观察到两件事:

  1. 您需要自己编写凌乱的反射材料。可以做到,但是当PropertyValueFactory 为您做到这一点时,为什么要这样做呢?
  2. 您正在返回StringProperty新实例,并且每次滚动包含一百万个条目的大表时都会进行反思。

我相信提到的缓存用于观察#2。如果你想确定的话,你可以继续“破译”这些代码,因为我绝对没有尝试这样做。

【讨论】:

  • 在寻找其他东西时遇到了这个问题,但我只想提一下,可以在 FXML 文件中使用 PropertyValueFactory。虽然我仍然更喜欢 lambdas(在代码中),因为它是类型安全的并且它们避免了反射。
猜你喜欢
  • 1970-01-01
  • 2020-06-04
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 2010-10-13
  • 1970-01-01
相关资源
最近更新 更多