1. Introduction

1.1. Overview

In this short tutorial, we’ll take a look at the JavaFX Button component and see how we can handle user interaction.

1.2. JavaFX API

In Java 8, 9, and 10 no additional setup is necessary to start working with the JavaFX library. The project will be removed from the JDK starting with JDK 11 and the following dependencies should be added to pom.xml:

<dependencies>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>${javafx.version}</version>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-fxml</artifactId>
        <version>${javafx.version}</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-maven-plugin</artifactId>
            <version>${javafx-maven-plugin.version}</version>
            <configuration>
                <mainClass>Main</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

2. Application Setup

First, let’s create a small application to be able to focus on the event handlers. Let’s start with creating a simple FXML layout that contains a button:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns:fx="http://javafx.com/fxml"
    xmlns="http://javafx.com/javafx"
    fx:controller="com.baeldung.button.eventhandler.ButtonEventHandlerController"
    prefHeight="200.0" prefWidth="300.0">
    <center>
        <Button fx:id="button" HBox.hgrow="ALWAYS"/>
    </center>

    <bottom>
        <Label fx:id="label" text="Test label"/>
    </bottom>
</BorderPane>

Let’s create the ButtonEventHandlerController class. This is responsible for connecting the UI elements and the application logic. We’ll set the label of the button in the initialize method:

public class ButtonEventHandlerController {

    private static final Logger logger = LoggerFactory.getLogger(ButtonEventHandlerController.class);

    @FXML
    private Button button;

    @FXML
    private Label label;

    @FXML
    private void initialize() {
        button.setText("Click me");
    }
}

Let’s start the application. We should see a button in the center titled “Click me” and a test label at the bottom of the window:

Application preview

3. Click Event

Let’s start with handling simple click events and adding an event handler to the initialize method:

button.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        logger.info("OnAction {}", event);
    }
});

Let’s test this now. When we click on the button, there’s a new log message:

INFO c.b.b.e.ButtonEventHandlerController - OnAction javafx.event.ActionEvent[source=Button[id=searchButton, styleClass=button]'Click me']

Because the event handler interface has only one method, we can treat it as a functional interface and replace these lines with a single lambda expression to make our code easier to read:

searchButton.setOnAction(event -> logger.info("OnAction {}", event));

Let’s try to add another click event handler. We can simply copy this line and change the log message to be able to see the difference when we test the application:

button.setOnAction(event -> logger.info("OnAction {}", event));
button.setOnAction(event -> logger.info("OnAction2 {}", event));

Now, when we click on the button, we see the “OnAction 2” message only. This happens because the second setOnAction method call replaced the first event handler with the second one.

4. Different Events

We can handle other event types as well, such as mouse press/release, drag, and keyboard events.

Let’s add a hover effect for our button. We’ll display a shadow when the cursor starts hovering over the button and remove the effect when the cursor leaves it:

Effect shadow = new DropShadow();
searchButton.setOnMouseEntered(e -> searchButton.setEffect(shadow));
searchButton.setOnMouseExited(e -> searchButton.setEffect(null));

5. Reusing Event Handlers

In some cases, we might want to use the same event handler multiple times. Let’s create an event handler that will increase the font size of our button when we click the secondary mouse button:

EventHandler<MouseEvent> rightClickHandler = event -> {
    if (MouseButton.SECONDARY.equals(event.getButton())) {
        button.setFont(new Font(button.getFont().getSize() + 1));
    }
};

However, it has no functionality because we didn’t associate it with any events. Let’s use this event handler for the mouse press event of the button and the label:

button.setOnMousePressed(rightClickHandler);
label.setOnMousePressed(rightClickHandler);

Now, when we test the application and click with the secondary mouse button on the label or the button, we see that the font size increases.

6. Conclusion

We learned how to add event handlers to JavaFX buttons and execute different actions depending on the type of event.

As always, the code implementation is available over on GitHub.

Course – LS (cat=Java)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.