DEV Community

Cover image for Key Events
Paul Ngugi
Paul Ngugi

Posted on

Key Events

A KeyEvent is fired whenever a key is pressed, released, or typed on a node or a scene. Key events enable the use of the keys to control and perform actions or get input from the keyboard. The KeyEvent object describes the nature of the event (namely, that a key has been pressed, released, or typed) and the value of the key, as shown in Figure below.

Image description

Every key event has an associated code that is returned by the getCode() method in KeyEvent. The key codes are constants defined in KeyCode. Table below lists some constants. KeyCode is an enum type. For the key-pressed and key-released events, getCode() returns the value as defined in the table, getText() returns a string that describes the key code, and getCharacter() returns an empty string. For the key-typed event, getCode() returns UNDEFINED and getCharacter() returns the Unicode character or a sequence of characters associated with the key-typed event.

Image description

The program below displays a user-input character. The user can move the character up, down, left, and right, using the up, down, left, and right arrow keys. Figure below contains a sample run of the program.

Image description

package application;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class KeyEventDemo extends Application {
    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {
        // Create a pane and set its properties
        Pane pane = new Pane();
        Text text = new Text(20, 20, "A");

        pane.getChildren().add(text);
        text.setOnKeyPressed(e -> {
            switch(e.getCode()) {
            case DOWN: text.setY(text.getY() + 10); break;
            case UP: text.setY(text.getY() - 10); break;
            case LEFT: text.setX(text.getX() - 10); break;
            case RIGHT: text.setX(text.getX() + 10); break;
            default:
                if(Character.isLetterOrDigit(e.getText().charAt(0)))
                    text.setText(e.getText());
            }
        });

        // Create a scene and place it in the stage
        Scene scene = new Scene(pane);
        primaryStage.setTitle("KeyEventDemo"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage

        text.requestFocus(); // text is focused to receive key input
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

Enter fullscreen mode Exit fullscreen mode

The program creates a pane (line 12), creates a text (line 13), and places the text into the pane (line 15). The text registers the handler for the key-pressed event in lines 16–26. When a key is pressed, the handler is invoked. The program uses e.getCode() (line 17) to obtain the key code and e.getText() (line 24) to get the character for the key. When a nonarrow key is pressed, the character is displayed (lines 23 and 24). When an arrow key is pressed, the character moves in the direction indicated by the arrow key (lines 18–21). Note that in a switch statement for an enum type value, the cases are for the enum constants (lines 17–25). The constants are unqualified.

Only a focused node can receive KeyEvent. Invoking requestFocus() on text enables text to receive key input (line 34). This method must be invoked after the stage is displayed.

We can now add more control for our ControlCircle.java example in this post to increase/decrease the circle radius by clicking the left/right mouse button or by pressing the U and D keys. The new program is given in below.

package application;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.HBox;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class ControlCircleWithMouseAndKey extends Application {
    private CirclePane circlePane = new CirclePane();
    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {
        // Hold two buttons in an HBox
        HBox hBox = new HBox();
        hBox.setSpacing(10);
        hBox.setAlignment(Pos.CENTER);
        Button btEnlarge = new Button("Enlarge");
        Button btShrink = new Button("Shrink");
        hBox.getChildren().add(btEnlarge);
        hBox.getChildren().add(btShrink);

        // Create and register the handler
        btEnlarge.setOnAction(e -> {
            circlePane.enlarge();
            circlePane.requestFocus(); // Request focus on circlePane
        });
        btShrink.setOnAction(e -> {
            circlePane.shrink();
            circlePane.requestFocus(); // Request focus on circlePane
        });

        circlePane.setOnMouseClicked(e -> {
            if(e.getButton() == MouseButton.PRIMARY) {
                circlePane.enlarge();
            }
            else if(e.getButton() == MouseButton.SECONDARY) {
                circlePane.shrink();
            }
            circlePane.requestFocus(); // Request focus on circlePane
        });

        circlePane.setOnKeyPressed(e -> {
            if(e.getCode() == KeyCode.U) {
                circlePane.enlarge();
            }
            else if(e.getCode() == KeyCode.D) {
                circlePane.shrink();
            }
        });

        BorderPane borderPane = new BorderPane();
        borderPane.setCenter(circlePane);
        borderPane.setBottom(hBox);
        BorderPane.setAlignment(hBox, Pos.CENTER);

        // Create a scene and place it in the stage
        Scene scene = new Scene(borderPane, 200, 150);
        primaryStage.setTitle("KeyEventDemo"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage

        circlePane.requestFocus(); // Request focus on circlePane
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

Enter fullscreen mode Exit fullscreen mode

The CirclePane class (line 13) is already defined in ControlCircle.java and can be reused in this program.

A handler for mouse clicked events is created in lines 35–43. If the left mouse button is clicked, the circle is enlarged (lines 36–38); if the right mouse button is clicked, the circle is shrunk (lines 39–41).

A handler for key pressed events is created in lines 45–52. If the U key is pressed, the circle is enlarged (lines 46–48); if the D key is pressed, the circle is shrunk (lines 49–51).

Invoking requestFocus() on circlePane (line 65) makes circlePane to receive key events. Note that after you click a button, circlePane is no longer focused. To fix the problem, invoke requestFocus() on circlePane again after each button is clicked.

Top comments (0)