I'm developing a JavaFX application that requires resources to be loaded in from a file before the main Application stage can be launched. My solution to accomplish this task is to use a PreLoader so that the user can't interact with the application until the resources have been loaded (pretty standard stuff).
I have a class extending the PreLoader class that creates an object that loads a .fxml file which is what the PreLoader scene will display. It works all nice and dandy until I try to insert code to load the files.
I want to do this concurrently so that during the loading of the files the status gets updated to the screen. I've looked into using tasks and the forums on here but none help as I don't know where to put code where.
Class extending PreLoader:
public class SplashPreLoader extends Preloader {
private Stage stage;
private SplashScene loadScreen;
public void start(Stage stage) throws Exception {
SplashScene intro = new SplashScene();
this.loadScreen = intro;
this.stage = stage;
stage.setScene(new Scene(intro, 475, 425));
stage.initStyle(StageStyle.UNDECORATED);
stage.show();
}
@Override
public void handleProgressNotification(ProgressNotification pn) {
//bar.setProgress(pn.getProgress());
}
@Override
public void handleStateChangeNotification(StateChangeNotification evt) {
if (evt.getType() == StateChangeNotification.Type.BEFORE_LOAD) {
//loadScreen.setStatusMessage("Hello Mister");
}
if (evt.getType() == StateChangeNotification.Type.BEFORE_START) {
/* Task<Void> task = new Task<Void>() {
@Override
public Void call() {
updateMessage("this mesashlkjfhkjlsd");
return null ;
}
};
statusMessage.textProperty().bind(task.messageProperty());
task.messageProperty().addListener((obs, oldMessage, newMessage) -> loadScreen.setStatusMessage(newMessage));
Thread th = new Thread(task);
th.setDaemon(true);
th.start();*/
//loadScreen.loadWebDriver();
stage.hide();
}
}
Scene component:
public class SplashScene extends StackPane {
@FXML public Label statusMessage;
public SplashScene() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("splash_scene.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
//statusMessage.setTextFill(Color.WHITE);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
public String getStatusMessage() { return statusMessageProperty().getValue(); }
public void setStatusMessage(String value) {
statusMessageProperty().set(value);
System.out.println("at hert");
}
public StringProperty statusMessageProperty() { return statusMessage.textProperty(); }
public void loadWebDriver() {
//This is the function that I want to call to load all the files.
}
statusMessage
is the Label that I want to modify as the files are being loaded. I've tried putting the task (thread) in the loadWebDriver()
function, at the end of the start()
and in the preceeding if clause but it is not producing the results I want.
I find it strange too because when I tried this without the task
, I had the label change code before the file loading code but they were always executed in the opposite order.
I feel like this could help from the documentation but it doesn't mean anything to me.. Anyone know what this means?
Note that preloaders are subject to the same rules as other JavaFX applications including FX threading rules. In particular, the class constructor and init() method will be called on a non-FX thread and start() will be executed on the FX application thread. This also means that the application constructor/init() will run concurrently with preloader start().
Do I need to utilize the init() method?