Как создать заставку в качестве загрузчика в автономном приложении JavaFX?

Я создал предварительный загрузчик (на основе следующего учебника), который должен отображать заставку для основного приложения.

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();
        }
    }

}

Я хотел бы запускать preloader каждый раз, когда я запускаю основное приложение в своей IDE (IntelliJ IDEA).

Я также следовал правилам упаковки для загрузчиков в IntelliJ: https://www.jetbrains.com/idea/help/applications-with-a-preloader-project-organization-and-packaging.html

когда я запускаю основное приложение, предварительный загрузчик не запускается, поэтому я полагаю, что что-то пропустил. Я новичок в Preloaders, и я не понимаю, каков механизм подключения основного приложения к preloader в автономном приложении.

3 ответов


вы можете запустить с помощью 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);
    }
}

IDEs еще не очень хороши при добавлении загрузчиков. Взгляните на манифест в jar-файл вашей программы и убедитесь, что эта строка:

JavaFX-Preloader-Class: SplashScreenLoader

может быть слишком поздно, это может помочь кому-то. Для меня я использовал сервис 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;
            }
        };
    }
};

запустить службу и показать / скрыть progressPane на initRoot при загрузке главного экрана:

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