11

I created a Preloader (based on the following tutorial) that should display a splash screen for the main application.

9.3.4 Using a Preloader to Display the Application Initialization Progress 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();
        }
    }

}

I'd like to run preloader each time I run the main application in my IDE (IntelliJ IDEA).

I also followed the packaging rules for preloaders in IntelliJ: https://www.jetbrains.com/idea/help/applications-with-a-preloader-project-organization-and-packaging.html

When I run the main application the preloader doesn't start, so I suppose I'm missing something. I'm new to Preloaders and I don't understand what is the mechanism to connect the main app with the preloader in standalone application.

krsi
  • 1,045
  • 2
  • 14
  • 24
  • Does this answer your question? [How to create a custom loading screen in JavaFX?](https://stackoverflow.com/questions/361225/how-to-create-a-custom-loading-screen-in-javafx) – Remzi Cavdar Nov 01 '22 at 17:00

3 Answers3

8

You can run using LauncherImpl like this . . .

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

And the class MyApplication would be like this . . .

public class MyApplication extends Application {

    @Override
    public void start(Stage primaryStage) {
        ....
        primaryStage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}
Ye Kyaw Kyaw Htoo
  • 702
  • 2
  • 9
  • 22
  • 1
    system property javafx.preloader=classname seems to work too – pranahata Sep 08 '16 at 09:40
  • 3
    For Java 9, where `LauncherImpl` is no longer a publicly available class, use the `javafx.preloader=classname` property hinted by pranahata. See: [Java 9 JavaFX Preloader](https://stackoverflow.com/questions/47533370/java-9-javafx-preloader/47540060#47540060). – jewelsea Nov 28 '17 at 20:12
2

The IDEs aren't great at adding preloaders yet. Take a look at the Manifest in your program's jar file and make sure this line is present:

JavaFX-Preloader-Class: SplashScreenLoader
corpico
  • 617
  • 3
  • 16
  • 26
2

May be too late, this can also help somebody. For me, i used JavaFX service and task to create splash screen as a Preloader in JavaFX standalone application. This, because the contexte of my project.

Create the AnchorPane and the progress Pane

@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();
 //.....

}

Create the splash screen service as this:

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

Start service and show/hide the progressPane on initRoot when loading the main screen:

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

To show/hide the progress...

showMask(boolean value){
        progressPane.setVisible(value);
};
Anatole ABE
  • 575
  • 1
  • 7
  • 12