简体   繁体   中英

Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantages

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? 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.

Disadvantages of PropertyValueFactory

  • Can only find public methods in a public 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 eg the property getter returns a String instead of a ReadOnlyProperty<LocalDate> which can lead to ClassCastException 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.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM