【问题标题】:How to create splash screen as a Preloader in JavaFX standalone application?如何在 JavaFX 独立应用程序中创建启动画面作为预加载器?
【发布时间】:2015-08-07 16:42:46
【问题描述】:

我创建了一个 Preloader(基于以下教程),它应该显示主应用程序的启动屏幕。

9.3.4 使用预加载器显示应用程序初始化进度 http://docs.oracle.com/javafx/2/deployment/preloaders.htm

public class SplashScreenLoader extends Preloader {

    private Stage splashScreen;

    @Override
    public void start(Stage stage) throws Exception {
        splashScreen = stage;
        splashScreen.setScene(createScene());
        splashScreen.show();
    }

    public Scene createScene() {
        StackPane root = new StackPane();
        Scene scene = new Scene(root, 300, 200);
        return scene;
    }

    @Override
    public void handleApplicationNotification(PreloaderNotification notification) {
        if (notification instanceof StateChangeNotification) {
            splashScreen.hide();
        }
    }

}

每次在我的 IDE (IntelliJ IDEA) 中运行主应用程序时,我都想运行预加载器。

我还遵循了 IntelliJ 中预加载器的打包规则: https://www.jetbrains.com/idea/help/applications-with-a-preloader-project-organization-and-packaging.html

当我运行主应用程序时,预加载器没有启动,所以我想我错过了一些东西。我是 Preloaders 的新手,我不明白在独立应用程序中将主应用程序与预加载器连接的机制是什么。

【问题讨论】:

    标签: javafx splash-screen preloader


    【解决方案1】:

    您可以像这样使用LauncherImpl 运行。 . .

    public class Main {
       public static void main(String[] args) {
          LauncherImpl.launchApplication(MyApplication.class, SplashScreenLoader.class, args);
       }
    }
    

    MyApplication 的类会是这样的。 . .

    public class MyApplication extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            ....
            primaryStage.show();
        }
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    【讨论】:

    • 系统属性 javafx.preloader=classname 似乎也可以工作
    • 对于 Java 9,LauncherImpl 不再是公开可用的类,请使用 pranahata 提示的 javafx.preloader=classname 属性。请参阅:Java 9 JavaFX Preloader
    【解决方案2】:

    IDE 还不能很好地添加预加载器。查看程序 jar 文件中的 Manifest 并确保存在这一行:

    JavaFX-Preloader-Class: SplashScreenLoader
    

    【讨论】:

      【解决方案3】:

      可能为时已晚,这也可以帮助某人。 对我来说,我使用 JavaFX 服务和任务在 JavaFX 独立应用程序中创建启动画面作为预加载器。这是因为我的项目的上下文。

      创建 AnchorPane 和进度窗格

      @FXML
      private AnchorPane anchorPane;
      private MaskerPane progressPane;
      
      
      public static void main(String[] args) {
          launch(args);
      }
      
          @Override
      public void init() throws Exception {
          progressPane = new MaskerPane();
          progressPane.setText(bundle.getString("root.pleaseWait"));
          progressPane.setVisible(false);
          AnchorPane.setLeftAnchor(progressPane, 0.0);
          AnchorPane.setTopAnchor(progressPane, 0.0);
          AnchorPane.setRightAnchor(progressPane, 0.0);
          AnchorPane.setBottomAnchor(progressPane, 0.0);
          anchorPane.getChildren().add(progressPane);
      }
      
      @Override
      public void start(Stage initStage) {
        //.....
          initRoot();
       //.....
      
      }
      

      这样创建启动画面服务:

      private final Service<Void> splashService = new Service<Void>() {
          @Override
          protected Task<Void> createTask() {
              return new Task<Void>() {
                  @Override
                  public Void call() throws Exception {
                      //main code, the code who take time
                      //or
                      //Thread.sleep(10000);
                      return null;
                  }
              };
          }
      };
      

      在加载主屏幕时启动服务并在 initRoot 上显示/隐藏 progressPane:

         public void initRoot() {
          try {
              //....
      
              splashService.restart();
              //On succeeded, do this
              splashService.setOnRunning(new EventHandler<WorkerStateEvent>() {
                  @Override
                  public void handle(WorkerStateEvent event) {
                      //Show mask on succeed
                      showMask(Boolean.TRUE);
                  }
              });
              splashService.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
                  @Override
                  public void handle(WorkerStateEvent event) {
                      splashService.cancel();
                       //Hide mask on succeed
                      showMask(Boolean.FALSE);
                  }
                  });    
                  //.....
                  primaryStage.show();
              } catch (IOException ex) {
                  ex.printStackTrace();
              }
          }
      

      显示/隐藏进度...

      showMask(boolean value){
              progressPane.setVisible(value);
      };
      

      【讨论】:

        猜你喜欢
        • 2021-01-20
        • 1970-01-01
        • 1970-01-01
        • 2014-11-05
        • 2018-02-11
        • 1970-01-01
        • 1970-01-01
        • 2011-10-25
        • 1970-01-01
        相关资源
        最近更新 更多