I am trying to create a custom alert that will display a message to the user until it finishes with the task (doOperation()) and then I will close the custom made alert and continue the process. But it does not work properly. It blocks the Fx thread but does not display the stage on the screen and then closes immediately. Anything I am missing in the code below?
class MyClass{
void doOperation(){
//fetch data from DB. Nothing fancy. Simply getting data from jdbc and processes the data which may take a few secs.
}
void fetchProcessData(){
Stage customStage = new Stage();
GridPane stageGrid = new GridPane();
stageGrid.setAlignment(Pos.CENTER);
stageGrid.setHgap(10);
stageGrid.setVgap(10);
Label contextLabel = new Label("Wait...");
stageGrid.add(contextLabel, 0, 1);
Scene scene = new Scene(stageGrid, 300, 150);
customStage.setScene(scene);
customStage.setTitle(title);
customStage.initStyle(stageStyle);
customStage.initModality(modality);
customStage.show();
try {
doOperation();
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
customStage.close();
}
}
You need to execute the longrunning operation on a background thread and do the update when the operation is completed.
The simplest approach would be to use Platform.runLater
for this:
customStage.show();
new Thread(new Runnable() {
@Override
public void run() {
try {
doOperation();
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// close stage on javafx application thread
Platform.runLater(new Runnable() {
@Override
public void run() {
customStage.close();
}
});
}
}).start();
The Task
class provides some funtionality to do intermediate updates on the javafx application thread and allows you to register handlers that handle different outcomes on this thread.