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 ...

Wednesday, March 16, 2016

A Case Statement for JavaFX Binding

This is a JavaFX Binding statement that changes the text label of a Button depending on the program state.  Rather than use a ChangeListener and interrogate the value, this is a declarative approach that I find very readable.

btnConnect.textProperty().bind( 
new When(connectedToServer)
.then("Disconnect")
.otherwise("Connect") 
);


I have a program with a state variable "connectedToServer".  When the server is connected, this value is true.  When the server is connected this value is false.

This screenshot shows the UI when connectedToServer is false.  The connection Button displays "Connect".

Button Shows Connect When Not Connected To Server
After pressing Connect, the client connects to the server.  Sometime later (this is a Netty asynchronous call), the connectedToServer value will be set to true.  The Connect Button will be replaced with a Disconnect Button.  This is actually just a text label change.

Button Shows Disconnect When Not Connected To Server
In the class definition, I have the following fields.


@FXML
Button btnConnect;

private BooleanProperty connectedToServer = new SimpleBooleanProperty(false);


Coming from a Swing background, you might be tempted to add a ChangeListener to this property.


connectedToServer.addListener((obs, oldValue, newValue) -> {
if( newValue ) {
btnConnect.setText( "Disconnect" );
} else {
btnConnect.setText( "Connect" );
}
});


This works, and it's even using a Lambda, but I find this example more readable as my code is using a lot of fluent APIs.  Also, if you have a block of similar statements -- say a set of UI controls that respond to the connection change -- you can remove the line breaks and arrange the lines into a condensed block.


btnConnect.textProperty().bind( 
new When(connectedToServer)
.then("Disconnect")
.otherwise("Connect") 
);


This is a style preference.  If your code has a lot of fluent API calls, opt for the JavaFX Binding syntax.  ChangeListeners are fine and if you have to do more than just toggle a text value on a Button, may be required.  However, you may want to look at the ChangeListener and break this apart into multiple Bind statements.

2 comments:

  1. May I ask you for a link to the source code?

    ReplyDelete
    Replies
    1. Sure. It's on GitHub as part of an online checkers games called "FXCheckers". The game isn't finished yet and I don't have any documentation to give you. However, there will be a blog and video series that I created based on this.

      https://bitbucket.org/bekwam/fxcheckers-repos-1

      Look for the file FXCheckersController.java in fxcheckers-client/src/main/java/com/bekwam/fxc/client.

      Line 309 has the binding expression.

      Because this is a work-in-progress, I created a tag "BLOGPOST_201603023" in case that particular file doesn't survive a refactor.

      Good luck

      Delete