Java:setCellValuefactory; Lambda与PropertyValueFactory; 优点缺点
今天我在尝试更多地了解JavaFX和Java时遇到了另一件我并不理解的事情。
参考是以下教程(我试图将原理应用于组织者):
JavaFX 8教程
我将简要介绍一下我有问题的特定部分:
我的主窗口包含一个tableview,显示一些约会数据。 所以我得到了一些这种风格的线条(与教程中相同):
aColumn.setCellValueFactory(cellData ->cellData.getValue().getAColumnsProperty());
可以通过额外的EditDialog操作数据。 这很好用。 如果我编辑的东西立即显示更改,但我做了一些额外的研究,以更好地了解Lambda(不太成功)。 现在……在线java文档Java Doc PropertyValueFactory中说:“Callback-Interface的一个便利实现,[…]”
所以我将我的代码重构为这种风格:
aColumn.setCellValueFactory(new PropertyValueFactory("date"));
我发现它比Lambda更具可读性。 但我注意到,当我进行更改时,我需要在显示更改之前对TableView进行一些排序。
是否有可能在第二种方法中立即显示变化?
如果是:是否存在阻碍这种修改的重大缺陷? 也就是Lambda是这种情况下的最佳实践?
我感谢任何帮助。
PropertyValueFactory
需要正确命名的属性getter。 getAColumnsProperty
可能不是一个。
在new PropertyValueFactory
的情况下, Appointment
类需要包含dateProperty()
方法; 返回的值需要扩展ReadOnlyProperty
才能工作,任何编辑只会导致模型自动更新,如果返回的对象也是WritableValue
。
应该使用PropertyValueFactory<>("date")
示例Appointment
类:
public class Appointment { private final ObjectProperty date = new SimpleObjectProperty<>(); public final LocalDate getDate() { return this.date.get(); } public final void setDate(LocalDate value) { this.date.set(value); } public final ObjectProperty dateProperty() { return this.date; } }
如果不存在这样的方法, PropertyValueFactory
将使用getter来检索值,即getDate()
,但是在更新Cell
之前,模型中的更新将不会在UI中可见,因为PropertyValueFactory
“不知道”在哪里添加一个监听器。
PropertyValueFactory
缺点
- 只能在
public
类中查找public
方法 -
PropertyValueFactory
使用reflection - 不是类型安全的。 在
new PropertyValueFactory
,编译器不检查,如果有适当的方法,该方法是否返回合适的类,或者例如属性getter返回("date") String
而不是ReadOnlyProperty
这可能会导致ClassCastException
。 - 没有编译时检查。 在lambda表达式中,编译器可以检查方法是否存在并返回适当的类型; 使用
PropertyValueFactory
这是不行的。
如果您确定正确地在项类中实现了适当的方法,那么使用PropertyValueFactory
没有任何问题,但如上所述,它有它的缺点。 此外,实现Callback
更灵活。 你可以做一些额外的修改:
TableColumn column = ... column.setCellValueFactory(new Callback, ObservableValue> { @Override public ObservableValue call(TableColumn.CellDataFeatures cd) { Appointment a = cd.getValue(); return Bindings.createStringBinding(() -> "the year: " + a.getDate().getYear(), a.dateProperty()); } });