0

I have an fxml that describes my gui. I want to change text of the gui and start a task on any key press anywhere.

FXML

<Text fx:id="barcodeText"/>

Controller

   @FXML
   Text barcodeText;

   public void start(Stage primaryStage) throws IOException {
        this.primaryStage=primaryStage;
        Scene mainScene =new Scene(root);
        primaryStage.setScene(mainScene);
        primaryStage.setResizable(false);
        primaryStage.show();
        Parent root = FXMLLoader.load(getClass().getResource("/view/foo.fxml"));
        mainScene.addEventHandler(KeyEvent.KEY_PRESSED,new KeyboardEventHandler(){
                @Override
                public void handle(KeyEvent event) {
                   barcodeText.setText("foo");
                }
        });

This gives me a NullPointerException(inside JavaFX Application Thread) for the barcodeText pointer when I fire the event.

Am I doing something wrong?

The examples I looked at were using this approach without fxml, do I have to use an annotation to define the handler? where would I put "onAction" for the scene in the fxml?

Flying Swissman
  • 818
  • 2
  • 14
  • 39
  • `@FXML Text textBox;` or `@FXML Text barcodeText;`? – pzaenger Feb 28 '17 at 15:22
  • 1
    The FXML loader initializes `@FXML`-annotated fields in the *controller*, not in the instance of the `Application` class on which `start` is called. So `barcodeText` (or `textBox`, or whatever you really called it) will be null in the `Application` instance. – James_D Feb 28 '17 at 15:25
  • @pzaenger sorry, that was a typo – Flying Swissman Feb 28 '17 at 15:26
  • @James_D Ok, so that is the root of the problem. How do I solve it? for a button i can do `@FXML public void onClick(Event event) ...` how do I do this for the scene? – Flying Swissman Feb 28 '17 at 15:37

1 Answers1

4

(Aside: it looks like you are trying to use the same class for the controller, and for the application. Don't do that.)

Define a method in the controller class for setting the barcode text:

public void setBarcodeText(String barcode) {
    barcodeText.setText(barcode);
}

Then call that method from your handler:

FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/foo.fxml"));
Parent root = loader.load();

MyControllerClass controller = loader.getController();

Scene mainScene = new Scene(root);
mainScene.addEventHandler(KeyEvent.KEY_PRESSED, new KeyboardEventHandler(){
        @Override
        public void handle(KeyEvent event) {
            controller.setBarcodeText("foo");
        }
});

Obviously, replace MyControllerClass with the actual name of the controller class.

Community
  • 1
  • 1
James_D
  • 201,275
  • 16
  • 291
  • 322