Reputation: 1256
I just try to show a loading-animation while I access an ERP in my code like this:
protected void submit()
{
messageField.getStyleClass().add("smallLoading");
submitImpl();
messageField.getStyleClass().remove("smallLoading");
}
Sadly the animation is never shown... Just the result as before. I tried using Platform.runLater
, which yielded the same result. I also transfered the last 2 lines in a Thread, which worked (the animation was shown), but lead to the error "Not on FX application thread", when the Submitter tried to write to my message-field. When I passed the Thread to Platform.runLater
it did not show the animation... I googled a little bit, but could not find a solution. Maybe I'm missing something important...
I appreciate any help. Thank you!
Upvotes: 4
Views: 10008
Reputation: 44200
It seems like you don't really fully understand how the UI thread works.
The code you've posted is single-threaded. It all operates on the UI thread. You add a style class, do some work, then remove it. The problem is that this sequence of operations is effectively "atomic": the UI doesn't actually update anything until its all done. This is why you don't see the loading symbol change.
When you put all of this within runLater
the result is the same. It's still all on the UI thread. The only difference here is that rather than running the code now, you're deferring it until some point "later" (probably actually very soon).
When you try to put the last two lines in a separate thread, the issue is that you're trying to make UI changes on a non-UI thread. That's not allowed.
What you want to do is run everything on a non-UI thread, and push back the UI operations to the UI thread with runLater
. Something like this:
new Thread(() -> {
Platform.runLater(()-> messageField.getStyleClass().add("smallLoading"));
submitImpl();
Platform.runLater(()-> messageField.getStyleClass().remove("smallLoading"));
}).start();
Upvotes: 10