I'm trying to add concurrency using JavaFX. After doing some reading I think that javafx.concurrent.Task
is what I want.
I would like to be able to update my scene from the thread. When I have this:
private void login() {
Task<Void> task = new Task<Void>(){
@Override
protected Void call() throws Exception {
Platform.runLater(new Runnable() {
@Override
public void run() {
System.out.println("Hello");
actiontarget.setText("logging in");
// login code
});
return null;
}
};
Thread t = new Thread(task);
t.setDaemon(true);
t.start();
}
The screen lags login code because it is extensive in what it checks. This would be an issue but the login screen also has some animations, so those lag and it looks tacky.
Instead of the above code I have tried this:
private void login() {
Task<Void> task = new Task<Void>(){
@Override
protected Void call() throws Exception {
System.out.println("Hello");
actiontarget.setText("logging in");
// login code
return null;
}
};
Thread t = new Thread(task);
t.setDaemon(true);
t.start();
}
This does not lag the screen, however, the actiontarget never changes to logging in
in this case. The terminal still receives hello
, but it is as if the daemon thread does not have access to the actiontarget even though the compiler throws no errors.
When I dig deeper though, I find that the failed()
method is being called. Printing the exception yields java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-5
.
Searching further makes it seem as though it needs Platform.runLater
, but doing so causes lag once again. Is there a way around that?
Any help would be greatly appreciated.