【问题标题】:Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantagesJava:setCellValuefactory; Lambda 与 PropertyValueFactory;优点缺点
【发布时间】:2016-10-29 05:14:11
【问题描述】:

今天我在尝试了解有关 JavaFX 和 Java 的更多信息时遇到了另一件我不太了解的事情。

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

JavaFX 8 Tutorial

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

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

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

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

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

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

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

第二种方法是否可以立即显示变化?

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

感谢您的帮助。

【问题讨论】:

    标签: java javafx


    【解决方案1】:

    PropertyValueFactory 期望正确命名的属性获取器。 getAColumnsProperty 可能不是一个。

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

    应与PropertyValueFactory&lt;&gt;("date") 一起使用的示例Appointment 类:

    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“不知道”在哪里添加监听器。

    PropertyValueFactory的缺点

    • 只能在public 类中找到public 方法
    • PropertyValueFactory 使用反射
    • 不是类型安全的。在new PropertyValueFactory&lt;Appointment, LocalDate&gt;("date") 中,编译器不检查是否存在适当的方法,该方法是否甚至返回合适的类,或者是否例如属性 getter 返回 String 而不是 ReadOnlyProperty&lt;LocalDate&gt;,这可能导致 ClassCastExceptions。
    • 没有编译时检查。在 lambda 表达式中,编译器可以检查方法是否存在并返回适当的类型; PropertyValueFactory 这还没有完成。
    • 不适用于records

    如果你确定在item类中正确的实现了相应的方法,使用PropertyValueFactory并没有什么问题,但是如上所述它有它的缺点。此外,实现Callback 更加灵活。你可以例如做一些额外的修改:

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

    【讨论】:

    • 哇,感谢您花时间在这个详尽的答案上!请原谅我迟到的接受。我需要再次检查我的 getter/setter 以全面评估我的错误。也非常感谢您对缺点的意见!
    • 在这种情况下使用反射是否会对性能造成巨大影响?它会在哪里看到最多?
    • 无法处理记录是一个严重的问题。我希望它在待解决的问题清单上。
    猜你喜欢
    • 2017-07-17
    • 1970-01-01
    • 2023-04-04
    • 2011-11-03
    • 2015-08-22
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    相关资源
    最近更新 更多