如何在 javaFx 中的应用程序 window 之前制作加载场景?

How to make Loading Scene before application window in javaFx?

我正在尝试在实际应用程序 window 打开之前创建加载 window。 loading场景有progressBar,不确定。

问题在于;在我执行程序时真正的 window 打开之前,进度条不起作用。

顺便说一下,我尝试了预加载器 class,但也不起作用。

这是我的代码;

public class MainApp2 extends Application {


    private Stage loadingStage = new Stage();

    public static void main(String[] args) {
        launch(args);
    }


    public void start(final Stage mainStage) throws Exception {

        //loading..
        loadingScreen();

        //start...
        appScreen();

    }


    private void loadingScreen() {

        ProgressBar bar = new ProgressBar(ProgressIndicator.INDETERMINATE_PROGRESS);
        bar.setPrefWidth(300);
        bar.setPrefHeight(200);

        loadingStage.initStyle(StageStyle.TRANSPARENT);
        loadingStage.initStyle(StageStyle.UNDECORATED);
        loadingStage.setScene(new Scene(bar));
        loadingStage.show();

    }


    private void appScreen() {

        new Task<Void>() {
            @Override
            protected Void call() throws Exception {

                Stage mainStage = new Stage();

                //get real window
                Scene root = new Scene(new MyAppWindow().getAppWindow());
                mainStage.setScene(root);
                mainStage.centerOnScreen();
                mainStage.show();

//                loadingStage.close();

                return null;
            }
        }.run();

    }

    public class MyAppWindow {

        public BorderPane getAppWindow(){

            System.out.println("may be initialize take a long time...");
            for (int i = 0; i < 90000000; i++) {
                System.out.print("");
            }

            return new BorderPane(new Label("Here is real application Window!"));
        }


    }


}

您可以使用预加载器。这是一个例子。摘自 source

public class FirstPreloader extends Preloader {
    ProgressBar bar;
    Stage stage;

    private Scene createPreloaderScene() {
        bar = new ProgressBar();
        BorderPane p = new BorderPane();
        p.setCenter(bar);
        return new Scene(p, 300, 150);        
    }

    public void start(Stage stage) throws Exception {
        this.stage = stage;
        stage.setScene(createPreloaderScene());        
        stage.show();
    }

    @Override
    public void handleProgressNotification(ProgressNotification pn) {
        bar.setProgress(pn.getProgress());
    }

    @Override
    public void handleStateChangeNotification(StateChangeNotification evt) {
        if (evt.getType() == StateChangeNotification.Type.BEFORE_START) {
            stage.hide();
        }
    }    
}

至少我发现了;无论如何都无法在 JavaFx 中初始化启动画面。因为 JavaFx 是由一个线程管理的。所以我尝试了这一步。它对我有用。

public void initAppScreen(final Stage mainStage) {

        loadingWindow = new LoadingWindow().getInitWindow();

        applicationContext = new ClassPathXmlApplicationContext("hibernate-config.xml");

        initSample();

        Platform.runLater(new Runnable() {
            public void run() {

                Scene root = new Scene(new AppWindow().getAppWindow());
                mainStage.setScene(root);

                mainStage.setTitle("My Application Title");
                mainStage.getIcons().add(new Image("/images/logo.png"));
                mainStage.setOnCloseRequest(event -> System.exit(0));

                mainStage.setWidth(APP_WINDOW_WIDTH);
                mainStage.setHeight(APP_WINDOW_HEIGHT);
                mainStage.setMinWidth(APP_WINDOW_WIDTH);
                mainStage.setMinHeight(APP_WINDOW_HEIGHT);

                Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
                mainStage.setX((screenBounds.getWidth() - APP_WINDOW_WIDTH) / 2);
                mainStage.setY((screenBounds.getHeight() - APP_WINDOW_HEIGHT) / 2);

                mainStage.show();
                loadingWindow.dispose();
            }
        });

    }

还有我的闪屏

public class LoadingWindow {


    public JFrame getInitWindow() {

        JFrame loadingFrame = new JFrame();

        URL url = this.getClass().getResource("/images/loading.gif");
        Icon icon = new ImageIcon(url);
        JLabel label = new JLabel(icon);

        loadingFrame.setIconImage(new ImageIcon(getClass().getResource("/images/logo.png").getPath()).getImage());
        loadingFrame.setUndecorated(true);
        loadingFrame.setBackground(new Color(0f, 0f, 0f, 0f));

        Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
        loadingFrame.setLocation((int) ((screenBounds.getWidth() - 600) / 2), (int) ((screenBounds.getHeight() - 0) / 2));

        loadingFrame.getContentPane().add(label);
        loadingFrame.pack();
        loadingFrame.setLocationRelativeTo(null);
        loadingFrame.setVisible(true);

        return loadingFrame;
    }

}