2

I have problems catching the KeyEvent when pressing down a key on the application pane. The files structures are as follows:

ApplicationStarter.java

package appdemo;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class ApplicationStarter extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(ApplicationStarter.class.getResource("GUI.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 320, 240);
        stage.setTitle("Rock N' Roll");
        stage.setScene(scene);
        stage.show();
    }

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

ApplicationControllerClass.java

package appdemo;
import javafx.fxml.FXML;
import javafx.scene.input.*;
import javafx.scene.layout.Pane;

public class ApplicationControllerClass {

    @FXML
    private Pane mainPane;

    @FXML
    void initialize(){
    }

    @FXML
    void onKeyPressed(KeyEvent event) {
        System.out.println("Key pressed on pane!");
    }

    @FXML
    void onMouseClicked(MouseEvent event) {
        System.out.println("Mouse clicked on pane!");
    }

}

GUI.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.Pane?>


<Pane fx:id="mainPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onKeyPressed="#onKeyPressed" onMouseClicked="#onMouseClicked" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="appdemo.ApplicationControllerClass" />.

In ApplicationControllerClass.java, there two methods for printing the events of mouse clicking and key pressing on the console. When I run the application, the mouse clicking event prints without problem when I click on the mainPane, whereas the key pressing event does not when I press a key on mainPane.

Am I missing something? Does the method OnKeyPressed in ApplicationControllerClass.java actually catch the event?

Addendum

I also checked here and here, but could not find any upvoted, accepted or relevant answer. The problem with the current answers is that they bind an event handler method to an element in the controller class, while I wish to do this binding in GUI.fxml, as is the current case.

Mostafa Ayaz
  • 480
  • 1
  • 7
  • 16
  • 4
    Key events are delivered to the `Node` that has focus. Most likely your `mainPane` is not focused—nor are any of its (non-existent) descendants—thus no key events reach it. You could add a `mainPane.requestFocus()` call in the `onMouseClicked` method. After clicking on the pane once, it should start to get key-pressed events. I would say put it in the `initialize` method, but I believe `requestFocus` only works once a `Node` is part of a `Scene`, and the `initialize` method will be called before that's true. – Slaw Jan 30 '23 at 20:30
  • Thank you. It worked. So, I guess I need to add the requestFocus() method to any other Node's MouseEventHandler to capture the focus first and then handle the KeyEvent (e.g. when there is another Pane I wish to capture a KeyEvent). – Mostafa Ayaz Jan 30 '23 at 20:56
  • 3
    Yes. Or add some other way to request the focus (e.g., react to `mainPane` becoming part of a `Scene` by then calling `requestFocus()`). It depends on how you want the flow of your application to work. But you can see in the implementations of e.g., `TextField` that it requests the focus when it is clicked (among other mechanisms, e.g., "tabbing" though the focus-traversable nodes). Note you might want to style your nodes differently when they have the focus, so that your users have some kind of indication. – Slaw Jan 30 '23 at 21:00
  • As noted in the second example you cited, adding a button produced the effect described by @Slaw. – trashgod Jan 30 '23 at 21:03
  • 3
    If you always want to be notified when a key a pressed, you can do that by an event *filter* on the scene. Then you will receive the event, whenever the window is focused and a key is pressed, regardless of what is focused or not in the scene. That is a different approach than you are using, just providing extra info for context, ignore if irrelevant. – jewelsea Jan 30 '23 at 21:19

0 Answers0