I have a simple app which updates the data in the background and while it updates, it disables all the other buttons and enables a TextArea to show the progress.
Steps:
Disable all the other buttons in the mainUI (Button name: plotButton)
Enable a TextArea showing that the updating has started (TextArea name: infoLogTextArea)
Then only start the update method (update() throws Exceptions).
Here is the code:
@FXML
public void handleUpdateButton() {
infoLogTextArea.setVisible(true);
infoLogTextArea.appendText("Please wait while downloading data from internet.....\n");
plotButton.setDisable(true);
updateButton.setDisable(true);
if(c!=null) {
Runnable task = new Runnable() {
@Override
public void run() {
// Thread.sleep(10000); -> sleep for 10secs
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
c.updateData();
infoLogTextArea.appendText(c.getErrorLog().toString());
plotLabel.setText(c.getCityData().size()+" cities found and updated from internet");
infoLogTextArea.appendText("Successfully updated the data from Internet\n");
}catch (IOException e) {
infoLogTextArea.setText("Couldnot update the data from web: "+e.getMessage()+"\n");
}
finally {
plotButton.setDisable(false);
updateButton.setDisable(false);
}
}
});
}
};
new Thread(task).start();
}else {
System.out.println("c not initialized");
}
}
Now the code works well but sometimes steps 1 and 2 are not executed and it starts step 3 (updating) which can freeze the program. If I put Thread.sleep(10 secs) in between step 2 and 3 then it works completely fine. (it is commented in the code)
But can anybody explain what is going on behind the scenes and why Platform.runLater()
doesn't work all the time?
c.updateData()
takes a long time, you should leave it outside therunLater
call. In other words - only wrap calls that actually change the UI inPlatform.runLater
. – Involucre