Review of JavaFX properties

This document is an attempt to quickly review JavaFX properties.

The main hierarchy in JavaFX is large. It fully integrates properties, observability and binding.

Full Oracle architecture discussion. Discusses how and why of JavaFX properties. A related Oracle pdf.


Types

Observable

  • addListener(InvalidationListener)
  • removeListener(InvalidationListener)
  • handles invalidation (aim for few invalidation events for performance)

ObservableValue<T> extends Observable

  • addListener(ChangeListener<? super T>)
  • removeListener(ChangeListener<? super T>)
  • getValue()
  • a basic value that can change over time

Observable types

  • ObservableBooleanValue extends Observable
  • ObservableNumberValue extends Observable
  • ObservableIntegerValue extends ObservableNumberValue (and double/float/long)
  • ObservableObjectValue extends Observable (sub types for collection elements)
  • ObservableStringValue extends ObservableObjectValue

Observable Collections

  • ObservableArray<T> extends Observable
  • ObservableList<T> extends Observable
  • ObservableSet<T> extends Observable
  • ObservableMap<T> extends Observable

ReadOnlyProperty<T> extends ObservableValue<T>

  • getBean() - may return null if N/A
  • getName() - may return "" if N/A
  • base for all properties

Property<T> extends ReadOnlyProperty<T>, WritableValue<T>

  • bind(ObservableValue<? extends T>)
  • unbind()
  • isBound()
  • bindBidirectional(Property<T>)
  • unbindBidirectional(Property<T>)
  • get and set allows full binding capability

ReadOnlyJavaBeanProperty<T> extends ReadOnlyProperty<T>

  • fireValueChangedEvent()
  • dispose()
  • connects to JavaBeans style properties
  • see ReadOnlyJavaBeanBooleanProperty and friends for implementation (not using java.beans)

JavaBeanProperty<T> extends ReadOnlyJavaBeanProperty<T>, Property<T>

  • no additional methods

WritableValue<T>

  • getValue()
  • setValue(T value)
  • provides getter and setter independent of main property framework
  • subtypes for boolean/numbers/object

StyleableProperty<T> extends WritableValue<T>

  • applyStyle(StyleOrigin, T)
  • getStyleOrigin()
  • getCssMetaData()
  • allows CSS to interact with properties

NumberExpression

  • methods to do maths on observables
  • used in NumberBinding

Basic pattern (from tutorial):

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

Some typical code (from TextField). Note three public methods property/getter/setter. Note that the state is in the property object (type 3). Note use of ObjectProperty not Property as the return type. Note that the property is created on demand (for memory/performance/gc reasons).

public final ObjectProperty<Pos> alignmentProperty() {
    if (alignment == null) {
        alignment = new StyleableObjectProperty<Pos>(Pos.CENTER_LEFT) {
            ...
            @Override
            public String getName() {
                return "alignment";
            }
        };
    }
    return alignment;
}
private ObjectProperty<Pos> alignment;
public final void setAlignment(Pos value) { alignmentProperty().set(value); }
public final Pos getAlignment() { return alignment == null ? Pos.CENTER_LEFT : alignment.get(); }

Variation where property always present:

private ObjectProperty<EventHandler<ActionEvent>> onAction = new ObjectPropertyBase<EventHandler<ActionEvent>>() {
    ...
    @Override
    public String getName() {
        return "onAction";
    }
};
public final ObjectProperty<EventHandler<ActionEvent>> onActionProperty() { return onAction; }
public final EventHandler<ActionEvent> getOnAction() { return onActionProperty().get(); }
public final void setOnAction(EventHandler<ActionEvent> value) { onActionProperty().set(value); }

Another variant:

private StringProperty promptText = new SimpleStringProperty(this, "promptText", "") {
    ...
};
public final StringProperty promptTextProperty() { return promptText; }
public final String getPromptText() { return promptText.get(); }
public final void setPromptText(String value) { promptText.set(value); }

Blogs

  • One bean to bind all, 2014, suggests its OK to use JavaFX properties on server side in limited contexts.
  • JPA and JavaFX, 2013, describes using “property access” rather than “field access” in JPA to enable JavaFX property support.

Back to top

Version: 0.1-SNAPSHOT. Last Published: 2015-01-03.

Reflow Maven skin by Andrius Velykis.