JavaFX是如何准确启动的

时间:2017-07-03 10:27:36

标签: java javafx

我刚刚写了一个JavaFX应用程序,并意识到我并不真正理解它是如何实际启动的。

@Override
public void start(Stage primaryStage) throws Exception {
    Parent root = new FXMLLoader(this.getClass().getResource("view.fxml")).load();
    primaryStage.setTitle("Dice Roller");
    primaryStage.setScene(new Scene(root));
    primaryStage.show();
}

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

这是Intellij给我的模板。我的切入点是主要的,其中唯一运行的是launch(args)。我曾尝试在Application类中进行挖掘,但没有发现任何指向运行start方法的内容。这甚至是如何推出的?由于JavaFX拥有自己的主题,我假设在启动方法中创建了一个主题,并且主线程从启动返回,直到您调用Platform.exit或者只是关闭所有窗户。这对我来说现在感觉有点太抽象了。有人可以向我解释它们是如何组合在一起的吗?

2 个答案:

答案 0 :(得分:3)

以下是您的主要应用程序类必须是什么样子。我把它命名为“HelloApp”,因为我需要一个名字。我还使用launch更改了Application.launch,但是相同但不那么令人困惑(请参阅下面的说明)。

但请注意(感谢@Cypher在评论中提出这一点) java不需要良好的旧public static void main(String[] args)方法来运行JavaFX应用程序
如果您省略了下面的main方法,请对其进行编译,然后使用java HelloApp运行它,它会起作用,并且可能会稍微有些混乱:) 您仍然可以处理没有main的命令行参数,因为它们会传递给参数对象,您可以使用ApplicationgetParameters()中获取参数对象。

我的IDE还允许在没有Application的情况下运行main,显然大部分都是。

话虽如此,让我们看看你的情况会发生什么:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class HelloApp extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = new FXMLLoader(this.getClass().getResource("view.fxml")).load();
        primaryStage.setTitle("Dice Roller");
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

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

}
  • HelloApp.main()调用launch()
  • launch是您扩展的Application类中的静态方法,因此可以直接使用launch()但是在调用静态方法时,建议使用类名,所以我用Application.launch替换上面。一些IDE和短信警告你,如果你不这样做,“ java静态方法应该以静态方式访问”。
  • launch方法中,JavaFX运行时(在“JavaFX”下面)确定哪个类是调用者(使用Thread.currentThread().getStackTrace(),但这只是一个有趣的实现细节)。该调用者类应该是javafx.application.Application - 在没有main的情况下运行时,上面的内容与JavaFX无关 从这里开始。 -
  • JavaFX创建一个应用程序线程,用于运行应用程序启动方法,处理输入事件和运行动画时间轴。
  • JavaFX构造指定Application类的实例
  • JavaFX调用init()(你可以覆盖)
  • JavaFX调用start()(您必须自己实现),来自“JavaFX Application Thread”

生命周期的其余部分在Application javadoc中描述 - 后续步骤正在等待应用程序完成(应用程序调用{​​{1}},或者最后一个窗口已关闭且Platform.exit()为真),然后JavaFX调用implicitExit(你可以覆盖)。

答案 1 :(得分:2)

通过此调用堆栈调用JavaFX应用程序的 start()方法:

  • 应用#发射:252
  • LauncherImpl#launchApplication:143
  • LauncherImpl#launchApplication:182
  • LauncherImpl#launchApplication1:863
  • 应用程序#start(由您的应用程序覆盖)