单独类中的EventHandler

时间:2018-07-26 08:45:58

标签: java javafx event-handling

以下代码允许在两个场景之间切换。

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();
  }
}

但是,我宁愿在单独的类中看到我的EventHandler,如下所示:

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);  
    }
  }

但是,EventHandlersExample类中对窗口的引用不起作用。

(当然)当我尝试从textfield.getText()类的文本字段中EventHandlersExample时,也会发生相同的问题。

我该如何解决?---非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

如果将事件处理逻辑封装在单独的类中,则需要以某种方式将父窗口和场景的引用传递给处理程序。一种方便的方法是通过构造函数注入依赖项:

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);  
    }
}

然后您将使用new Button1Handler(window, scene2)创建处理程序。