A.Dumas
A.Dumas

Reputation: 3267

JavaFX: Preloader stop after start before show of the Application

Given an JavaFX Application

public class App extends Application{
 @Override
    public void init() throws Exception {
        // Do some huge task 
     }
    @Override
    public void start(Stage primaryStage) {
    // even a bigger task 
    }
}

and a Preloader class

public class PreloadScreen extends Preloader {
// all the overwritten methods 
@Override
    public void handleStateChangeNotification(StateChangeNotification info) {
        // Handle state change notifications.
        StateChangeNotification.Type type = info.getType();
      if(type.equals(BEFORE_START))
     // hide the preloader 
    }
}

As I understand correctly the Preloader hides before the start() of the application. Consider this image as visualisation enter image description here Is it possible to add StateChangeNotification into the enum like BEFORE_SHOW I have a very intensive task that needs the stage of the start method in the application.

Upvotes: 3

Views: 821

Answers (1)

Eng.Fouad
Eng.Fouad

Reputation: 117597

Define a custom progress message:

public class ProgressMessage implements Preloader.PreloaderNotification
{
    public static final ProgressMessage SUCCESSFULLY_DONE = new ProgressMessage(true, false);
    public static final ProgressMessage FAILED = new ProgressMessage(false, true);

    // TODO: add a variable to hold the exception in case of failure.
    private double progress;
    private String message;
    private boolean done;
    private boolean failed;

    public ProgressMessage(double progress, String message)
    {
        this.progress = progress;
        this.message = message;
        this.done = false;
        this.failed = false;
    }

    private ProgressMessage(boolean done, boolean failed)
    {
        this.done = done;
        this.failed = failed;
    }

    public double getProgress(){return progress;}
    public String getMessage(){return message;}
    public boolean isDone(){return done;}
    public boolean isFailed(){return failed;}

    @Override
    public boolean equals(Object o)
    {
        if(this == o) return true;
        if(o == null || getClass() != o.getClass()) return false;
        ProgressMessage message1 = (ProgressMessage) o;
        return Double.compare(message1.progress, progress) == 0 &&
               done == message1.done && failed == message1.failed &&
               Objects.equals(message, message1.message);
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(progress, message, done, failed);
    }

    @Override
    public String toString()
    {
        return "ProgressMessage{" + "progress=" + progress + ", message='" +
               message + '\'' + ", done=" + done + ", failed=" + failed + '}';
    }
}

Inside the Preloader, override handleApplicationNotification(PreloaderNotification info):

@Override
public void handleApplicationNotification(PreloaderNotification info)
{
    ProgressMessage progressMessage = (ProgressMessage) info;

    if(progressMessage.isDone())
    {
        splashScreenStage.hide();
        LOGGER.info("The splash screen is closed");
    }
    else if(progressMessage.isFailed())
    {
        // TODO: receive the exception from the main application.
        // TODO: show error dialog here with exception details.
        LOGGER.error("Exiting the application due to an error during the startup!");
        splashScreenStage.hide();
        Platform.exit();
    }
    else
    {
        double progress = progressMessage.getProgress();
        String message = progressMessage.getMessage();

        LOGGER.info("New Progress: progress({}), message({})", progress, message);

        splashScreenController.setProgress(progress);
        splashScreenController.setProgressMessage(message);
    }
}

Now, from your main application you can invoke the following methods to notify the progress:

notifyPreloader(new ProgressMessage(0.5, "Downloading some data from the backend server")); // 0.5 = 50%
notifyPreloader(ProgressMessage.SUCCESSFULLY_DONE);
notifyPreloader(ProgressMessage.FAILED);

Upvotes: 3

Related Questions