Welcome!

Machine Learning Authors: Zakia Bouachraoui, Yeshim Deniz, Elizabeth White, Pat Romanski, Liz McMillan

Related Topics: Java IoT, Industrial IoT, Linux Containers, Open Source Cloud, Machine Learning , Agile Computing

Java IoT: Blog Feed Post

JavaFX Event Handling and Property Binding

In JavaFX an event object is represented by the instance of the class javafx.event.Event

The event handler for the button Sign In will be implemented using an anonymous inner class. The event handler for the Cancel button will be implemented using a lambda expression. I’ll implement the click handler for the hyperlink Forgot password using a method reference. The code of the class GridPaneSampleEvents is shown next (see the section marked as event handlers).

public class GridPaneSampleEvents extends Application {

    public void start(Stage primaryStage) {
        
        Label userIdLbl = new Label("User ID:");
        TextField userIdTxt = new TextField();
        Label userPwdLbl = new Label("Password:");
        PasswordField userPwdTxt = new PasswordField();
        Button signInBtn = new Button ("Sign In");
        Button cancelBtn = new Button ("Cancel");
        Hyperlink forgotPwdLink = new Hyperlink("Forgot password");

        GridPane root = new GridPane();
        root.setVgap(20);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);
        
        // Using static methods for setting node constraints 
        GridPane.setConstraints(userIdLbl, 0, 0);
        GridPane.setConstraints(userIdTxt, 1, 0);
        GridPane.setConstraints(userPwdLbl, 0, 1);
        GridPane.setConstraints(userPwdTxt, 1, 1);
        GridPane.setConstraints(signInBtn, 0, 2);
        //Cancel button: span 1, right aligned
        GridPane.setConstraints(cancelBtn, 1,2, 1, 1, HPos.RIGHT,
                                                      VPos.CENTER);
        GridPane.setConstraints(forgotPwdLink, 0, 3,2,1);

        root.getChildren().addAll(userIdLbl, userIdTxt, userPwdLbl, 
                     userPwdTxt,signInBtn, cancelBtn, forgotPwdLink);
            
        // event handlers
        //1. Anonymous class 
        signInBtn.setOnAction(new EventHandler(){
            public void handle(ActionEvent evt){
              System.out.println(
                      "Anonymous class handler. Sign in clicked.");   
            }
        });
        
        // lambda expression
        cancelBtn.setOnAction(evt -> 
            System.out.println("Lambda handler. Cancel clicked.")
        );
        
        // method reference
        forgotPwdLink.setOnAction(this::forgotPwdHandler);
        
        // Show the window
        Scene scene = new Scene(root,250,200);
        primaryStage.setScene(scene);
        primaryStage.show();

    }
    
    private void forgotPwdHandler(ActionEvent evt){
        System.out.println(
              "Method reference handler. Forgot password clicked");
    }

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

If you run this program, and click on Sign In, Cancel, and Forgot password, the console output will show the following:

Anonymous class handler. Sign in clicked.
Lambda handler. Cancel clicked.
Method reference handler. Forgot password clicked

While each of the event handlers works the same, I prefer the lambda expression version as it’s concise and is easy to read. Each of the JavaFX GUI controls has a set of setOnXXX() methods (e.g. setOnAction(), setOnMouseMoved() et al) that should be called for the events you’re interested in handling.

Properties and Binding
While Java developers casually use the words properties referring to class attributes, JavaFX properties are more than just class attributes. JavaFX defines an interface javafx.beans.property.Property, which has a very useful functionality allowing to bind the GUI components (the view) with properties of the Java classes (the model) and automate notifications of the GUI components when the value in the model change or visa versa.

Imagine that you’re developing a financial application that receives notification from the server about the stock price changes. When a Java object receives the new price, you need to modify the content of the corresponding GUI component. With JavaFX you can simply bind a property price of a Java class to the property of, say Label component. No more coding required. As soon as the price value changes, the Label will be automatically updated. JavaFX properties greatly simplify the process of synchronization of the data and the GUI.

Existing implementations of the Property interface serve as wrappers to Java attributes adding the change notification functionality. The interface Property declares the following methods: bind(), unbind(), bindBidirectional() , unbindBidirctional(), and isBound(). Can you bind any value to a JavaFX property? No – the value has to be of an ObservableValue type.

JavaFx property classes are located in the package javafx.beans.property. For each property type there are two classes: read-only and read-write ones. For example, if you need a String property, use either SimpleStringProperty or ReadOnlyStringWrapper. Both of these implement StringProperty interface. Similarly named classes exist for other data types and some collections too.

Let’s modify the GridPaneSampleEvents class. I will place an additional Label components at the bottom of the Sign In window. It’ll display the messages about the events as the user clicks on the buttons and the hyperlink. Initially this label will not have any text:

Label messageLbl = new Label();

JavaFX properties are observables. Hence we can add a listener (observer) to the property to be notified when the property value changes. But it’s much easier to simply use property in a binding expressions. I’ll bind this label to the string property, and as soon as the value of this property changes, the label component messageLbl will display this value.

private StringProperty message = new SimpleStringProperty();
messageLbl.textProperty().bind(message);

The class GridePaneSampleEvents was just printing messages on the system console when the user clicked on the buttons or the hyperlink. The new class GridPaneSampleBinding will modify our property message instead, for example:

cancelBtn.setOnAction(evt -> message.set(“Cancel clicked.”));

The click on the cancelBtn changes the value of the the message property, which was bound to the label’s text – the GUI will change automatically! This is how our Sign In window will look like after pressing the Cancel button.

f1808

The complete code of the GridPaneSampleBinding class is shown next.

public class GridPaneSampleBinding extends Application {

    //Declaring a JavaFX property
    private StringProperty message = new SimpleStringProperty();
    
    public void start(Stage primaryStage) {
        
        Label userIdLbl = new Label("User ID:");
        TextField userIdTxt = new TextField();
        Label userPwdLbl = new Label("Password:");
        PasswordField userPwdTxt = new PasswordField();
        Button signInBtn = new Button ("Sign In");
        Button cancelBtn = new Button ("Cancel");
        Hyperlink forgotPwdLink = new Hyperlink("Forgot password");
        
        // A label to display messages using binding
        Label messageLbl = new Label();
        // binding the StringProperty to a GUI component
        messageLbl.textProperty().bind(message);
        
        GridPane root = new GridPane();
        root.setVgap(20);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);
        
        // Using static methods for setting node constraints 
        GridPane.setConstraints(userIdLbl, 0, 0);
        GridPane.setConstraints(userIdTxt, 1, 0);
        GridPane.setConstraints(userPwdLbl, 0, 1);
        GridPane.setConstraints(userPwdTxt, 1, 1);
        GridPane.setConstraints(signInBtn, 0, 2);
        
        //Cancel button: span 1, right aligned
        GridPane.setConstraints(cancelBtn, 1,2, 1, 1, 
                                      HPos.RIGHT, VPos.CENTER);
        GridPane.setConstraints(forgotPwdLink, 0, 3,2,1);
        
        // Message label: span 2
        GridPane.setConstraints(messageLbl, 0,4,2,1);

        root.getChildren().addAll(userIdLbl, userIdTxt, userPwdLbl,
          userPwdTxt,signInBtn, cancelBtn, forgotPwdLink, messageLbl);
        
        // event handlers
        //1. Anonymous class 
        signInBtn.setOnAction(new EventHandler(){
            public void handle(ActionEvent evt){
                  message.set("Sign in clicked.");   
            }
        });
        
        // lambda expression
        cancelBtn.setOnAction(evt -> 
           message.set("Cancel clicked.")
        );
        
        // method reference
        forgotPwdLink.setOnAction(this::forgotPwdHandler);
        
        // Show the window
        Scene scene = new Scene(root,250,220);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    
    private void forgotPwdHandler(ActionEvent evt){
        message.set("Forgot password clicked");
    }

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

The binding can be bidirectional. If the value of the GUI component changes it can change the value of the underlying model (remember MVC?), and if the value of the model changes the GUI is updated too. If you want to stop binding at any time, use the method unbind().

That’s all folks for now.

Read the original blog entry...

More Stories By Yakov Fain

Yakov Fain is a Java Champion and a co-founder of the IT consultancy Farata Systems and the product company SuranceBay. He wrote a thousand blogs (http://yakovfain.com) and several books about software development. Yakov authored and co-authored such books as "Angular 2 Development with TypeScript", "Java 24-Hour Trainer", and "Enterprise Web Development". His Twitter tag is @yfain

CloudEXPO Stories
Cloud-enabled transformation has evolved from cost saving measure to business innovation strategy -- one that combines the cloud with cognitive capabilities to drive market disruption. Learn how you can achieve the insight and agility you need to gain a competitive advantage. Industry-acclaimed CTO and cloud expert, Shankar Kalyana presents. Only the most exceptional IBMers are appointed with the rare distinction of IBM Fellow, the highest technical honor in the company. Shankar has also received the prestigious Outstanding Technical Achievement Award three times - an accomplishment befitting only the most innovative thinkers. Shankar Kalyana is among the most respected strategists in the global technology industry. As CTO, with over 32 years of IT experience, Mr. Kalyana has architected, designed, developed, and implemented custom and packaged software solutions across a vast spectrum o...
When building large, cloud-based applications that operate at a high scale, it’s important to maintain a high availability and resilience to failures. In order to do that, you must be tolerant of failures, even in light of failures in other areas of your application. “Fly two mistakes high” is an old adage in the radio control airplane hobby. It means, fly high enough so that if you make a mistake, you can continue flying with room to still make mistakes. In his session at 18th Cloud Expo, Lee Atchison, Principal Cloud Architect and Advocate at New Relic, will discuss how this same philosophy can be applied to highly scaled applications, and can dramatically increase your resilience to failure.
In his general session at 19th Cloud Expo, Manish Dixit, VP of Product and Engineering at Dice, discussed how Dice leverages data insights and tools to help both tech professionals and recruiters better understand how skills relate to each other and which skills are in high demand using interactive visualizations and salary indicator tools to maximize earning potential. Manish Dixit is VP of Product and Engineering at Dice. As the leader of the Product, Engineering and Data Sciences team at Dice, he takes a metrics-driven approach to management. His experience in building and managing high performance teams was built throughout his experience at Oracle, Sun Microsystems and SocialEkwity.
Despite being the market leader, we recognized the need to transform and reinvent our business at Dynatrace, before someone else disrupted the market. Over the course of three years, we changed everything - our technology, our culture and our brand image. In this session we'll discuss how we navigated through our own innovator's dilemma, and share takeaways from our experience that you can apply to your own organization.
DXWorldEXPO LLC announced today that Nutanix has been named "Platinum Sponsor" of CloudEXPO | DevOpsSUMMIT | DXWorldEXPO New York, which will take place November 12-13, 2018 in New York City. Nutanix makes infrastructure invisible, elevating IT to focus on the applications and services that power their business. The Nutanix Enterprise Cloud Platform blends web-scale engineering and consumer-grade design to natively converge server, storage, virtualization and networking into a resilient, software-defined solution with rich machine intelligence.