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:
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());
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"));
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?
If yes: are there major disavantages which would discourage such a modification? Ie would the Lambda be the best practice in this situation?
I appreciate any help.
PropertyValueFactory
expects correctly named property getters. getAColumnsProperty
is probably not one.
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
.
Example Appointment
class that should work with 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, ie 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
public
methods in a public
class PropertyValueFactory
uses reflection 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 eg the property getter returns a String
instead of a ReadOnlyProperty<LocalDate>
which can lead to ClassCastException
s. PropertyValueFactory
this is not done. 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 eg 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());
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.