13.20 Events and Event Handlers
So far we have seen how to build a user interface with controls and layout managers in JavaFX. But when we played with the previous project, we noticed that some interactions had no effect at all: clicking a radio button or typing in a text field did not seem to be noticed by the application. A UI exists for the user to provide information to the program, and somehow the program needs to react. When you press the Run button in IntelliJ, IntelliJ runs the application; when you type in the editor, IntelliJ highlights the syntax and colors the code. So how does an application know which code to run when the user clicks a button? This is where events and event handling come in.
When the application wants to do something because the user interacted with a control, it actually runs a method known as an event handler. In this lesson we will write a small handler for a Button to see how it works. We start from a new JavaFX project and add a Button to our GridPane:
<Button text="message" onAction="#sayHello" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
The first time we run it, nothing happens on click, because we have not added a handler yet. Console applications, which we mostly used before this section, are procedural: they go from the entry point to the last line of code, with conditionals influencing the path. With a UI, we want to run a handler only when the user actually presses a button.
Writing the handler and reading a TextField
In HelloController we create a method sayHello() that prints Bonjour in the terminal. Back on the Button we use the onAction="#sayHello" attribute to bind it. Running the program again and clicking the button now prints "Bonjour" in the console.
To make the message dynamic, we add a TextField to the GridPane:
<TextField fx:id="nameField" GridPane.rowIndex="1" GridPane.columnIndex="0"/>
The important point is that the controller variable must have the exact same name as the fx:id. So in the controller we add:
@FXML
private TextField nameField;
@FXML
public void sayHello() {
System.out.println("Bonjour " + nameField.getText());
}
The @FXML annotation links the field to the FXML, and getText() gives us whatever the user typed. Running the program, typing "Tom" and clicking the button now prints "Bonjour Tom" in the console. That is all for this video — see you in the next one.
Summary
This lesson introduces event-driven programming in JavaFX, explaining how applications respond to user interactions through event handlers. The instructor demonstrates creating a simple button with an onAction event handler, then extends it to read text input from a text field and output "Hello [name]" to the console. The lesson also covers linking FXML UI elements to Java code using the @FXML annotation, showing the connection between UI controls and their corresponding Java instance variables.
Key points
- Event handlers are methods triggered when a user interacts with UI controls (buttons, text fields, etc.); without them, UI changes go unnoticed by the application
- Event-driven programming differs from procedural programming—instead of executing code sequentially from start to finish, event-driven applications wait for user interactions and execute specific code blocks in response
- In JavaFX, the onAction property on a button allows you to specify which method to call when the button is clicked
- UI elements defined in FXML files must be linked to Java instance variables with matching names, and the @FXML annotation tells JavaFX to inject the control reference automatically
- The getText() method on a TextField retrieves the text entered by the user, enabling you to capture and use user input in your event handlers
FAQ
What is the difference between procedural and event-driven programming?
Procedural programming executes code sequentially from the application's entry point to the end, with conditional statements controlling flow. Event-driven programming waits for user interactions with UI controls and executes specific handler methods in response, making the order of execution less predictable and dependent on user actions.
How do you link an FXML UI element to a Java variable?
First, assign an fx:id to the control in the FXML file (e.g., fx:id="nameField"). Then create a private instance variable in your controller with the same name (e.g., private TextField nameField) and annotate it with @FXML. JavaFX will automatically inject the control reference when the FXML is loaded.
How do you make a button execute code when clicked?
Add the onAction property to the button in FXML and set it to the name of a method in your controller (e.g., onAction="#handleButtonClick"). Create the corresponding method in your controller class, and it will be called whenever the button is clicked.