DEV Community

Cover image for Listeners for Observable Objects
Paul Ngugi
Paul Ngugi

Posted on

Listeners for Observable Objects

You can add a listener to process a value change in an observable object.
An instance of Observable is known as an observable object, which contains the addListener(InvalidationListener listener) method for adding a listener. The listener class must implement the InvalidationListener interface to override the invalidated(Observable o) method for handling the value change. Once the value is changed in the Observable object, the listener is notified by invoking its invalidated(Observable o) method. Every binding property is an instance of Observable. The program below gives an example of observing and handling a change in a DoubleProperty object balance.

Image description

When line 16 is executed, it causes a change in balance, which notifies the listener by invoking the listener’s invalidated method.

Note that the anonymous inner class in lines 10–14 can be simplified using a lambda expression as follows:

balance.addListener(ov -> {
System.out.println("The new value is " +
balance.doubleValue());
});

Recall that in this post DisplayClock.java, the clock pane size is not changed when you resize the window. The problem can be fixed by adding a listener to change the clock pane size and register the listener to the window’s width and height properties, as shown in the program below.

package application;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;

public class DisplayResizableClock extends Application {
    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {
        // Create a clock and a label
        ClockPane clock = new ClockPane();
        String timeString = clock.getHour() + ":" + clock.getMinute() + ":" + clock.getSecond();
        Label lblCurrentTime = new Label(timeString);

        // Place clock and label in border pane
        BorderPane pane = new BorderPane();
        pane.setCenter(clock);
        pane.setBottom(lblCurrentTime);
        BorderPane.setAlignment(lblCurrentTime, Pos.TOP_CENTER);

        // Create a scene and place it in the stage
        Scene scene = new Scene(pane, 250, 250);
        primaryStage.setTitle("DisplayClock"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage

        pane.widthProperty().addListener(ov -> clock.setW(pane.getWidth()));

        pane.heightProperty().addListener(ov -> clock.setH(pane.getHeight()));
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

Enter fullscreen mode Exit fullscreen mode

The program is identical to DisplayClock.java except that you added the code in lines 29–31 to register listeners for resizing the clock pane upon a change of the width or height of the scene. The code ensures that the clock pane size is synchronized with the scene size.

Top comments (0)