At the heart of JavaFX is its scenegraph, a structure that includes (perhaps many) nodes. The JavaFX rendering engine displays these nodes and ultimately what you see depends on the properties of these nodes.
Properties are oh-so-important. They make a Circle red or a Rectangle 50 pixels wide. They determine the gradient for a background color or whether or not some text includes reflection or a drop shadow effect. You manipulate nodes with layout components—which are themselves nodes—by setting properties such as spacing or alignment. When your application includes animation, JavaFX updates a node’s properties over time—perhaps a node’s position, its rotation, or its opacity.
Before we look at JavaFX properties in detail, let’s review JavaBean properties first. JavaBean properties support encapsulation and a well-defined naming convention. You can create read-write properties, read-only properties, and immutable properties.
For example, here is a simple Person JavaBean with property fullname. (In fact, once we write the instance variable fullname, an IDE can generate the getter and setter.) Because we provide both getter and setter for this String property, the property is read-write. A Person object is built with a default constructor.
public class Person {
private String fullname = "";
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
@Override
public String toString() {
return getFullname();
}
}
We can use Person as follows.
Person p = new Person();
p.setFullname("Joe Smith");
System.out.println(p); // Joe Smith
Okay, so what are JavaFX properties and how are they different from regular JavaBean properties? JavaFX properties are JavaBean properties on steroids. That is, like JavaBean properties, they support encapsulation, a well-defined naming convention, as well as read-only, read-write, and immutable attributes. But there’s more. To see the difference, let’s create a Person POJO with a JavaFX property.
public class Person {
private StringProperty fullname =
new SimpleStringProperty(this, "fullname", "");
public final StringProperty fullnameProperty() {
return fullname;
}
public final String getFullname() {
return fullname.get();
}
public final void setFullname(String fullname) {
this.fullname.set(fullname);
}
@Override
public String toString() {
return getFullname();
}
}
You’ll notice right away that JavaFX properties include additional implementation code. First, the instance variable type is no longer String, but StringProperty, a type that wraps a String value and provides enhanced JavaFX property behaviors and structure, as you will soon see.
Second, conforming to the JavaFX property naming convention, you access a JavaFX property exactly the same as a JavaBean property. This means client code doesn’t change.
// unchanged from JavaBean property
Person p = new Person();
p.setFullname("Joe Smith");
System.out.println(p); // Joe Smith
Third, also confirming to the JavaFX property naming convention, you provide access to the Property itself with method propertynameProperty(). Here is method fullnameProperty() again.
public final StringProperty fullnameProperty() {
return fullname;
}
Fourth, JavaFX properties store contextual information. Method getBean() returns a reference to the enclosing object and getName() returns the property’s name. Here, we initialize these values in the property’s constructor, along with an empty String to use as its initial value.
private StringProperty fullname =
new SimpleStringProperty(this, "fullname", "");
And, we can use these methods as follows.
System.out.println(p.fullnameProperty().getBean());
// returns p and prints 'Joe Smith'
System.out.println(p.fullnameProperty().getName());
// prints 'fullname'
As alluded to earlier, JavaFX properties support additional behaviors. JavaFX properties are observable, which means you can attach listeners and define event handlers when a property value changes or becomes invalid. JavaFX properties also support unidirectional and bidirectional binding and unbinding. Binding lets properties participate in dependencies with other property values. Unbinding removes any dependencies. These are powerful constructs that let JavaFX developers write code that easily synchronizes itself based on changing values. These behaviors are important for responsive UIs as well as animation.
Because all JavaFX nodes contain many JavaFX properties, the JavaFX API does not implement properties in the straightforward way I have described. Instead, JavaFX nodes use lazy evaluation for properties. Thus, for any given property, if a node object only gets and sets values, the overhead for that property is equivalent to a regular JavaBean property.
Our Person POJO with its JavaFX property could be re-implemented as follows. Now the actual JavaFX property is created only when the StringProperty object is accessed with fullnameProperty().
public class Person {
private String _fullname = "";
private StringProperty fullname;
public final StringProperty fullnameProperty() {
if (fullname == null) {
fullname = new SimpleStringProperty(
this, "fullname", _fullname);
}
return fullname;
}
public final String getFullname() {
if (fullname == null) {
return _fullname;
}
else return fullname.get();
}
public final void setFullname(String fullname) {
if (this.fullname == null) {
_fullname = fullname;
}
else this.fullname.set(fullname);
}
@Override
public String toString() {
return getFullname();
}
}
Note that our user code only inflates fullname (that is, invokes the SimpleStringProperty constructor) after the first call to p.fullnameProperty(), as shown here.
Person p = new Person();
p.setFullname("Joe Smith");
System.out.println(p);
// JavaFX Property fullname inflated here:
System.out.println(p.fullnameProperty().getBean());
// prints 'Joe Smith'
System.out.println(p.fullnameProperty().getName());
// prints 'fullname'
What about JavaFX properties with types other than String? JavaFX supports the following property types.
BooleanProperty, DoubleProperty, FloatProperty,
IntegerProperty, LongProperty, ObjectProperty<T>,
StringProperty
These are abstract types and are instantiated with SimpleBooleanProperty, SimpleDoubleProperty, and so forth.
We’ll explore examples with JavaFX properties that use binding next.






![Event Loop Diagram [Click for larger image] Event Loop Diagram](http://www.asgteach.com/blog/wp-content/uploads/EventLoopDiagram1.gif)