When to use the JavaFX and getter property property, instead of using the property directly

I am familiar with Java, but just starting to learn JavaFX and especially learn about JavaFX properties. I understand the basic design pattern, as shown in the following Oracle example:

package propertydemo; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; class Bill { // Define a variable to store the property private DoubleProperty amountDue = new SimpleDoubleProperty(); // Define a getter for the property value public final double getAmountDue(){return amountDue.get();} // Define a setter for the property value public final void setAmountDue(double value){amountDue.set(value);} // Define a getter for the property itself public DoubleProperty amountDueProperty() {return amountDue;} } 

I don't understand when / why would I use getter and setter methods instead of using Property directly?

I thought you might need some kind of custom code in getter and / or setter that can do preliminary or post manipulation / data validation, but if you create a custom getter and / or setter, get different results, then, depending whether you use a getter / setter or a property directly, which seems dangerous to me.

If getter / setter just calls the get and set Property methods, then why do they even have?

Any understanding of this would be appreciated.

+6
source share
1 answer

The JavaFX property template is intended to extend the old standard JavaBean template. So, in your example, according to the JavaBean convention, you have a (read-write) property of type double , called amount . This is determined by two methods:

 public double getAmount() ; public void setAmount(double amount); 

The JavaBean pattern allows limited “observability” through “related properties” in which beans supports registering PropertyChangeListener . The UI toolkit often needs to monitor properties and respond to changes. For example, it makes sense to have a Label text property. If the text property changes, the Label notification needs to be notified so that it can repaint itself. At first glance, using JavaBeans with related properties would be a way to do this. However, using this mechanism in the user interface toolkit creates performance problems because there is no way to get notifications that the value no longer works without calculating it immediately. This means, for example, that the layout will be recalculated with each individual change of property.

Obviously, the JavaFX team was trying to do is define a template that

  • matches the standard javabean pattern and
  • supported observable properties, in which invalidity can be monitored without recalculation of dependent values ​​each time the value changes ("lazily observable values")

Therefore, the JavaFX solution must create properties that support both ChangeListener s, which are notified when the value changes, and InvalidationListener s, which are notified when the value is no longer valid. This means that, for example, the layout engine can track whether it is valid at the moment, without causing a recalculation when it becomes invalid. The layout will be recounted only on the actual screen impulse (that is, when rendering the scene) and only if it is invalid.

(As a quick proof of concept, consider the following:

 DoubleProperty width = new SimpleDoubleProperty(3); DoubleProperty height = new SimpleDoubleProperty(4); ObservableDoubleValue area = Bindings.createDoubleBinding(() -> { double a = width.get() * height.get(); System.out.println("Computed area: "+a); return a ; }, width, height); System.out.println("Area is "+area.getValue()); width.set(2); height.set(3); System.out.println("Area is "+area.getValue()); 

Note that the intermediate value, when width is 2 and height is still 4, is never calculated.)

Thus, values ​​in JavaFX are represented by these observable Properties , which support both invalidation listeners and change listeners, which means that they are mostly “lazily observable.” Detecting the property itself using the property accessor method ( amountProperty() in your example) is enough to support this feature.

Semantically, however, the expression DoubleProperty means that the bean is of type double . To maintain compatibility with the old JavaBean convention, this bean should advertise this fact by exposing the appropriate get and set methods. Therefore, the JavaFX Property requires both the “accessor property” ( amountProperty() ) and the standard JavaBean methods ( getAmount() and setAmount(...) ). This means that beans, following the JavaFX pattern, can be used wherever a standard JavaBean pattern is used, such as in JPA .

Please note that for the template to work correctly it must always be true that amountProperty().get() == getAmount() and that amountProperty().set(x) has the same effect as setAmount(x) . This is guaranteed (even if the bean class is a subclass) by creating the get and set final methods, as in your example.

If you call methods yourself to retrieve or change the value of a property, it doesn't matter what you call, since they are guaranteed to have the same effect. Since the JavaFX Property template is an extension of the JavaBean template, there can be very little preference for calling get and set methods: in the sense of accessing a value, only the JavaBean function is required, and not the full functionality of the JavaFX properties, so this can make some sense only relying on this functionality. In practice, however, it does not matter what you use.

+11
source

All Articles