Java: setCellValuefactory;Lambda 与 PropertyValueFactory;优点缺点 [英] Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantages

查看:19
本文介绍了Java: setCellValuefactory;Lambda 与 PropertyValueFactory;优点缺点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天我在尝试更多地了解 JavaFX 和 Java 时遇到了另一件我不太了解的事情.

today i encountered another thing i don't really understand while trying to learn more about JavaFX and Java in general.

参考以下教程(我正在尝试将原理应用于组织者):

Reference is the following tutorial (im trying to apply the principle to an organizer):

JavaFX 8 教程

我将简要概述我有问题的特定部分:

I will give a short outline of the particular part on which i've got a question:

我的主窗口包含一个显示一些约会数据的表格视图.所以我得到了一些这种风格的线条(与教程中相同):

My main window contains a tableview which shows some appointment-data. So i got some lines of this style(same as in the tutorial):

aColumn.setCellValueFactory(cellData ->cellData.getValue().getAColumnsProperty());

可以通过附加的 EditDialog 操作数据.这工作得很好.如果我编辑内容,更改会立即显示,但我做了一些额外的研究以更好地理解 Lambda(不太成功).现在...在在线 Java 文档中 JavaDoc PropertyValueFactory 它说:回调接口的便捷实现,[...]"

The data can be manipulated via an additional EditDialog. That works just fine. If i edit things the changes are displayed immediately but i did some additional research to better understand the Lambda (not too successful). Now...in the online java documentation Java Doc PropertyValueFactory it says: "A convenience implementation of the Callback-Interface,[...]"

所以我将我的代码重构为这种风格:

So i refactored my code into this style:

aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));

我发现它比 Lambda 更具可读性.但我注意到,当我进行更改时,我需要在显示更改之前对 TableView 进行一些排序.

Which i find much more readable than the Lambda. But i noticed that when i make changes i need to do some sorting on the TableView before the changes are displayed.

是否有可能在第二种方法中立即显示变化?

Is it possible to achieve an immediate display of change in the second approach?

如果是:是否存在阻碍这种修改的主要缺点?IE.在这种情况下,Lambda 会是最佳实践吗?

If yes: are there major disavantages which would discourage such a modification? I.e. would the Lambda be the best practice in this situation?

感谢您的帮助.

推荐答案

PropertyValueFactory 需要正确命名的属性 getter.getAColumnsProperty 可能不是一个.

PropertyValueFactory expects correctly named property getters. getAColumnsProperty is probably not one.

如果是 new PropertyValueFactory(date")Appointment 类需要包含一个 dateProperty()方法;返回的值需要扩展 ReadOnlyProperty 才能工作,并且任何编辑只会导致模型自动更新,如果返回的对象也是 WritableValue.

In case of new PropertyValueFactory<Appointment, LocalDate>("date") the Appointment class needs to contain a dateProperty() method; the returned values need to extend ReadOnlyProperty for this to work and any edits will only lead to an update in the model automatically, if the returned object also WritableValue.

示例 Appointment 应该与 PropertyValueFactory<>(date") 一起使用:

Example Appointment class that should work with PropertyValueFactory<>("date"):

public class Appointment {
    private final ObjectProperty<LocalDate> date = new SimpleObjectProperty<>();

    public final LocalDate getDate() {
        return this.date.get();
    }

    public final void setDate(LocalDate value) {
        this.date.set(value);
    }

    public final ObjectProperty<LocalDate> dateProperty() {
        return this.date;
    }
}

如果不存在这样的方法,PropertyValueFactory 将使用 getter 来检索值,即 getDate(),但这种情况下模型中的更新将不可见UI 直到它更新 Cell,因为 PropertyValueFactory 不知道"在何处添加侦听器.

If no such method exists, PropertyValueFactory will use a getter to retrieve the value, i.e. getDate(), but this case updates in the model will not be visible in the UI until it updates the Cell, since the PropertyValueFactory "does not know" where to add a listener.

  • 只能在public类中找到public方法
  • PropertyValueFactory 使用反射
  • 不是类型安全的.在 new PropertyValueFactory(date") 中,编译器不检查是否存在合适的方法,该方法是否甚至返回合适的类,或者例如属性 getter 返回一个 String 而不是 ReadOnlyProperty,这会导致 ClassCastExceptions.
  • 没有编译时检查.在 lambda 表达式中,编译器可以检查该方法是否存在并返回适当的类型;使用 PropertyValueFactory 这没有完成.
  • 不适用于记录.
  • Can only find public methods in a public class
  • PropertyValueFactory uses reflection
  • Not typesafe. In new PropertyValueFactory<Appointment, LocalDate>("date") the compiler does not check, if there is a appropriate method, if that method even returns a suitable class or if e.g. the property getter returns a String instead of a ReadOnlyProperty<LocalDate> which can lead to ClassCastExceptions.
  • No compile time checking. In the lambda expression the compiler can do some checking if the method exists and returns a appropriate type; with PropertyValueFactory this is not done.
  • Does not work with records.

如果您确定正确地在项目类中实现了适当的方法,那么使用PropertyValueFactory 没有任何问题,但如上所述它有其缺点.此外,实现 Callback 更加灵活.你可以例如做一些额外的修改:

If you are sure to implement the appropriate methods in the item class correctly, there is nothing wrong with using PropertyValueFactory, but as mentioned above it has it's disadvantages. Moreover implementing the Callback is much more flexible. You could e.g. do some additional modifications:

TableColumn<Appointment, String> column = ...

column.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Appointment, String>, ObservableValue<String>> {
    @Override
    public ObservableValue<String> call(TableColumn.CellDataFeatures<Appointment, String> cd) {
        Appointment a  = cd.getValue();

        return Bindings.createStringBinding(() -> "the year: " + a.getDate().getYear(), a.dateProperty());
    }

});

这篇关于Java: setCellValuefactory;Lambda 与 PropertyValueFactory;优点缺点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆