Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Events and handlers

When the user clicks a button, clicks the mouse or presses a key, JavaFX creates an event object and passes it to a handler, the code you attached to the control beforehand. The handler runs in the JavaFX thread. In this lesson the "Add" button starts doing real work: checking the title, showing a message and clearing the form.

Class fields instead of local variables

Handlers are best moved into separate methods. For those methods to see the form controls, the controls become class fields:

// src/main/java/com/example/notes/App.java — class fields
private final TextField titleField = new TextField();
private final TextArea textArea = new TextArea();
private final ComboBox<String> categoryBox = new ComboBox<>();
private final CheckBox importantBox = new CheckBox("Important");
private final Label statusLabel = new Label();

statusLabel is a status line: it goes into the bottom row next to the buttons.

A handler in a separate method

The handler method takes an ActionEvent object. It is attached to the button with the method reference this::addNote:

// src/main/java/com/example/notes/App.java — part of the class
addButton.setOnAction(this::addNote);
titleField.setOnAction(this::addNote);
 
// ...
 
private void addNote(ActionEvent event) {
    String title = titleField.getText().strip();
    if (title.isEmpty()) {
        statusLabel.setText("Enter a title");
        return;
    }
    statusLabel.setText("Note added: " + title);
    clearForm();
}
 
private void clearForm() {
    titleField.clear();
    textArea.clear();
    importantBox.setSelected(false);
    titleField.requestFocus();
}

TextField has an onAction event too: it fires on the Enter key. So a note can be added without leaving the keyboard. requestFocus() puts the cursor back into the title field.

The mouse

Besides onAction, every node has mouse and keyboard events. A double click on the status line clears it:

// src/main/java/com/example/notes/App.java — part of start()
statusLabel.setOnMouseClicked(event -> {
    if (event.getClickCount() == 2) {
        statusLabel.setText("");
    }
});
MethodWhen it fires
setOnActionA button click, Enter in a field, a choice in a ComboBox
setOnMouseClickedA mouse click; getClickCount() is the number of clicks
setOnKeyPressedA key press while the node has focus
setOnMouseEnteredThe cursor moved onto the node

A keyboard shortcut

A shortcut that works anywhere in the window is added to the scene. SHORTCUT_DOWN means Ctrl on Windows and Linux and Cmd on macOS:

// src/main/java/com/example/notes/App.java — part of start()
Scene scene = new Scene(root, 640, 480);
scene.getAccelerators().put(
        new KeyCodeCombination(KeyCode.N, KeyCombination.SHORTCUT_DOWN),
        this::clearForm);

Now Ctrl+N clears the form wherever the cursor is.

Trying it out

Add the status line to the bottom row: new HBox(8, addButton, new Button("Delete"), statusLabel). Run the application, type "Buy milk" and press Enter. To the right of the buttons you see "Note added: Buy milk", the fields are cleared and the check box is unticked. Click "Add" with an empty field and the line changes to "Enter a title".

Common mistake

Instead of a method reference people write a call: addButton.setOnAction(addNote());. The parentheses call the method right away instead of handing it to the button, so the compiler answers method addNote in class com.example.notes.App cannot be applied to given types; required: javafx.event.ActionEvent; found: no arguments. Pass the method itself: this::addNote or the lambda event -> addNote(event).

Thanks for reading!

Donate to the site — we work hard for you.