首页 > 解决方案 > 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));

      //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-Class 中对 window 的引用不起作用。

当我尝试textfield.getText()从 -Class 中的文本字段时(当然)会出现同样的问题EventHandlersExample

我该如何解决这个问题?---非常感谢帮助。

标签: javajavafxevent-handling

解决方案


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

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).


推荐阅读