Home JavaFX JavaFX Observables and Bindings

JavaFX Observables and Bindings

JavaFX Observable and Bindings in action


JavaFX Observable is an entity that wraps content and allows to observe the content for invalidations. In simple terms, Observable allows to observe data in your application. In our everyday programming, we come up with cases where we have to constantly check whether the variable value has changed. With JavaFX observable, we can bind or attach listeners to data so that all the changes will be tracked.

Basic Addition

Let’s consider a case of adding two variables as follows.

private void sumNonObservable() {
   int a = 10;
   int b = 10;
   int sum = a + b;
   System.out.println(sum); //20
   //Change value of a now
   a = 20;
   //Sum is still 20
   System.out.println(sum); //20

This code shows a simple addition. Two variables a=10 and b=10 are added and assigned to sum. Then later, a is changed to 20. The sum won’t change.

Observable Addition

What if you wanted the sum to track its components. Let’s say when a was changed to 20, you needed the sum to automatically become 30 without doing another addition?. Well, JavaFX has the right solution.

Let’s write the above addition in JavaFX observable way.

private void sumObservable() {
   //Create two simple observable integers.
   SimpleIntegerProperty a = new SimpleIntegerProperty(10);
   SimpleIntegerProperty b = new SimpleIntegerProperty(10);
   //Add them with built-in add() function
   NumberBinding sum = a.add(b);

   //Answer = 20

   //Answer = 30

SimpleIntegerProperty is a built-in observable class that stores integer value with Observable support. Then a.add(b) will return a NumberBinding which keeps the sum of a and b. The advantage is, the sum is now listening on a and b and whatever change is made to a or b or both, it will be immediately reflected to the sum.

Similar to SimpleIntegerProperty, there are lots of default implementation for different types of variables. Some of them are

Adding Listener

We have seen how observables are useful in arithmetics. Well, that is just the tip of the iceberg.  Let’s see how we can make use of observable listeners.

Following code example prints a message whenever a variable’s value is changed.

 private static void observable() {
     SimpleIntegerProperty smartVar = new SimpleIntegerProperty(10);
     smartVar.addListener(new ChangeListener<Number>() {
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                System.out.println("Changed to " + newValue);

and the Output is:-

Changed to 5
Changed to 25

So, whenever the value is changed, the ChangeListener will be called.

You can add two types of listeners to an observable.

  1. ChangeListener
    A ChangeListener is notified whenever the value of an ObservableValue changes.
  2. InvalidationListener
    An InvalidationListener is notified whenever an Observable becomes invalid.
What is the difference between ChangeListener and InvalidationListener ?

An ObservableValue generates two types of events; change events and invalidation events. A change event indicates that the value has changed. An invalidation event is generated, if the current value is not valid anymore.This distinction becomes important, if the ObservableValue supports lazy evaluation. Because for a lazily evaluated value one does not know if an invalid value really has changed until it is recomputed. For this reason, generating change events requires eager evaluation while invalidation events can be generated for eager and lazy implementations.

ChangeListeners in contrast to InvalidationListeners require the new value to be passed to them. So, adding any ChangeListener results in get() being called and every invalidation call triggers a call of computeValue.

Now, If you still need more info on this topics, please have a look at the following tutorial video.

View Sample Project on GitHub