Featured Post

Applying Email Validation to a JavaFX TextField Using Binding

This example uses the same controller as in a previous post but adds a use case to support email validation.  A Commons Validator object is ...

Tuesday, September 13, 2016

Disabling a Save Button with JavaFX Confirmation Binding Controls

This post demonstrates a one-line JavaFX Binding expression that disables a Save Button until a confirmed input is entered into a pair of TextFields.

btnSave.disableProperty().bind(
    txtEmail.textProperty().isEqualTo(txtConfirmEmail.textProperty()).not()
    .or(
        txtEmail.textProperty().isEmpty()
    )
);



This video shows the enabling and disabling of the Save Button through entering and removing text from the Email and Confirm Email Text Fields.



In SceneBuilder, I added a pair of TextFields, txtEmail and txtConfirmEmail, to a GridPane.

Scene Builder Showing Confirm Screen
This JavaFX Controller binds the disable (not disabled) property of the Save button to a compound expression.  The or() method is used to disable the Save button under two conditions


  1. The contents of the TextFields are not equal.  Notice the not() method at the end of the isEqualTo() method.
  2. The txtEmail TextField is empty.  This is a case enforcing the required field.

The binding expression is put in the @FXML initialize() method.

public class ConfirmController {

    private Logger logger = Logger.getLogger("ConfirmController");

    @FXML
    private TextField txtEmail, txtConfirmEmail;

    @FXML
    private GridPane gridPane;

    @FXML
    private Button btnSave;

    @FXML
    public void initialize() {

        btnSave.disableProperty().bind(
                txtEmail.textProperty().isEqualTo(txtConfirmEmail.textProperty()).not()
                .or(
                       txtEmail.textProperty().isEmpty()
                )
        );
    }

    @FXML
    public void save(ActionEvent evt) {
        logger.info("confirmed " + txtEmail.getText());
        hide(evt);
    }

    @FXML
    public void cancel(ActionEvent evt) {
        hide(evt);
    }

    private void hide(ActionEvent evt) {
        ((Node)evt.getSource()).getScene().getWindow().hide();
    }
}

While you can satisfy this requirement using property listeners as you might do with a Swing program, this JavaFX Binding syntax will be more consistent in your app.  That's because there's more variation in listeners: lambda vs anonymous inner class, parameter names, variations on comparisons and empty checks.  Once you get up the learning curve of JavaFX Binding, this type of expression becomes very

No comments:

Post a Comment