我正在学习JavaFX.我只能在main方法中看到启动(args)方法.当我调试进入发布时.我看不到任何语句调用start().那么JavaFX程序何时调用start方法?这是launch(args)源代码.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
LauncherImpl调用Application#start,但是通过将actuall调用放到JavaFX事件队列中来实现PlatformImpl.runAndWait.这是在Preloader启动后完成的
Application#launch调用LauncherImpl.launchApplication,创建一个Thread和调用launchApplication1,launchApplication然后Thread通过a 等待终止CountDownLatch.
这Thread然后调用LauncherImpl.launchApplication1,它启动Preloader,如果指定,那么,根据有关的状态的数量决定Preloader的呼叫Application#start,包裹在一个runAndWait电话,以确保start在JavaFX的的GUI /事件队列线程的上下文中调用...
这基于Java 8
更新...
theApp.start,被称为LauncherImpl.launcherApplication1你的实例Application.
Application通过步行StackTrace...来查找你的课程名称......
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这将获取您的类的名称,然后Class使用它创建一个实例Class.forName并将其传递给LauncherImpl...
launcherApplication1然后构造此类的新实例并将其分配给引用theApp,该引用是您的实例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();
Run Code Online (Sandbox Code Playgroud)
然后它继续调用theApp.start,这是调用你Application的start方法....我知道很奇怪,但确实如此