Tryphon
Tryphon

Reputation: 161

How does JavaFX start exactly

I've just written a JavaFX application and realized I don't really understand how it actually starts up.

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

This is the template given to me in Intellij. My entry point would be main where the only thing that gets run is launch(args). I've tried digging in the Application class but didn't find anything that would point towards running the start method. How is this even launched? Since JavaFX has it's own thread I'm assuming a thread gets created in the launch method and the main thread doesn't return from launch until you call Platform.exit or just close all windows. This all feels just a bit too abstract to me right now. Can someone explain to me how it all fits together?

Upvotes: 4

Views: 3719

Answers (2)

Hugues M.
Hugues M.

Reputation: 20467

Below is what your main application class must look like. I named it "HelloApp" because I needed a name. I also changed launch with Application.launch, it's the same but less confusing (see explanations below).

Please note however (thanks @Cypher in comments for bringing this up) that java does not need the good old public static void main(String[] args) method to run a JavaFX application.
If you omit the main method from below, compile it, and run it with java HelloApp, it will work, and might be slightly less confusing :)
You can still handle command line arguments without main, as they are passed to the parameters object, which you can obtain from within your Application with getParameters().

My IDE also allows to run an Application without main, and apparently most do.

That being said, let's see what happens here in your case:

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() invokes launch()
  • launch is a static method in Application class that you extends, so you can use launch() directly but when calling static methods it's recommended to use the class name, so I replaced above with Application.launch. Some IDEs and linters warn you with "java static method should be accessed in a static way" if you don't do that.
  • Within the launch method, the JavaFX runtime (below "JavaFX") figures out which class is the caller (by using Thread.currentThread().getStackTrace(), but that's just an interesting implementation detail). That caller class is expected to be a javafx.application.Application
    -- When running without main, the above is irrelevant, and JavaFX starts about here. --
  • JavaFX creates an application thread for running the application start method, processing input events, and running animation timelines.
  • JavaFX constructs an instance of the specified Application class
  • JavaFX calls init() (which you can override)
  • JavaFX calls start() (which you must implement yourself), from the "JavaFX Application Thread"

The rest of the lifecycle is described in Application javadoc -- subsequent steps are waiting for application to finish (either app calls Platform.exit(), or last window has been closed and implicitExit is true), then JavaFX calls stop() (which you can override).

Upvotes: 3

Luciano van der Veekens
Luciano van der Veekens

Reputation: 6577

The start() method of a JavaFX application is called via this call stack:

  • Application#launch:252
  • LauncherImpl#launchApplication:143
  • LauncherImpl#launchApplication:182
  • LauncherImpl#launchApplication1:863
  • Application#start (overridden by your application)

Upvotes: 2

Related Questions