Lambda expressions can be used to greatly simplify coding for event handling. Lambda expressions can be viewed as an anonymous class with a concise syntax. For example, the following code in (a) can be greatly
simplified using a lambda expression in (b) in three lines.
The basic syntax for a lambda expression is either
(type1 param1, type2 param2, ...) -> expression
or
(type1 param1, type2 param2, ...) -> { statements; }
The data type for a parameter may be explicitly declared or implicitly inferred by the compiler. The parentheses can be omitted if there is only one parameter without an explicit data type. In the preceding example, the lambda expression is as follows
e -> {
// Code for processing event e
}
The compiler treats a lambda expression as if it is an object created from an anonymous inner class. In this case, the compiler understands that the object must be an instance of EventHandler. Since the EventHandler interface defines the handle method with a parameter of the ActionEvent type, the compiler automatically recognizes that e is a parameter of the ActionEvent type, and the statements are for the body of the handle method. The EventHandler interface contains just one method. The statements in the lambda expression are all for that method. If it contains multiple methods, the compiler will not be able to compile the lambda expression. So, for the compiler to understand lambda expressions, the interface must contain exactly one abstract method. Such an interface is known as a functional interface or a Single Abstract Method (SAM) interface.
AnonymousHandlerDemo.java in here can be simplified using lambda expressions as shown in the program below.
package application;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class LambdaHandlerDemo extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Hold four buttons in an HBox
HBox hBox = new HBox();
hBox.setSpacing(10);
hBox.setAlignment(Pos.CENTER);
Button btNew = new Button("New");
Button btOpen = new Button("Open");
Button btSave = new Button("Save");
Button btPrint = new Button("Print");
hBox.getChildren().addAll(btNew, btOpen, btSave, btPrint);
// Create and register the handler
btNew.setOnAction((ActionEvent e) -> {
System.out.println("Process New");
});
btOpen.setOnAction((e) -> {
System.out.println("Process Open");
});
btSave.setOnAction(e -> {
System.out.println("Process Save");
});
btPrint.setOnAction(e -> System.out.println("Process Print"));
// Create a scene and place it in the stage
Scene scene = new Scene(hBox, 300, 50);
primaryStage.setTitle("LambdaHandlerDemo"); // Set title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
public static void main(String[] args) {
Application.launch(args);
}
}
The program creates four handlers using lambda expressions (lines 24–36). Using lambda expressions, the code is shorter and cleaner. As seen in this example, lambda expressions may have many variations. Line 24 uses a declared type. Line 28 uses an inferred type since the type can be determined by the compiler. Line 32 omits the parentheses for a single inferred type. Line 36 omits the braces for a single statement in the body.
You can handle events by defining handler classes using inner classes, anonymous inner classes, or lambda expressions. We recommend that you use lambda expressions because it produces a shorter, clearer, and cleaner code.