初始化之前的javafx显示对话框
我想知道在调用主应用程序的初始化之前的javafx显示对话框,java,javafx-8,startup,launcher,preinit,Java,Javafx 8,Startup,Launcher,Preinit,我想知道在调用主应用程序的init方法之前显示对话框(Stage)的最佳方式。我不能在init方法中实现它,因为它不在JavaFX应用程序线程上运行,在start方法中实现它时,我会失去预加载程序的选项(只有在我正确理解它的情况下,它才存在于init阶段) 它应该类似于eclipse中的工作区选择器或lightroom中的目录选择器 我能想到的一个解决方案是创建两个程序,一个启动程序和一个主应用程序,但如果它可以在同一个应用程序中发生,我更喜欢它。如果只能这样做,如何使用与启动程序相同的Java
init
方法之前显示对话框(Stage)
的最佳方式。我不能在init方法中实现它,因为它不在JavaFX应用程序线程上运行,在start方法中实现它时,我会失去预加载程序的选项(只有在我正确理解它的情况下,它才存在于init阶段)
它应该类似于eclipse中的工作区选择器或lightroom中的目录选择器
我能想到的一个解决方案是创建两个程序,一个启动程序和一个主应用程序,但如果它可以在同一个应用程序中发生,我更喜欢它。如果只能这样做,如何使用与启动程序相同的Java版本启动主app.jar?(不能使用路径中配置的Java版本调用它,因为命令行/终端允许使用不同版本启动应用程序)
感谢您的建议。启动JavaFX应用程序是通过调用
Application.launch()
,其中调用launchempl\launchApplication
在launchApplication
中,调用私有方法launchApplication
时使用具有以下签名的preforerclass
参数:
public static void launchApplication(final Class<? extends Application> appClass,
final Class<? extends Preloader> preloaderClass,
final String[] args)
然后将其传递给启动应用程序
方法
完美无瑕代码>
尽情享受吧代码>
感谢您到目前为止的回复,但我实际上不明白应该如何做。我的意思是,对话框应该在主应用程序初始化之前出现(因此在预加载程序显示之前),因为该对话框中的用户操作应该为init方法设置一个重要变量,甚至取消整个启动。或者一个关于您想法的问题:当我应该将其放入预加载程序中时,如何让init方法等待用户输入继续初始化,并继续显示预加载程序的“启动屏幕”以及进度?但是您可以使用Stage对象吗?否,是,我有,但剩下的问题是,在用户做出选择之前,如何阻止主应用程序init()
方法运行?通过在主应用程序的start()
方法中实现用户选择、启动屏幕和加载,可以采用不同的方法,但会导致结构不那么干净。为什么需要这样做?init()
方法是FX应用程序生命周期初始化的一部分:在初始化完成之前,您很难期望运行应用程序的一部分。为什么不像往常一样只在start()
方法中显示对话框,然后在对话框关闭时,在显示主应用程序窗口之前执行您需要的任何处理?@James\u D我想这样做,因为代码在用户选择后会花费足够的时间进行预加载/启动屏幕,据我所知,预加载程序的生命周期在init()
方法期间,因此用户可能会在主应用程序阶段出现之前等待几秒钟,而看不到进度条。这意味着我不需要预加载程序,而是在start()
方法中打开一个无装饰对话框作为进度指示闪屏,直到可以显示主阶段?因此您可以使用预加载机制。虽然从start()
方法显示带有进度条的启动屏幕(imo)更容易,但在后台线程中执行任何需要花费大量时间的任务,并在完成任务后显示主屏幕。@James\u D是的,这将是我的简单选择,但我认为这不是最好的做法。如何使用预加载机制实现这一点?
public class MyPreloader extends Preloader {
private Stage preloaderStage;
@Override
public void start(Stage primaryStage) throws Exception {
this.preloaderStage = primaryStage;
VBox loading = new VBox(20);
loading.setMaxWidth(Region.USE_PREF_SIZE);
loading.setMaxHeight(Region.USE_PREF_SIZE);
loading.getChildren().add(new ProgressBar());
loading.getChildren().add(new Label("Please wait..."));
BorderPane root = new BorderPane(loading);
Scene scene = new Scene(root);
primaryStage.setWidth(800);
primaryStage.setHeight(600);
primaryStage.setScene(scene);
primaryStage.show();
}
@Override
public void handleStateChangeNotification(StateChangeNotification
stateChangeNotification) {
if (stateChangeNotification.getType() == Type.BEFORE_START) {
preloaderStage.hide();
}
}
}