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):
JavaFX 8 Tutorial
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? I.e. 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, 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
public
methods in a public
classPropertyValueFactory
uses reflectionnew 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 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 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());
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With