Property Binding
Tags: java, programming, learning, beginners
Published: 2024-06-20 15:54:53

You can bind a target object to a source object. A change in the source object will be automatically reflected in the target object. JavaFX introduces a new concept called _property binding_ that enables a _target object_ to be bound to a _source object_. If the value in the source object changes, the target object is also changed automatically. The target object is called a _binding object_ or a _binding property_ and the source object is called a _bindable object_ or _observable object_. As discussed in the preceding listing, the circle is not centered after the window is resized. In order to display the circle centered as the window resizes, the x- and y-coordinates of the circle center need to be reset to the center of the pane. This can be done by binding the **centerX** with pane’s **width/2** and **centerY** with pane’s **height/2**, as shown in the program below.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tp1upff2eehzgkqhznfj.png)

The **Circle** class has the **centerX** property for representing the x-coordinate of the circle center. This property like many properties in JavaFX classes can be used both as target and source in a property binding. A target listens to the changes in the source and automatically updates itself once a change is made in the source. A target binds with a source using the **bind** method as follows:

`target.bind(source);`

The **bind** method is defined in the **javafx.beans.property.Property** interface. A binding property is an instance of **javafx.beans.property.Property**. A source object is an instance of the **javafx.beans.value.ObservableValue** interface. An **ObservableValue** is an entity that wraps a value and allows to observe the value for changes.

JavaFX defines binding properties for primitive types and strings. For a **double**/**float**/**long**/**int**/**boolean** value, its binding property type is **DoubleProperty**/**FloatProperty**/**LongProperty**/**IntegerProperty**/**BooleanProperty**. For a string, its binding property type is **StringProperty**. These properties are also subtypes of **ObservableValue**. So they can also be used as source objects for binding properties.

By convention, each binding property (e.g., **centerX**) in a JavaFX class (e.g., **Circle**) has a getter (e.g., **getCenterX()**) and setter (e.g., **setCenterX(double)**) method for returning and setting the property’s value. It also has a getter method for returning the property itself. The naming convention for this method is the property name followed by the word **Property**. For example, the property getter method for **centerX** is **centerXProperty()**. We call the **getCenterX()** method as the _value getter method_, the **setCenterX(double)** method as the _value setter method_, and **centerXProperty()** as the _property getter method_. Note that **getCenterX()** returns a **double** value and **centerXProperty()** returns an object of the **DoubleProperty** type.

Figure below (a) shows the convention for defining a binding property in a class and Figure below (b) shows a concrete example in which **centerX** is a binding property of the type **DoubleProperty**.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0q9yvcqln5b6y5uqxqn2.png)

The program in Listing 14.5 is the same as in Listing 14.4 except that it binds **circle**’s **centerX** and **centerY** properties to half of **pane**’s width and height (lines 16–17). Note that **circle.centerXProperty()** returns **centerX** and **pane.widthProperty()** returns **width**. Both **centerX** and **width** are binding properties of the **DoubleProperty** type. The numeric binding property classes such as **DoubleProperty** and **IntegerProperty** contain the **add**, **subtract**, **multiply**, and **divide** methods for adding, subtracting, multiplying, and dividing a value in a binding property and returning a new observable property. So, **pane.widthProperty().divide(2)** returns a new observable property that represents half of the **pane**’s width. The statement

`circle.centerXProperty().bind(pane.widthProperty().divide(2));`

is same as

`centerX.bind(width.divide(2));`

Since **centerX** is bound to **width.divide(2)**, when **pane**’s width is changed, **centerX** automatically updates itself to match **pane**’s width / 2.

The program below gives another example that demonstrates bindings.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpqxoy4vref9290c3ux7.png)

The program creates an instance of **DoubleProperty** using
**SimpleDoubleProperty(1)** (line 7). Note that **DoubleProperty**, **FloatProperty**, **LongProperty**, **IntegerProperty**, and **BooleanProperty** are abstract classes. Their concrete subclasses **SimpleDoubleProperty**, **SimpleFloatProperty**, **SimpleLongProperty**, **SimpleIntegerProperty**, and **SimpleBooleanProperty** are used to create instances of these properties. These classes are very much like wrapper classes **Double**, **Float**, **Long**, **Integer**, and **Boolean** with additional features for binding to a source object.

The program binds **d1** with **d2** (line 9). Now the values in **d1** and **d2** are the same. After setting **d2** to **70.2** (line 11), **d1** also becomes **70.2** (line 12).

The binding demonstrated in this example is known as _unidirectional binding_. Occasionally, it is useful to synchronize two properties so that a change in one property is reflected in another object, and vice versa. This is called a _bidirectional binding_. If the target and source are both binding properties and observable properties, they can be bound bidirectionally using the **bindBidirectional** method.