Reputation: 161
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
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.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
main
, the above is irrelevant, and JavaFX
starts about here. --init()
(which you can override)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
Reputation: 6577
The start() method of a JavaFX application is called via this call stack:
Upvotes: 2