Clyde Frog
Clyde Frog

Reputation: 483

EventHandler in a separate class

The following code allows to switch between two scenes.

import javafx.application.*;
import javafx.event.ActionEvent; 
import javafx.event.EventHandler;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.control.*;

public class EventHandlersExample extends Application {

  Stage window;
  Scene scene1, scene2;

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

  @Override
  public void start(Stage primaryStage) {
      window = primaryStage;

      //Button 1
      Label label1 = new Label("Welcome to the first scene!");
      Button button1 = new Button("Go to scene 2");

      button1.setOnAction(e -> window.setScene(scene2));

      //Textfield
      TextField tf1 = new TextField();

      //Layout 1 - children laid out in vertical column
      VBox layout1 = new VBox(20);
      layout1.getChildren().addAll(label1, button1);
      scene1 = new Scene(layout1, 200, 200);

      //Button 2
      Button button2 = new Button("Go back to scene 1");
      button2.setOnAction(e -> window.setScene(scene1));

      //Layout 2
      StackPane layout2 = new StackPane();
      layout2.getChildren().add(button2);
      scene2 = new Scene(layout2, 600, 300);

      //Display scene 1 at first
      window.setScene(scene1);
      window.show();
  }
}

However, I'd rather see my EventHandler in a separate class, like this:

import javafx.application.*;
import javafx.event.ActionEvent; 
import javafx.event.EventHandler;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.control.*;

public class EventHandlersExample extends Application {

  Stage window;
  Scene scene1, scene2;

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

  @Override
  public void start(Stage primaryStage) {
      window = primaryStage;

      //Button 1
      Label label1 = new Label("Welcome to the first scene!");
      Button button1 = new Button("Go to scene 2");

      //button1.setOnAction(e -> window.setScene(scene2));
      Button1Handler button1handler = new Button1Handler();
      button1.setOnAction(button1handler);

      //Textfield
      TextField tf1 = new TextField();

      //Layout 1 - children laid out in vertical column
      VBox layout1 = new VBox(20);
      layout1.getChildren().addAll(label1, button1);
      scene1 = new Scene(layout1, 200, 200);

      //Button 2
      Button button2 = new Button("Go back to scene 1");
      button2.setOnAction(e -> window.setScene(scene1));

      //Layout 2
      StackPane layout2 = new StackPane();
      layout2.getChildren().add(button2);
      scene2 = new Scene(layout2, 600, 300);

      //Display scene 1 at first
      window.setScene(scene1);
      window.show();
  }
}

class Button1Handler implements EventHandler<ActionEvent> {
      @Override
      public void handle (ActionEvent e) {
      System.out.println("OK button clicked");
      window.setScene(scene2);  
    }
  }

Yet, the reference to window in the EventHandlersExample-Class does not work.

The same problem occurs (of course) when I try to textfield.getText() from a textfield in the EventHandlersExample-Class.

How can I fix this?---Help is greatly appreciated.

Upvotes: 0

Views: 1169

Answers (1)

Mick Mnemonic
Mick Mnemonic

Reputation: 7956

If you're encapsulating the event-handling logic in a separate class, you need to somehow pass references of the parent window and the scene to the handler. A convenient way to do this is to inject the dependencies through the constructor:

class Button1Handler implements EventHandler<ActionEvent> {

    private final Stage window;
    private final Scene scene;

    public Button1Handler (Stage window, Scene scene) {
        this.window = window;
        this.scene = scene;
    }

     @Override
     public void handle (ActionEvent e) {
         System.out.println("OK button clicked");
         window.setScene(scene);  
    }
}

You'd then create the handler with new Button1Handler(window, scene2).

Upvotes: 1

Related Questions