Search code examples
javajavafxjavafx-8splash-screen

JavaFX : Use an Indeterminate Progressbar in a splashScreen


I have a splash screen :

splash screen I need to have the animation of the progress bar (Indeterminate) but it doesn't work.

It's maybe due to because my thread is running in my initilize methode.

public class splashscreenController implements Initializable {
  @Override
  public void initialize(URL location, ResourceBundle resources) {
    new SplashScreen().run();
  }

  class SplashScreen extends Task {
    @Override
    public Object call() {

        Platform.runLater(new Runnable() {
            @Override
            public void run()
                Parent root = null;
                try {
                    Thread.sleep(3000);
                    root = FXMLLoader.load(getClass().getResource("../gui/NewUI.fxml"));
                } catch (InterruptedException | IOException e) {
                    e.printStackTrace();
                }
                Stage stage = new Stage();
                stage.initStyle(StageStyle.UNDECORATED);

                assert root != null;
                Scene scene = new Scene(root, 1280, 720);
                stage.setScene(scene);
                stage.show();
                MainJavaFx.setPrimaryStage(stage);
                ((Stage) panParent.getScene().getWindow()).close();
            }
        });
        return null;
    }
  }
}

Solution

  • There are 2 issues in your code:

    new SplashScreen().run();
    

    A Task does not provide functionality for running on a new thread. run is executed on the calling thread.

    class SplashScreen extends Task {
        @Override
        public Object call() {
    
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    // placeholder for parts of your code
                    longRunningOperation();
                    guiUpdate();
                }
            });
            return null;
        }
    }
    

    Even if you execute this task on a seperate thread, the Runnable passed to Platfrom.runLater is executed on the JavaFX application thread and doing long-running operations from this runnable freezes the GUI.

    Do all the long-running operations on the background thread instead and only do short updates using Platfrom.runLater.

    new Thread(new SplashScreen()).start();
    
    class SplashScreen extends Task {
        @Override
        public Object call() throws IOException, InterruptedException {
            Thread.sleep(3000);
            final Parent root = FXMLLoader.load(getClass().getResource("../gui/NewUI.fxml"));
    
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    Stage stage = new Stage();
                    stage.initStyle(StageStyle.UNDECORATED);
    
                    Scene scene = new Scene(root, 1280, 720);
                    stage.setScene(scene);
                    stage.show();
                    MainJavaFx.setPrimaryStage(stage);
                    ((Stage) panParent.getScene().getWindow()).close();
                }
            });
            return null;
        }
    }
    

    Note that since you're not using the functionality provided by Task, you could simply implement Runnable with your class instead of inheriting from Task.