Java: setCellValuefactory; Lambda 与 PropertyValueFactory;优点缺点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38049734/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantages
提问by Wolfone
today i encountered another thing i don't really understand while trying to learn more about JavaFX and Java in general.
今天,我在尝试更多地了解 JavaFX 和 Java 时遇到了另一件我不太了解的事情。
Reference is the following tutorial (im trying to apply the principle to an organizer):
参考是以下教程(我试图将原理应用于组织者):
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):
我的主窗口包含一个 tableview,它显示了一些约会数据。所以我得到了一些这种风格的线条(与教程中相同):
aColumn.setCellValueFactory(cellData ->cellData.getValue().getAColumnsProperty());
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 PropertyValueFactoryit says: "A convenience implementation of the Callback-Interface,[...]"
可以通过附加的 EditDialog 操作数据。这工作得很好。如果我编辑内容,更改会立即显示,但我做了一些额外的研究以更好地理解 Lambda(不太成功)。现在...在在线 Java 文档Java Doc PropertyValueFactory 中,它说:“回调接口的便捷实现,[...]”
So i refactored my code into this style:
所以我将我的代码重构为这种风格:
aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));
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.
我发现它比 Lambda 更具可读性。但我注意到,当我进行更改时,我需要在显示更改之前对 TableView 进行一些排序。
Is it possible to achieve an immediate display of change in the second approach?
是否有可能在第二种方法中实现立即显示变化?
If yes: are there major disavantages which would discourage such a modification? I.e. would the Lambda be the best practice in this situation?
如果是:是否存在阻碍这种修改的主要缺点?即在这种情况下,Lambda 是最佳实践吗?
I appreciate any help.
我很感激任何帮助。
回答by fabian
PropertyValueFactory
expects correctly named property getters. getAColumnsProperty
is probably not one.
PropertyValueFactory
期望正确命名的属性 getter。getAColumnsProperty
可能不是一个。
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
.
在的情况下new PropertyValueFactory<Appointment, LocalDate>("date")
的Appointment
类需要包含一个dateProperty()
方法; 返回的值需要扩展ReadOnlyProperty
才能使其工作,并且任何编辑只会导致模型自动更新,如果返回的对象也是WritableValue
.
Example Appointment
class that should work with PropertyValueFactory<>("date")
:
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;
}
}
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.
如果不存在这样的方法,PropertyValueFactory
将使用 getter 来检索值,即getDate()
,但是这种情况下模型中的更新将在 UI 中不可见,直到它更新Cell
,因为PropertyValueFactory
“不知道”在哪里添加侦听器。
Disadvantages of PropertyValueFactory
的缺点 PropertyValueFactory
- Can only find
public
methods in apublic
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 aString
instead of aReadOnlyProperty<LocalDate>
which can lead toClassCastException
s. - 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.
- 只能
public
在public
类中查找方法 PropertyValueFactory
使用反射- 不是类型安全的。在
new PropertyValueFactory<Appointment, LocalDate>("date")
编译器中,不检查是否有合适的方法,如果该方法甚至返回合适的类,或者例如属性 getter 返回 aString
而不是 aReadOnlyProperty<LocalDate>
这可能导致ClassCastException
s。 - 没有编译时检查。在 lambda 表达式中,编译器可以检查该方法是否存在并返回适当的类型;有
PropertyValueFactory
没有这样做。
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:
如果您确定正确地在 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());
}
});