JavaFX: Binding Properties

By Doug Lowe

JavaFX property binding allows you to synchronize the value of two properties so that whenever one of the properties changes, the value of the other property is updated automatically. Two types of binding are supported:

  • Unidirectional binding: With unidirectional binding, the binding works in just one direction. For example, if you bind property A to property B, the value of property A changes when property B changes, but not the other way around.

  • Bidirectional binding: With bidirectional binding, the two property values are synchronized so that if either property changes, the other property is automatically changed as well.

Setting up either type of binding is surprisingly easy. Every property has a bind and a bindBiDirectional method. To set up a binding, simply call this method, specifying the property you want to bind to as the argument.

Here’s an example that creates a unidirectional binding on the text property of a label to the text property of a text field, so that the contents of the label always displays the contents of the text field:

lable1.textProperty().bind(text1.textProperty());

With this binding in place, the text displayed by label1 is automatically updated, character by character, when the user types data into the text field.

The following example shows how to create a bidirectional binding between two text fields, named text1 and text2:

text1.textProperty()
    .bindBidirectional(text2.textProperty());

With this binding in place, any text you type into either text field will be replicated automatically in the other.

To show how binding can be used in a complete program, this code listing shows a program with two text fields with a pair of labels bound to each. The first text field accepts the name of a character in a play, and the second text field accepts the name of an actor. The labels display the actor who will play the role, as shown in the figure.

A dialog box in a program allows you to choose what actor will play a role in a movie.

import javafx.application.*;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.geometry.*;
import javafx.scene.control.*;
public class RolePlayer extends Application
{
    public static void main(String[] args)
    {
        launch(args);
    }
    TextField txtCharacter;
    TextField txtActor;
    @Override public void start(Stage primaryStage)
    {
        // Create the Character label
        Label lblCharacter = new Label("Character's Name:");
        lblCharacter.setMinWidth(100);
        lblCharacter.setAlignment(Pos.BOTTOM_RIGHT);
        // Create the Character text field
        txtCharacter = new TextField();
        txtCharacter.setMinWidth(200);
        txtCharacter.setMaxWidth(200);
        txtCharacter.setPromptText("Enter the name of the character here.");
        // Create the Actor label
        Label lblActor = new Label("Actor's Name:");
        lblActor.setMinWidth(100);
        lblActor.setAlignment(Pos.BOTTOM_RIGHT);
        // Create the Actor text field
        txtActor = new TextField();
        txtActor.setMinWidth(200);
        txtActor.setMaxWidth(200);
        txtActor.setPromptText("Enter the name of the actor here.");
        // Create the Role labels
        Label lblRole1 = new Label("The role of ");
        Label lblRole2 = new Label();
        Label lblRole3 = new Label(" will be played by ");
        Label lblRole4 = new Label();
        // Create the Character pane
        HBox paneCharacter = new HBox(20, lblCharacter, txtCharacter);
        paneCharacter.setPadding(new Insets(10));
        // Create the Actor pane
        HBox paneActor = new HBox(20, lblActor, txtActor);
        paneActor.setPadding(new Insets(10));
        // Create the Role pane
        HBox paneRole = new HBox(lblRole1, lblRole2, lblRole3, lblRole4);
        paneRole.setPadding(new Insets(10));
        // Add the Character and Actor panes to a VBox
        VBox pane = new VBox(10, paneCharacter, paneActor, paneRole);
        // Create the bindings
        lblRole2.textProperty().bind(txtCharacter.textProperty());
        lblRole4.textProperty().bind(txtActor.textProperty());
        // Set the stage
        Scene scene = new Scene(pane);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Role Player");
        primaryStage.show();    }
}