如何在JavaFX独立应用程序中将启动画面创建为预加载器?

时间:2015-08-07 16:42:46

标签: javafx splash-screen preloader

我创建了一个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的新手,我不明白将主应用程序与独立应用程序中的预加载器连接的机制是什么。

3 个答案:

答案 0 :(得分:7)

您可以像这样使用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);
    }
}

答案 1 :(得分:2)

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

JavaFX-Preloader-Class: SplashScreenLoader

答案 2 :(得分:1)

可能为时已晚,这也可以帮助别人。 对我来说,我使用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);
};