I would understand why
scene.setCursor(Cursor.WAIT);
long task...
scene.setCursor(Cursor.DEFAULT);
needs new threads; it works with:
private void set_cursore_attesa(final Scene scene)
{
Runnable r=new Runnable() {
@Override
public void run() {
scene.setCursor(Cursor.WAIT);
}
};
Thread t=new Thread(r);
t.start();
}
private void set_cursore_normale(final Scene scene)
{
Runnable r=new Runnable() {
@Override
public void run() {
scene.setCursor(Cursor.DEFAULT);
}
};
Thread t=new Thread(r);
t.start();
}
in my function:
set_cursore_attesa(scene);
long task...
set_cursore_normale(scene);
why I can't use the same thread? I:
So, my long task doesn't go in MAIN queue? because, if it goes in main queue, I expected it's executed after my WAIT cursor that is inserted in queue first. Why this behavior?
Without the threads, your code is being executed on the FX Application Thread. This is the thread that is (effectively) responsible for rendering the UI to the screen and for processing user input. If you execute a long-running task on this thread, then you prevent any of the normal functionality of the FX Application Thread from occurring until your long-running task is complete. In particular, if you do
scene.setCursor(Cursor.WAIT);
longRunningTask();
scene.setCursor(Cursor.DEFAULT);
then the settings take place in the order you specify, but the scene does not get rerendered until all lines of code are complete. Hence you never actually see any changes to the UI - including the change to the cursor - until after your code is complete. The next time the FX Application Thread has an opportunity to render the scene, the cursor is set to Cursor.DEFAULT
, and you never see the wait cursor.
There are two basic rules for multithreading and JavaFX (and the same rules generally apply to most UI toolkits):
So your solution is not actually correct, because you violate both of those rules. You should
WAIT
on the FX Application ThreadDEFAULT
, on the FX Application Thread.You can do this using a Task
:
scene.setCursor(Cursor.WAIT);
Task<Void> task = new Task<Void>() {
@Override
public Void call() {
// long running task here...
return null ;
}
};
task.setOnSucceeded(e -> scene.setCursor(Cursor.DEFAULT));
new Thread(task).start();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With