的Application
类表示整个应用程序,其start(...)
方法是在应用程序启动(你真的应该想start(...)
法作为main(...)
方法在传统的Java应用程序的等效)的方法。你的问题似乎意味着你认为Application
类代表一个窗口; Stage
类代表一个窗口。但是,据我所知,您的应用程序无论如何都只需要一个窗口。
当你调用Application.launch()
(或Java中8只执行JVM指定Application
子类作为主类),外汇工具包创建您的Application
类本身的实例,启动FX工具包和FX应用程序线程,以及调用在Application
实例上的start(...)
方法,传入Stage
。你应该永远不要实例化你自己的Application
子类;如果你这样做,你将会有一个与start(...)
方法被调用的实例不同的实例。
与几乎所有的UI工具包一样,JavaFX是单线程的。必须在JavaFX应用程序线程上执行“活动”场景图元素上的所有操作。您当然可以拥有后台线程,但是如果他们需要更新UI,他们应该通过调用Platform.runLater(...)
或利用javafx.concurrent
API来安排FX应用程序线程上的更新。 (短语“在自己的线程中有一个JavaFX Window对象”对我来说甚至没有意义,线程没有对象,堆中存在对象,线程只是独立序列的可执行语句的抽象。
所以,如果你想有一个JavaFX应用程序有一个后台线程,在一个图像视图定期更新的形象,你可以做这样的事情:
// imports omitted
public class MyImageUpdatingApp extends Application {
@Override
public void start(Stage primaryStage) {
Label label = new Label("Main application");
BorderPane root = new BorderPane(label);
Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
startImageUpdateThread();
}
private void startImageUpdateThread() {
ImageView imageView = new ImageView();
BorderPane root = new BorderPane(imageView);
Scene scene = new Scene(root, 600, 400);
Stage imageViewWindow = new Stage()
imageViewWindow.setScene(scene);
imageViewWindow.show();
final int pause = 50 ;
Thread t = new Thread(() -> {
while (moreImagesToGet()) {
Image image = getNextImage() ;
Platform.runLater(() -> imageView.setImage(image));
try {
Thread.sleep(pause);
} catch (Exception exc) {
exc.printStackTrace();
break();
}
}
});
t.setDaemon(true); // this thread won't prevent application exit
t.setName("Image update thread");
t.start();
}
// ...
}
显然,可以因数startImageUpdateThread
代码为如果你想要的话,可以单独一堂
请注意,此答案仅用于演示线程生成映像和UI之间的关系。在现实生活中,您可能需要一些更复杂的代码才能充分发挥其性能;您不太可能可以快速生成并显示图像,因此您可能需要一个BlockingQueue<Image>
作为图像缓冲区,其中一个线程生成图像,一个线程消耗它们。
'start(...)'方法是您的应用程序应该启动的地方。 'Application.launch()'方法将为你创建一个你的'Application'子类的实例。如果你想要从应用程序的其他部分重用的类,它们不应该是'Application'的子类。您可能需要重新构建此应用程序。 –
你介意多解释一下吗?我无法完全理解JavaFX的概念。我怎样才能从我的主要应用程序分开(线程明智)窗口加载图像? – TomTom
你的问题并没有什么意义:像几乎所有的UI工具包一样,JavaFX是单线程的,所有UI元素都必须从FX应用程序线程访问。我将尝试展示我将如何编写您所描述的应用程序的结构。 –