Set KeyPressed event for a TextField in JavaFX

Danial Kosarifa picture Danial Kosarifa · Sep 5, 2016 · Viewed 8.2k times · Source

I have number of TextField objects inside a pop up window called dialog (type : Stage).

I am trying to define an action handler for them which aims to close the stage once the escape button is clicked on the key board.

Here is my function for the stage closer :

public void escapeKeyPressed(KeyCode keyCode , Stage dialog){
    if (keyCode == KeyCode.ESCAPE ){
        dialog.close();
        System.out.println("escape got called");
    }
} 

and the following is where I call it :

textUsername.setOnAction((event) -> {escapeKeyPressed(KeyCode.ESCAPE ,dialog );});
textAddress.setOnAction((event) -> {escapeKeyPressed(KeyCode.ESCAPE ,dialog );});
textwp.setOnAction((event) -> {escapeKeyPressed(KeyCode.ESCAPE ,dialog );});
textState.setOnAction((event) -> {escapeKeyPressed(KeyCode.ESCAPE ,dialog );});
textloginName.setOnAction((event) -> {escapeKeyPressed(KeyCode.ESCAPE ,dialog );});

The problem is that the function doesn't get called.

Any idea how can I fix that? It's woth mentioning that the function by itself works fine if I replace the caller out of setOnAction();

Answer

DVarga picture DVarga · Sep 5, 2016

The setOnAction documentation for TextField states:

The action handler associated with this text field, or null if no action handler is assigned. The action handler is normally called when the user types the ENTER key.

Therefore, escapeKeyPressed will be executed on Enter key press. What will happen now: if you press Enter key, it will call this method with KeyCode.ESCAPE, therefore it will close the dialog.

Use setOnKeyPressed rather than setOnAction:

Defines a function to be called when this Node or its child Node has input focus and a key has been pressed.

Rather than pass KeyCode.ESCAPE, pass the KeyCode of the KeyEvent what you can get with getCode():

textUsername.setOnKeyPressed(event -> escapeKeyPressed(event.getCode(), dialog));