2

JavaFX 11 and Spring Boot 2.0.

I want to display a splash screen until Spring inits all of its necessary beans, and in the spring.run() I want to close the splash stage(or at least after x amount of seconds). Such that connecting to the DB creating POJOs etc. But when I try to show my splash screen before FX thread kicks in so it throws:

Caused by: java.lang.IllegalStateException: This operation is permitted on the event thread only; currentThread = main()

I even tried in the Platform.runLater() but still did not work out. Is there any work around for this problem? Thanks.

public class StartUp extends Application{
    public static void main(String[] args) {
        loadSplashScreen();
        appContext = SpringApplication.run(StartUp.class);
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        stage.setScene(new Scene(root, 300, 275));
        stage.show();
    }

    static void loadSplashScreen() {
        Stage splashStage = new Stage();
        try {
            BorderPane splashPane = FXMLLoader.load(getClass().getResource("splash.fxml"));
            Scene splashScene = new Scene(splashPane);
            splashStage.setScene(splashScene);
            splashStage.show();
            setFadeInOut(splashPane, splashStage);
        } catch (IOException e) {
            e.printStackTrace();
        }
}

    static void setFadeInOut(Parent splashScene, Stage splashStage) {
        FadeTransition fadeIn = new FadeTransition(Duration.seconds(3), splashScene);
        fadeIn.setFromValue(0);
        fadeIn.setToValue(1);
        fadeIn.setCycleCount(1);

        FadeTransition fadeOut = new FadeTransition(Duration.seconds(3), splashScene);
        fadeOut.setFromValue(1);
        fadeOut.setToValue(0);
        fadeOut.setCycleCount(1);
        fadeIn.play();

        fadeIn.setOnFinished((e) -> fadeOut.play());
        fadeOut.setOnFinished((e) -> splashStage.close());
    }
}
Slaw
  • 37,820
  • 8
  • 53
  • 80
Akansha
  • 45
  • 1
  • 6
  • Have you considered using a [`Preloader`](https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Preloader.html)? See [this answer](https://stackoverflow.com/a/15148611/6395627). A `Preloader` is part of the JavaFX life-cycle so you won't be able to show it "before FX thread kicks in". However, I'm not familiar with Spring Boot but if you can bootstrap it from the `Application.init` method it may fit nicely with `Preloader`. – Slaw Jan 03 '19 at 04:51
  • you already have the solution? – EsopMx Feb 20 '19 at 06:25

1 Answers1

0

In your code you have a method called loadSplashScreen() which you call before the Application.launch(). It will be the call to the launch method that starts the JavaFX thread which is why your loadSplashScreen() method fails i.e. the JavaFX thread hasn't even started when this method is called.

You might want to take a look here at this Oracle tutorial on PreLoaders to understand how to understand a basic example before you try work with starting JavaFX with Spring Boot.

Although I haven't booted JavaFX from Spring Boot, I have done similar in an OSGi bundle and you might like to take a look at my FlexFx GitHub repo here which might give you a few pointers on how to use a pre-loader with Spring Boot but note I currently do not have the ability to display a splash screen in my project.

Finally, your issue would happen on JavaFX-8, 9 or 10. It's not specific to JavaFX-11.

D-Dᴙum
  • 7,689
  • 8
  • 58
  • 97
  • Thanks for the suggestion. But PreLoaders does not work in this matter. If I find out a solution I will post here. – Akansha Jan 04 '19 at 19:52
  • 1
    @Akansha, what did you try with the Preloader? It should work fine. Instead of initializing Spring Boot in the main() method, you'd do it in the Application init() method. You can also look at this GitHub repo that shows Spring Boot + Preloader: https://github.com/thomasdarimont/spring-labs/tree/master/spring-boot-javafx – Ted M. Young Jan 04 '19 at 20:17
  • @Akansha If you don't want to use a preloader then the only other way is to do make a splash screen yourself as if it were a regular scene object and handle the creation and destruction of it yourself but you _still_ must do it on the JavaFX thread i.e. all of the above still applies. – D-Dᴙum Jan 05 '19 at 09:07
  • @ted-m-young, that suggestion worked. Created a preloader and placed spring run into init(). Thanks – Akansha Jan 12 '19 at 03:04