【问题标题】:Delay between Preloader and Stage shown显示的预加载器和阶段之间的延迟
【发布时间】:2016-04-15 08:47:53
【问题描述】:

我有一个使用简单预加载器的程序,而 init() 方法创建主 gui。一切正常,但在 init() 方法完成并且预加载器消失后,在主阶段出现之前有一个明显的延迟。我说引人注目是因为它可能长达 7 秒,足以让用户感到困惑。

我尝试在start()方法中尽量少放:

public void start(Stage stage) {
    /*Scene*/
    scene = new Scene(root, 1200, 700);
    stage.setScene(scene);
    scene.setFill(null);

    /*Stage*/
    stage.initStyle(StageStyle.TRANSPARENT);
    stage.centerOnScreen();
    stage.show();

}

有没有办法减少/消除这种延迟?完全废弃预加载器并将其作为主程序中的一个阶段实现会更好吗?提前致谢。

编辑:

我接受了 Maverick283 的建议并实现了预加载器的淡出。仍然有一点延迟,所以我发送了最终通知(从主程序到预加载器)显示主阶段之后,它运行良好!

public void start(Stage stage) {
    /*Scene*/
    scene = new Scene(root, 1200, 700);
    stage.setScene(scene);
    scene.setFill(null);

    /*Stage*/
    stage.initStyle(StageStyle.TRANSPARENT);
    stage.centerOnScreen();
    stage.show();
    notifyPreloader(new Preloader.ProgressNotification(0.99));
}

【问题讨论】:

    标签: java javafx delay preloader


    【解决方案1】:

    来自Oracle

    预加载器在应用程序启动之前收到的最后一个状态更改通知是 StateChangeNotification.Type.BEFORE_START。处理完毕后,将调用应用程序的 start() 方法。但是,在调用 start() 方法后,应用程序准备好显示其阶段可能需要一些时间。如果预加载器阶段已经隐藏,则可能有一段时间应用程序在屏幕上不显示任何内容。

    因此,他们提供了如何解决该问题的示例代码:

    @Override
    public void handleStateChangeNotification(StateChangeNotification evt) {
        if (evt.getType() == StateChangeNotification.Type.BEFORE_START) {
            if (isEmbedded && stage.isShowing()) {
                //fade out, hide stage at the end of animation
                FadeTransition ft = new FadeTransition(
                    Duration.millis(1000), stage.getScene().getRoot());
                    ft.setFromValue(1.0);
                    ft.setToValue(0.0);
                    final Stage s = stage;
                    EventHandler<ActionEvent> eh = new EventHandler<ActionEvent>() {
                        public void handle(ActionEvent t) {
                            s.hide();
                        }
                    };
                    ft.setOnFinished(eh);
                    ft.play();
            } else {
                stage.hide();
            }
        }
    }
    

    如果您继续阅读,甚至可以共享两个阶段(预加载器和主应用程序阶段)...

    【讨论】:

      【解决方案2】:

      我尝试了之前显示的解决方案但没有成功,然后我编写了一个对我有用的代码,我所做的是让预加载器不会自己隐藏,它只是在显示主应用程序时被隐藏,看:

      预加载:

      我评论了 stage.hide();

      @Override
      public void handleStateChangeNotification(StateChangeNotification scn) {
          if (scn.getType() == StateChangeNotification.Type.BEFORE_INIT) {
             //stage.hide();
          }
      }
      

      我将舞台设置为静态

      static Stage stage;
      

      我添加了这段代码:

      public static Stage getStage() {
          return stage;
      }
      

      在主应用上:

      @Override
      public void start(Stage stage) throws IOException {
      
          scene = new Scene(loadFXML("fxmlLoginGUI.fxml"), 640, 480);
      
          stage.setScene(scene);
          stage.show();
          if (stage.showingProperty().get()) {
              try {
                  UkhuluvelaERP_Preloader.getStage().hide();
              } catch (Exception ex) {
                  Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
              }
          }
      }
      

      我检查阶段是否已经显示,然后我使用 get 方法将预加载阶段设置为 hide()。

      我希望这对你们有用,对我也有用。祝你好运。雪儿

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-04
        • 2013-05-07
        • 1970-01-01
        相关资源
        最近更新 更多