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:
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:
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}