JavaFX在运行时会创建多个线程。在不同阶段,各个线程用来执行不同的任务。有两个线程需要我们掌握:
这两个线程在程序运行时,会依次调用 JavaFX Application类的以下四个方法:
为了理解上面四个方法和两个线程之间的关系。我们来看以下这段代码:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class FXLifeCycleApp extends Application {
public FXLifeCycleApp() {
String name = Thread.currentThread().getName();
System.out.println("FXLifeCycleApp() constructor: " + name);
}
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void init() {
String name = Thread.currentThread().getName();
System.out.println("init() method: " + name);
}
@Override
public void start(Stage stage) {
String name = Thread.currentThread().getName();
System.out.println("start() method: " + name);
Scene scene = new Scene(new Group(), 200, 200);
stage.setScene(scene);
stage.setTitle("JavaFX Application Life Cycle");
stage.show();
}
@Override
public void stop() {
String name = Thread.currentThread().getName();
System.out.println("stop() method: " + name);
}
}
在关闭窗体前,控制台输出结果为:
FXLifeCycleApp() constructor: JavaFX Application Thread
init() method: JavaFX-Launcher
start() method: JavaFX Application Thread
从上面输出我们可以看到,一个JavaFX Application在运行时会依次调用no-args constructor, init() ,start() 这三个方法。并且no-args constructor与start()是在JavaFX Application Thread线程中被调用。而init()方法是在JavaFX-Launcher线程中被调用。
在点击关闭窗体后,控制台输出结果变为:
FXLifeCycleApp() constructor: JavaFX Application Thread
init() method: JavaFX-Launcher
start() method: JavaFX Application Thread
stop() method: JavaFX Application Thread
这说明stop() 方法是在窗体关闭时被JavaFX Application Thread调用。
通常,我在编写桌面应用时,用init() 来作一些数据初始化的工作,在start()方法中实现窗体。
JavaFX Application的终止可以分为显式终止和隐式终止。
显示终止通过调用Platform.exit() 来实现。当使用Platform.exit()时,实际是调用了stop() 方法来终止运行。Platform.exit()的调用位置可以是在start()中。如果在无参构造方法中或者init()方法中调用Platform.exit(),将不起作用。
修改上面代码,,使窗体出现两秒以后,自动关闭:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class FXLifeCycleApp extends Application {
public FXLifeCycleApp() {
String name = Thread.currentThread().getName();
System.out.println("FXLifeCycleApp() constructor: " + name);
}
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void init() {
String name = Thread.currentThread().getName();
System.out.println("init() method: " + name);
}
@Override
public void start(Stage stage) {
String name = Thread.currentThread().getName();
System.out.println("start() method: " + name);
Scene scene = new Scene(new Group(), 200, 200);
stage.setScene(scene);
stage.setTitle("JavaFX Application Life Cycle");
stage.show();
//延迟2秒后关闭窗体
try{
Thread.sleep(2000);
Platform.exit();
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void stop() {
String name = Thread.currentThread().getName();
System.out.println("stop() method: " + name);
}
}
隐式终止是指关闭窗体时,stop()方法被自动调用。上一小节正是这种情况。 在JavaFX中可以通过setImplicitExit(boolean implicitExit)方法来设置隐式终止的开启与关闭。当该方法的参数为True时,隐式终止开启。为False时,隐式终止关闭,此时即使关闭窗体,JavaFX Application Thread仍未终止;此时你需要调用Platform.exit()方法来终止JavaFX Application Thread。