When does a JavaFX program call the start method?


Question

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);
    }
}
1
3
5/19/2014 4:26:55 AM

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

7
5/19/2014 5:49:56 AM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon