Most JavaFX example code conflates the main
method with the Application
subclass, and in many cases even does the UI layout, etc., in the same class. There's not necessarily a reason to do this, and in the latter case it's not a particularly good design.
Assuming you separate concerns appropriately in your UI code, you might have a class like
public class MainUI {
private BorderPane root ;
public MainUI() {
root = new BorderPane();
// do layout, register event handlers, etc etc
}
public Pane getView() {
return root ;
}
}
Then if you want a standalone JavaFX application, you would do
public class JavaFxApp extends Application {
@Override
public void start(Stage stage) {
MainUI ui = new MainUI();
Scene scene = new Scene(ui.getView());
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
But this isn't the only place you can use the UI class. In JavaFX (as in most UI toolkits), you must create a new stage, and perform other UI tasks, on the UI thread (i.e. the FX Application Thread).
Additionally, in JavaFX you must explicitly start up the FX toolkit. In the code above, this is done by the Application.launch()
method.
JavaFX 9 introduced a Platform.startup(Runnable)
, which starts the FX toolkit and executes the supplied Runnable
on the FX Application Thread.
So, using JavaFX 9 and later, you can have code like
public class SomeApp {
public static void main(String[] args) {
// start FX toolkit
// Since we don't want it to exit when we close a window, set
// implicit exit to false:
Platform.startup(() -> Platform.setImplicitExit(false));
// do some other stuff...
// whenever you need to:
Platform.runLater(SomeApp::showStage);
// do other stuff...
}
private static void showStage() {
Scene scene = new Scene(new MainUI().getView());
Stage stage = new Stage();
stage.show();
}
}
Prior to JavaFX 9, you can still do this, but you need to launch a "blank" application:
public class FXStartup extends Application {
@Override
public void start(Stage ignored) {
// probably need this:
Platform.setImplicitExit(false);
}
}
Note that the launch()
method blocks until the toolkit exits, so your application needs to start it in another thread:
public class SomeApp {
public static void main(String[] args) {
// start FX toolkit
new Thread(() -> Application.launch(FXStartup.class, args)).start();
// do some other stuff...
// whenever you need to:
Platform.runLater(SomeApp::showStage);
// do other stuff...
}
private static void showStage() {
Scene scene = new Scene(new MainUI().getView());
Stage stage = new Stage();
stage.show();
}
}