【问题标题】:JavaFX Event handling from a different class来自不同类的 JavaFX 事件处理
【发布时间】:2019-09-29 20:13:35
【问题描述】:

我查看了似乎与我的问题相似的 stackoverflow 问题,但没有任何帮助。

这是我的问题:

对于一个项目,我正在制作一个没有 FXML 的纯 Java 的 JavaFX 应用程序。我有两个类,一个控制器 Controller 类和一个包含 gui 东西 GUI 的类。

Controller 有一个GUI 类型的成员变量,我正在尝试将事件处理程序分配给GUI 中的一个按钮,但它似乎不起作用。它仅在我尝试在 GUI 类中实现处理程序时才有效,但我需要它在 Comtroller 中工作。

Controller的构造函数中如下:

        this.view = view;

        view.addSimpleHandler(new SimpleHandler());

viewGUI 类型,addSimpleHandlerview 的成员函数

SimpleHandlerController 的内部类,它实现了EventHandler 并覆盖了handle() 函数

public void addSimpleHandler(EventHandler<ActionEvent> e) {
        simpleButton.setOnAction(e);
}

这是GUI的主要方法和类签名

public class GUI extends Application {
//member variables for the GUI design including simpleButton
    private Button simpleButton;
    public static void main(String[] args) {
        GUI view = new GUI();
        Controller controller = new Controller(view);

        Application.launch(view.getClass(), args);

    }

    public GUI() {
       simpleButton = new Button("Simple button");

       //rest of code is setting up GUI into my panes
    }


    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(mainPane, sceneWidth, sceneHeight);
        //mainPane is a pane that contains simpleButton with a screenwidth and screenHeight
        primaryStage.setTitle("Simple");
        primaryStage.setScene(scene);
        primaryStage.show();

    }

【问题讨论】:

  • 显示你的整个代码。
  • @mentallurg 这是唯一涉及的代码
  • 显然不是。例如,没有定义“simpleButton”。如果不清楚您真正拥有什么代码,则很难为您提供帮助。
  • @mentallurg 添加了简单的按钮部分。
  • 没有人知道您的 Controller 和 SimpleHandler 中发生了什么。如果您不显示代码,则只能猜测。祝你好运。

标签: java javafx model-view-controller


【解决方案1】:

不要手动实例化您的应用程序类。要了解原因,请参阅 the documentation 关于 JavaFX 生命周期(强调我的):

JavaFX 应用程序的入口点是 Application 类。 JavaFX 运行时按顺序执行以下操作,每当启动应用程序时:

  1. 启动 JavaFX 运行时(如果尚未启动)(有关详细信息,请参阅 Platform.startup(Runnable)
  2. 构造指定应用程序类的实例
  3. 调用init()方法
  4. 调用start(javafx.stage.Stage)方法
  5. 等待应用程序完成,当发生以下任一情况时会发生这种情况:
    • 应用程序调用Platform.exit()
    • 最后一个窗口已关闭且Platform 上的implicitExit 属性为真
  6. 调用stop()方法

如您所见,JavaFX 本身将实例化应用程序类,它是 那个 实例,它调用了它的生命周期方法——这些方法是 init()start(Stage)stop() .但是,在您的代码中,您有以下内容:

public static void main(String[] args) {
    GUI view = new GUI(); // created your own instance
    Controller controller = new Controller(view); // gave controller that instance

    // Launches JavaFX which starts the life-cycle documented above
    Application.launch(view.getClass(), args);
}

您创建自己的GUI 实例。这个实例不是由 JavaFX 管理的,这意味着它的 start(Stage) 方法永远不会被调用。当您创建Controller 实例并将GUI 实例传递给它时,您将EventHandler 添加到一个从未显示的节点中。您看到显示的窗口来自作为对 Application#launch 的调用的一部分而创建的 GUI 实例,并且该 GUI 实例永远不会与 Controller 关联。

对于 JavaFX 应用程序,您应该考虑将 init()start(Stage) 方法作为入口点1。换句话说,在上述生命周期方法之一中创建Controller。虽然我想你可以在构造函数中做同样的事情而不是2。无论您选择哪种方式,请记下哪个线程调用了每个方法,这已记录在 in the same place as the life-cycle 中。以下是要点:

  • 应用程序类在 JavaFX 应用程序线程上加载、初始化和构造。
  • init() 方法由 JavaFX-Launcher 线程调用。
  • start(Stage)stop() 方法由JavaFX 应用程序线程 调用。

请记住,某些操作只能在 JavaFX 应用程序线程上执行。


1.如果需要,您仍然可以在 main 方法中调用 Application#launch 之前执行代码。唯一的限制是代码不应与 JavaFX 直接相关。

2。您的构造函数当前是公开的并且具有零参数——保持这种状态。 JavaFX 要求应用程序类具有公共的、无参数的构造函数,以便通过反射构造实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    • 1970-01-01
    相关资源
    最近更新 更多