我明白为什么
scene.setCursor(Cursor.WAIT);
long task...
scene.setCursor(Cursor.DEFAULT);
需要新线程;它适用于:
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);
为什么我不能使用相同的线程? I:
那么,我的长任务不会进入MAIN队列?因为,如果它进入主队列,我预计它会在我首先插入队列的WAIT游标之后执行。 为什么会出现这种情况?
答案 0 :(得分:7)
没有线程,您的代码正在FX应用程序线程上执行。这是(有效地)负责将UI呈现给屏幕并处理用户输入的线程。如果在此线程上执行长时间运行的任务,则会阻止FX应用程序线程的任何正常功能发生,直到长时间运行的任务完成。特别是,如果你这样做
scene.setCursor(Cursor.WAIT);
longRunningTask();
scene.setCursor(Cursor.DEFAULT);
然后按照您指定的顺序进行设置,但是在所有代码行完成之前,场景不会被重新呈现。因此,在代码完成之前,您永远不会看到对UI的任何更改 - 包括对光标的更改。下一次FX应用程序线程有机会渲染场景时,光标设置为Cursor.DEFAULT
,您永远不会看到等待光标。
多线程和JavaFX有两个基本规则(相同的规则通常适用于大多数UI工具包):
所以你的解决方案实际上并不正确,因为你违反了这两个规则。你应该
WAIT
DEFAULT
。您可以使用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();