Key Events
Tags: java, programming, learning, beginners
Published: 2024-06-24 21:13:24

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u4kt8p10dzedmbjhnfkr.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q18zm6thpy5jviw1y8xp.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n5kbzr8xjzq5v9tzffma.png)

```
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);
	}
}

```

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](https://dev.to/paulike/registering-handlers-and-handling-events-3j7e) 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);
	}
}

```

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.