有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在javaFx中在应用程序窗口之前制作加载场景?

我正在尝试在真正的应用程序窗口打开之前创建一个加载窗口。加载场景中有一个进度条,未确定

问题是,;progressbar在我执行程序时真正的窗口打开之前不工作

顺便说一下,我尝试了预加载类,但也不太有效

这是我的密码

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!"));
        }


    }


}

共 (2) 个答案

  1. # 1 楼答案

    你可以使用预加载。下面是一个例子。摘自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();
            }
        }    
    }
    
  2. # 2 楼答案

    至少我发现了;无论如何,在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;
        }
    
    }