Java · JavaFX · Topic 5
Basic Event Handling
Understand event-driven programming and handle actions, text, selections, keyboard input, and mouse input.
Step 1 of 13
5.1 Event-Driven Programming
Contrast sequential console flow with event-driven GUI flow.
| Console program | Event-driven JavaFX program |
|---|---|
| Runs statements in a planned sequence | Starts the interface and waits |
| Often blocks while reading input | Receives events from controls, keys, and the mouse |
| The program asks for the next value | The user chooses the next action |
After stage.show(), the JavaFX event loop continues running. When the user clicks, types, or changes a selection, JavaFX creates an event and dispatches it to a matching handler.
Check your understanding: What determines which handler runs in an event-driven application?
The event that occurs and the handler registered for its source or target.
Step 2 of 13
5.2 What is an Event?
Define an event and identify common JavaFX event categories.
Common events
- ActionEvent for command controls
- KeyEvent for keyboard input
- MouseEvent for mouse actions
- InputMethodEvent for composed text input
- Selection and value changes exposed through observable properties
Check your understanding: What event commonly represents a Button activation?
ActionEvent.
Step 3 of 13
5.3 Event Source
Identify the object where an event originates.
submit.setOnAction(event -> {
Button source = (Button) event.getSource();
result.setText(source.getText() + " clicked");
});Check your understanding: In a button-click example, what is normally the event source?
The Button that was activated.
Step 4 of 13
5.4 Event Object
Use event-object information inside a handler.
scene.setOnKeyPressed(event ->
status.setText("Key: " + event.getCode()));
root.setOnMouseClicked(event ->
status.setText("Mouse: " + event.getX()
+ ", " + event.getY()));Check your understanding: Which MouseEvent methods return the pointer position relative to the node?
getX() and getY().
Step 5 of 13
5.5 Event Handler
Describe the code executed in response to an event.
button.setOnAction(event -> {
result.setText("Operation completed");
});A useful handler usually
- Reads the event or current control values
- Validates input
- Updates application state
- Updates the interface
- Reports errors clearly
Check your understanding: Does registering a handler execute it immediately?
No. It runs when the matching event is dispatched.
Step 6 of 13
5.6 EventHandler<ActionEvent>
Implement the EventHandler interface explicitly and compare it with a lambda.
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
result.setText("Clicked");
}
});button.setOnAction(event -> result.setText("Clicked"));import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class EventHandlerDemo extends Application {
@Override
public void start(Stage stage) {
Button button = new Button("Click Me");
Label result = new Label("Waiting");
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
result.setText("Handled by EventHandler");
}
});
stage.setScene(new Scene(new VBox(12, button, result), 340, 180));
stage.setTitle("EventHandler Demo");
stage.show();
}
public static void main(String[] args) { launch(args); }
}Before clicking: Waiting
After clicking: Handled by EventHandlerCheck your understanding: Which method is implemented by EventHandler<ActionEvent>?
handle(ActionEvent event).
Step 7 of 13
5.7 Button Click Event
Handle a command button and validate numeric input.
addButton.setOnAction(event -> {
try {
double first = Double.parseDouble(firstField.getText());
double second = Double.parseDouble(secondField.getText());
result.setText("Sum: " + (first + second));
} catch (NumberFormatException ex) {
result.setText("Enter valid numbers");
}
});import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class AdditionEventDemo extends Application {
@Override
public void start(Stage stage) {
TextField first = new TextField();
TextField second = new TextField();
Button add = new Button("Add");
Label result = new Label();
add.setOnAction(e -> {
try {
double a = Double.parseDouble(first.getText());
double b = Double.parseDouble(second.getText());
result.setText("Sum: " + (a + b));
} catch (NumberFormatException ex) {
result.setText("Enter valid numbers");
}
});
stage.setScene(new Scene(new VBox(10, first, second, add, result), 340, 240));
stage.setTitle("Addition Event Demo");
stage.show();
}
public static void main(String[] args) { launch(args); }
}For inputs 15 and 25:
Sum: 40.0
For invalid input:
Enter valid numbersCheck your understanding: Which exception should be handled when converting invalid text to a number?
NumberFormatException.
Step 8 of 13
5.8 TextField Events
Respond when the user submits text or when the text value changes.
nameField.setOnAction(event ->
greeting.setText("Hello " + nameField.getText()));nameField.textProperty().addListener(
(observable, oldValue, newValue) ->
count.setText("Characters: " + newValue.length()));Check your understanding: How can a handler run when the user presses Enter in a TextField?
Register it with setOnAction().
Step 9 of 13
5.9 Checkbox Events
Respond to independent selected-state changes.
EventHandler<ActionEvent> updateSubjects = event -> {
String selected = "";
if (javaBox.isSelected()) selected += "Java ";
if (pythonBox.isSelected()) selected += "Python ";
result.setText("Subjects: " + selected.trim());
};
javaBox.setOnAction(updateSubjects);
pythonBox.setOnAction(updateSubjects);Check your understanding: Can several CheckBox handlers report selected choices at the same time?
Yes, because CheckBoxes are independent.
Step 10 of 13
5.10 RadioButton Events
Respond to a mutually exclusive selection and safely read the selected toggle.
EventHandler<ActionEvent> showGender = event -> {
RadioButton selected =
(RadioButton) genderGroup.getSelectedToggle();
result.setText(selected == null
? "Select gender"
: "Gender: " + selected.getText());
};
male.setOnAction(showGender);
female.setOnAction(showGender);Check your understanding: Why must getSelectedToggle() be checked for null?
A group may have no selected RadioButton.
Step 11 of 13
5.11 ComboBox Event
Respond when a new drop-down item is chosen.
branchBox.setOnAction(event -> {
String branch = branchBox.getValue();
result.setText(branch == null
? "Select a branch"
: "Branch: " + branch);
});Check your understanding: What must be handled before using the selected value?
The possibility that getValue() is null.
Step 12 of 13
5.12 Keyboard Events
Handle pressed, released, and typed keyboard input.
scene.setOnKeyPressed(event -> {
status.setText("Pressed: " + event.getCode());
if (event.getCode() == KeyCode.ESCAPE) {
stage.close();
}
});| Method | Meaning |
|---|---|
| setOnKeyPressed | Physical key goes down |
| setOnKeyReleased | Physical key goes up |
| setOnKeyTyped | A character is produced |
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class KeyboardEventDemo extends Application {
@Override
public void start(Stage stage) {
Label status = new Label("Press a key");
Scene scene = new Scene(new StackPane(status), 360, 180);
scene.setOnKeyPressed(e -> {
status.setText("Pressed: " + e.getCode());
if (e.getCode() == KeyCode.ESCAPE) stage.close();
});
stage.setScene(scene);
stage.setTitle("Keyboard Event Demo");
stage.show();
}
public static void main(String[] args) { launch(args); }
}Pressing A displays:
Pressed: A
Pressing Escape closes the window.Check your understanding: Why might a Scene key handler receive nothing while the window is open?
The intended node may not have focus, or another control may consume the event.
Step 13 of 13
5.13 Mouse Events
Handle mouse actions and combine multiple event types in one application.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class IntegratedEventDemo extends Application {
@Override
public void start(Stage stage) {
TextField name = new TextField();
name.setPromptText("Enter name and press Enter");
CheckBox emailUpdates = new CheckBox("Email updates");
ComboBox<String> branch = new ComboBox<>();
branch.getItems().addAll("CSE", "IT", "EC");
branch.setPromptText("Select branch");
Label status = new Label("Interact with the controls");
Button submit = new Button("Submit");
name.setOnAction(e ->
status.setText("Hello " + name.getText()));
emailUpdates.setOnAction(e ->
status.setText("Email updates: "
+ emailUpdates.isSelected()));
branch.setOnAction(e ->
status.setText("Branch: " + branch.getValue()));
submit.setOnAction(e ->
status.setText("Submitted for " + name.getText()));
VBox root = new VBox(12,
name, emailUpdates, branch, submit, status);
root.setPadding(new Insets(20));
root.setOnMouseClicked(e ->
status.setText("Mouse: " + (int)e.getX()
+ ", " + (int)e.getY()));
Scene scene = new Scene(root, 430, 300);
scene.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ESCAPE) stage.close();
});
stage.setScene(scene);
stage.setTitle("Integrated Event Demo");
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}The status label changes according to the latest event.
Examples:
Hello Vatsal
Email updates: true
Branch: IT
Submitted for Vatsal
Mouse: 120, 210
Pressing Escape closes the window.| Handler | Responds to |
|---|---|
| setOnMouseClicked | Click or double-click |
| setOnMousePressed | Mouse button goes down |
| setOnMouseReleased | Mouse button goes up |
| setOnMouseEntered | Pointer enters a node |
| setOnMouseExited | Pointer leaves a node |
| setOnMouseMoved | Pointer moves without dragging |
| setOnMouseDragged | Pointer moves while a button is held |
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class MouseEventDemo extends Application {
@Override
public void start(Stage stage) {
Label status = new Label("Click anywhere");
StackPane root = new StackPane(status);
root.setOnMouseClicked(e -> status.setText(
"Mouse: " + (int)e.getX() + ", " + (int)e.getY()
+ " | Clicks: " + e.getClickCount()));
stage.setScene(new Scene(root, 420, 240));
stage.setTitle("Mouse Event Demo");
stage.show();
}
public static void main(String[] args) { launch(args); }
}Example single click:
Mouse: 120, 90 | Clicks: 1
Example double-click:
Mouse: 120, 90 | Clicks: 2Check your understanding: Which method reports a double-click count?
MouseEvent.getClickCount(), which returns 2 for a double-click.