问题描述
今天我在尝试更多地了解JavaFX和Java时遇到了另一件我并不理解的事情。
today i encountered another thing i don't really understand while trying to learn more about JavaFX and Java in general.
参考是以下教程(我试图将原则应用于组织者):
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:
我的主窗口包含一个显示一些约会数据的tableview。
所以我得到了一些这种风格的线条(与教程相同):
My main window contains a tableview which shows some appointment-data.So i got some lines of this style(same as in the tutorial):
aColumn.setCellValueFactory(cellData ->cellData.getValue().getAColumnsProperty());
可以通过额外的EditDialog操作数据。
这很好用。如果我编辑的东西立即显示更改,但我做了一些额外的研究,以更好地了解Lambda(不太成功)。现在......在在线java文档中它说:
Callback-Interface的便捷实现,[...]
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 PropertyValueFactory it says:"A convenience implementation of the Callback-Interface,[...]"
所以我将我的代码重构为这种风格:
So i refactored my code into this style:
aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));
我发现它比Lambda更具可读性。
但我注意到,当我进行更改时,我需要在显示更改之前对TableView进行一些排序。
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.
是否可以立即显示第二种方法的变化?
Is it possible to achieve an immediate display of change in the second approach?
如果是:是否存在阻碍这种修改的主要障碍?即Lambda是这种情况下的最佳做法吗?
If yes: are there major disavantages which would discourage such a modification? I.e. would the Lambda be the best practice in this situation?
我感谢任何帮助。
推荐答案
PropertyValueFactory
需要正确命名的属性getter。 getAColumnsProperty
可能不是一个。
PropertyValueFactory
expects correctly named property getters. getAColumnsProperty
is probably not one.
如果新的PropertyValueFactory< Appointment,LocalDate> (date)
约会
类需要包含 dateProperty()
方法;返回值需要扩展 ReadOnlyProperty
才能使其工作,任何编辑只会导致模型自动更新,如果返回的对象也 WritableValue
。
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
.
示例约会
应该与一起使用的类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()
,但是此模型中的更新将不会在UI中显示直到它更新 Cell
,因为 PropertyValueFactory
不知道添加监听器的位置。
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.
- 可以只能在
公共
类中找到public
方法 -
PropertyValueFactory
使用反射 - 非类型安全。在
new PropertyValueFactory< Appointment,LocalDate>(date)
中,如果有合适的方法,编译器不检查该方法是否返回合适的类或者例如属性getter返回String
而不是ReadOnlyProperty< LocalDate>
,这可能导致ClassCastException
s。 - 无编译时检查。在lambda表达式中,编译器可以检查方法是否存在并返回适当的类型;
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.
如果你确定要实现正确的项类中的适当方法,使用 PropertyValueFactory
没有任何问题,但如上所述它有它的缺点。此外,实现 Callback
更加灵活。你可以,例如做一些额外的修改:
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:
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());
}
});
这篇关于Java:setCellValuefactory; Lambda与PropertyValueFactory;优点缺点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!