10

I recently started playing around with Java FX, FXML, and scene builder, and I've been trying to add key listeners to one of the controllers for a scene. When I do this though, the key listeners don't work as they should, and I figure it's because they're not focused onto that particular scene. I tried to get access to the scene the controller was part of in order to set it directly, but it comes up that it's part of a null scene.

Is there a way to gain access to the scene that this controller is used in in order to try and assign key event and listeners to that particular scene? Should I go through the rootController which is static throughout the whole application? Or, better yet, is there a simpler way of going about this?

Most examples I see assume that everything is mostly together in a main class or separated amongst a couple of other classes without FXML being brought in, and I'm not sure how to apply their fixes when I have the java controllers, FXML pages, and the main application all separated.

Thanks for any help!

Keanu
  • 207
  • 2
  • 3
  • 9

2 Answers2

30

Use any of the controls that is bound in the Controller and use getScene() on it.

Remember not to use it in initialize() as the root element(though completely processed) is still not placed on the scene when initialize() is called for the controller

public class WindowMainController implements Initializable {

    @FXML
    private Button button;

    @FXML
    private void handleButtonAction(ActionEvent event) {
        System.out.println(button.getScene()); // Gives you the Scene
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        System.out.println(button.getScene()); // Prints null
    }

}
Neuron
  • 5,141
  • 5
  • 38
  • 59
ItachiUchiha
  • 36,135
  • 10
  • 122
  • 176
  • Yup! That gives me the scene instead of null ^^. I was trying to get it while in the init() method, so that must have been the problem! Thank you! Now, I can hopefully get the keylisteners to work :D – Keanu Sep 26 '14 at 13:56
  • If you are trying to add `keylisteners` to scene, I would advice to do it where the scene is created. *Though I am not sure of your requirement* – ItachiUchiha Sep 26 '14 at 13:58
  • I'm trying to make a game using all of this stuff, and the way I have it now there's one scene that would be the root, and I just switch the stage depending on where the user would be at each time. Would I just add it onto the scene when I change the stage, so the key events are already there? And how would I access elements inside the new controller and stage from outside the controller?(i.e. making a keyevent to move an image when the image is instantiated in the stage controller) – Keanu Sep 26 '14 at 14:14
  • I hope with `switch the stage`, you mean `switch the view`. `Would I just add it onto the scene when I change the stage, so the key events are already there`, you can do it, if there is not something stopping you from doing it. `And how would I access elements inside the new controller and stage from outside the controller?` you can use a property binding for this – ItachiUchiha Sep 26 '14 at 14:18
1

I found a similar problem where I wanted to get the scene whenever the scene is loaded and not on a button click. So I used the following approach.

public class WindowMainController implements Initializable {
  @FXML
  private AnchorPane parentPane;

  @Override
  public void initialize(URL url, ResourceBundle rb) {
      System.out.println(parentPane.getScene()); // Prints null

      parentPane.sceneProperty().addListener((observable, oldScene, newScene) -> {
        if (newScene != null) {
          System.out.println(parentPane.getScene()); // Prints the Scene               
        }
      });
  }
}
Shaheer.K
  • 21
  • 7