Custom events and submitting on enter using JavaFx

Table of Contents

Tags:

This blog post will showcase a simple, small and often overlooked usage of event handlers1 in Javafx2.

First we start off by creating a new JavaFx app named Demo extending Application with an attribute s of type Scene. Our class also includes the standard main method calling the launch method inherited from the Application class.

 1import javafx.application.Application;
 2import javafx.scene.Scene;
 3
 4public class Demo extends Application {
 5    Scene s;
 6
 7    public static void main(String[] args) {
 8        launch(args);
 9    }
10}

Our next step is to create a new Scene and add both a TextField and a Button to a vertical aligned box (VBox). This can be archived by adding the following code to a new method called start and creating a new method called createContent:

 1/**/
 2import javafx.scene.control.Button;
 3import javafx.scene.control.TextField;
 4import javafx.scene.layout.VBox;
 5import javafx.stage.Stage;
 6import javafx.scene.Parent;
 7
 8
 9public class Demo extends Application {
10    /**/
11
12    private Parent createContent() {
13        Button b = new Button("Submit");
14        TextField tf = new TextField("Placeholder");
15        tf.setId("textarea-main");
16
17        return new VBox(tf, b);
18    }
19
20    @Override
21    public void start(Stage primaryStage) {
22        this.s = new Scene(createContent(), 500, 500);
23        primaryStage.setScene(this.s);
24        primaryStage.show();
25    }
26
27    /**/
28}

Your Application should now look like this:

image

The next move is to implement our custom event which will fire on pressing Enter:

 1/**/
 2import javafx.event.Event;
 3import javafx.event.EventType;
 4
 5class UserEvent extends Event {
 6    public static final EventType<UserEvent> _KEY_ENTER = new EventType<>(ANY, "_KEY_ENTER");
 7    public UserEvent(EventType<? extends Event> eventType){
 8        super(eventType);
 9    }
10}
11
12public class Demo extends Application {
13  /**/
14}

Now we can implement the event_handler method:

 1/**/
 2
 3/**/
 4
 5public class Demo extends Application {
 6    /**/
 7
 8    private void event_handler(Event e) {
 9        TextField t = (TextField) this.s.lookup("#textarea-main");
10        switch (e.getEventType().getName()) {
11            case "_KEY_ENTER":
12            case "MOUSE_PRESSED": {
13                System.out.println(t.getText().trim());
14                break;
15            }
16            default:
17                System.out.println("Unknown Event");
18        }
19    }
20
21    /**/
22
23    /**/
24}

This should log the content of the TextField on pressing Enter or clicking on the Submit-Button once we implement firing these events in the following snippet by adding an ID to the TextField which we will use to query the Scene to look for the TextField and extract its content. We will also add two event listeners, the first on the Button and the second on the TextField:

 1/**/
 2
 3/**/
 4
 5public class Demo extends Application {
 6  /**/
 7
 8  private Parent createContent() {
 9        Button b = new Button("Submit");
10        b.addEventHandler(UserEvent._KEY_ENTER, this::event_handler);
11        b.setOnMousePressed(this::event_handler);
12
13        TextField tf = new TextField("Placeholder");
14        tf.setId("textarea-main");
15        tf.setOnKeyPressed(k -> {
16            if(k.getCode() == KeyCode.ENTER) b.fireEvent(new UserEvent(UserEvent._KEY_ENTER));
17        });
18
19        return new VBox(tf, b);
20    }
21
22    /**/
23
24    /**/
25
26    /**/
27}

The TextField now fires a event of type _KEY_ENTER which we are listening for in Demo.event_handler(). Clicking the Button fires an MOUSE_PRESSED and the _KEY_ENTER event which will also be processed by our event handling.

1b.addEventHandler(UserEvent._KEY_ENTER, this::event_handler);
2b.setOnMousePressed(this::event_handler);
3tf.setOnKeyPressed(/**/);

After putting everything together, the app should look like this:

image

Congrats, you implemented submitting on enter :)

Full code:

 1import javafx.application.Application;
 2import javafx.event.Event;
 3import javafx.event.EventType;
 4import javafx.scene.Parent;
 5import javafx.scene.Scene;
 6import javafx.scene.control.Button;
 7import javafx.scene.control.TextField;
 8import javafx.scene.input.KeyCode;
 9import javafx.scene.input.MouseEvent;
10import javafx.scene.layout.VBox;
11import javafx.stage.Stage;
12
13class UserEvent extends Event {
14    public static final EventType<UserEvent> _KEY_ENTER = new EventType<>(ANY, "_KEY_ENTER");
15    public UserEvent(EventType<? extends Event> eventType){
16        super(eventType);
17    }
18}
19
20public class Demo extends Application {
21    Scene s;
22
23
24    private Parent createContent() {
25        Button b = new Button("Submit");
26        b.addEventHandler(UserEvent._KEY_ENTER, this::event_handler);
27        b.setOnMousePressed(this::event_handler);
28
29        TextField tf = new TextField("Placeholder");
30        tf.setId("textarea-main");
31        tf.setOnKeyPressed(k -> {
32            if(k.getCode() == KeyCode.ENTER) b.fireEvent(new UserEvent(UserEvent._KEY_ENTER));
33        });
34
35        return new VBox(tf, b);
36    }
37
38    private void event_handler(Event e) {
39        TextField t = (TextField) this.s.lookup("#textarea-main");
40        switch (e.getEventType().getName()) {
41            case "_KEY_ENTER":
42            case "MOUSE_PRESSED": {
43                System.out.println(t.getText().trim());
44                break;
45            }
46            default:
47                System.out.println("Unknown Event");
48        }
49    }
50
51    @Override
52    public void start(Stage primaryStage) {
53        this.s = new Scene(createContent(), 500, 500);
54        primaryStage.setScene(this.s);
55        primaryStage.setTitle("Demo");
56        primaryStage.show();
57    }
58
59    public static void main(String[] args) {
60        launch(args);
61    }
62}