When does a JavaFX program call the start method?

java, javafx

Solution

`LauncherImpl` calls `Application#start`, but does so by placing the actuall call onto the JavaFX event queue via `PlatformImpl.runAndWait`. This is done after the `Preloader` is launched

`Application#launch` calls `LauncherImpl.launchApplication`, which creates a `Thread` and calls `launchApplication1`, `launchApplication` then waits for this `Thread` to terminate, via a `CountDownLatch`.

This `Thread` then calls `LauncherImpl.launchApplication1`, which launches the `Preloader`, if specified, then, based on a number decisions about the state of the `Preloader` calls `Application#start`, wrapped in a `runAndWait` call, to ensure that `start` is called within the context of the JavaFX's GUI/Event Queue thread...

This is based on Java 8

Updated...

`theApp.start`, called by `LauncherImpl.launcherApplication1` is the instance of your `Application`.

`Application` does a look up for your classes name, by walking a `StackTrace`...of all things...

StackTraceElement[] cause = Thread.currentThread().getStackTrace();

boolean foundThisMethod = false;
String callingClassName = null;
for (StackTraceElement se : cause) {
    // Skip entries until we get to the entry for this class
    String className = se.getClassName();
    String methodName = se.getMethodName();
    if (foundThisMethod) {
        callingClassName = className;
        break;
    } else if (Application.class.getName().equals(className)
            && "launch".equals(methodName)) {

        foundThisMethod = true;
    }
}

This gets the name of your class, it then creates a `Class` instance using `Class.forName` and passes this to `LauncherImpl`...

`launcherApplication1` then constructs a new instance of this class and assigns it to the reference `theApp`, which is an instance of your `Application`

PlatformImpl.runAndWait(new Runnable() {
        @Override public void run() {
            try {
                Constructor<? extends Application> c = appClass.getConstructor();
                app.set(c.newInstance());
                // Set startup parameters
                ParametersImpl.registerParameters(app.get(), new ParametersImpl(args));
                PlatformImpl.setApplicationName(appClass);
            } catch (Throwable t) {
                System.err.println("Exception in Application constructor");
                constructorError = t;
                error = true;
            }
        }
    });
}
final Application theApp = app.get();

It then proceeds to call `theApp.start`, which is calling your `Application`'s `start` method....I know weird, but there it is

Problem

I am learning JavaFX. And I can only see a launch(args) method in main method. When I a debug into the launch. I can't see any statement call the start().So when does the JavaFX program call the start method? This is the launch(args) source code. ``` public static void launch(String... args) { // Figure out the right class to call StackTraceElement[] cause = Thread.currentThread().getStackTrace(); boolean foundThisMethod = false; String callingClassName = null; for (StackTraceElement se : cause) { // Skip entries until we get to the entry for this class String className = se.getClassName(); String methodName = se.getMethodName(); if (foundThisMethod) { callingClassName = className; break; } else if (Application.class.getName().equals(className) && "launch".equals(methodName)) { foundThisMethod = true; } } if (callingClassName == null) { throw new RuntimeException("Error: unable to determine Application class"); } try { Class theClass = Class.forName(callingClassName, true, Thread.currentThread().getContextClassLoader()); if (Application.class.isAssignableFrom(theClass)) { Class<? extends Application> appClass = theClass; LauncherImpl.launchApplication(appClass, args); } else { throw new RuntimeException("Error: " + theClass + " is not a subclass of javafx.application.Application"); } } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { throw new RuntimeException(ex); } } ```

Original source