PropertyValueFactory 期望正确命名的属性获取器。 getAColumnsProperty 可能不是一个。
如果是new PropertyValueFactory<Appointment, LocalDate>("date"),Appointment 类需要包含dateProperty() 方法;返回的值需要扩展 ReadOnlyProperty 才能工作,如果返回的对象也是 WritableValue,任何编辑只会导致模型自动更新。
应与PropertyValueFactory<>("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<Appointment, LocalDate>("date") 中,编译器不检查是否存在适当的方法,该方法是否甚至返回合适的类,或者是否例如属性 getter 返回 String 而不是 ReadOnlyProperty<LocalDate>,这可能导致 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());
}
});