Java:setCellValuefactory; Lambda与PropertyValueFactory;优点缺点

时间:2016-06-27 08:59:37

标签: java javafx

今天我在尝试更多地了解JavaFX和Java时遇到了另一件我真正理解的事情。

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

JavaFX 8 Tutorial

我将简要介绍一下我提出问题的具体部分:

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

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

可以通过额外的EditDialog操作数据。 这很好用。如果我编辑的东西,立即显示更改,但我做了一些额外的研究,以更好地了解Lambda(不太成功)。现在......在在线java文档Java Doc PropertyValueFactory中它说: " Callback-Interface的便捷实现,[...]"

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

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

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

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

如果是:是否存在阻碍此类修改的重大缺陷?即在这种情况下Lambda会是最好的做法吗?

我感谢任何帮助。

1 个答案:

答案 0 :(得分:10)

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

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

应该使用Appointment的示例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(),但是在更新{{Cell之前,模型中的这种情况更新将不会在UI中可见。 1}},因为PropertyValueFactory&#34;不知道&#34;在哪里添加一个监听器。

PropertyValueFactory

的缺点
  • 只能在public
  • 中找到public个方法
  • PropertyValueFactory使用反射
  • 不是类型安全的。在new PropertyValueFactory<Appointment, LocalDate>("date")中,如果存在适当的方法,则编译器不检查该方法是否返回合适的类或者例如属性getter返回String而不是ReadOnlyProperty<LocalDate>,这可能会导致ClassCastException s。
  • 没有编译时检查。在lambda表达式中,编译器可以检查方法是否存在并返回适当的类型;使用PropertyValueFactory时尚未完成。

如果您确定正确地在项目类中实现了适当的方法,那么使用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());
    }

});