JAVAFX:为什么等待游标需要一个新线程? [英] JAVAFX : why wait cursor needs a new thread?

查看:117
本文介绍了JAVAFX:为什么等待游标需要一个新线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我理解为什么

 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:


  1. 将我的光标设置为WAIT(它进入GUI队列)

  2. 做我的长任务......(它进入GUI队列,但我希望光标改变,即在队列中,它在此之前执行)

  3. 将我的光标重置为DEFAULT(在我的任务完成后)

那么,我的长任务不会进入MAIN队列?因为,如果它进入主队列,我预计它会在我首先插入队列的WAIT游标之后执行。
为什么会出现这种情况?

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?

推荐答案

如果没有线程,您的代码将在FX应用程序线程上执行。这是(有效地)负责将UI呈现给屏幕并处理用户输入的线程。如果在此线程上执行长时间运行的任务,则会阻止FX应用程序线程的任何正常功能发生,直到长时间运行的任务完成。特别是,如果你这样做

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);

然后设置按照您指定的顺序进行,但场景不会被重新渲染直到所有代码行完成。因此,在代码完成之前,您永远不会看到UI的任何更改 - 包括对光标的更改。下次FX Application Thread有机会渲染场景时,光标设置为 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.

多线程和JavaFX有两个基本规则(相同的规则通常适用于大多数UI工具包):

There are two basic rules for multithreading and JavaFX (and the same rules generally apply to most UI toolkits):


  1. 对UI 的任何更改必须 在FX应用程序线程上执行

  2. 长时间运行的进程应该在FX应用程序线程上执行(因为它们使UI无响应)

  1. Any changes to the UI must be performed on the FX Application Thread
  2. Long-running processes should not be performed on the FX Application Thread (as they make the UI unresponsive)

所以你的解决方案实际上并不正确,因为你违反了这两个规则。您应该

So your solution is not actually correct, because you violate both of those rules. You should


  1. 在FX应用程序线程上将光标设置为 WAIT

  2. 在后台线程上启动长时间运行的任务

  3. 任务完成后,将光标设置回 DEFAULT ,在FX申请主题上。

  1. Set the cursor to WAIT on the FX Application Thread
  2. Start your long running task on a background thread
  3. When the task is complete, set the cursor back to DEFAULT, 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();

这篇关于JAVAFX:为什么等待游标需要一个新线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆