JavaFX如何处理线程和GUI的交互

14

在使用JavaFX和线程时遇到问题。基本上我有两个选择:使用TasksPlatform.runLater。据我所知,Platform.runLater应该用于简单/短时间的任务,而Task则用于较长时间的任务。然而,我不能使用它们中的任何一个。

当我调用Thread时,它必须在任务进行时弹出验证码对话框。但使用Task时,它忽略了我的请求以显示新的对话框……它不允许我创建新的舞台。

另一方面,当我使用Platform.runLater时,它允许我显示一个对话框,但程序的主窗口会冻结,直到弹出对话框被显示。

我需要任何解决这个问题的方法。如果有人知道如何处理这个问题或有类似的经验并找到了解决办法,我期待着您的回复!


可能是JavaFX2:我可以暂停后台任务/服务吗?的重复问题。 - jewelsea
4个回答

39

如puce所说,你需要使用TaskService来处理在后台执行的任务。同时,你需要使用Platform.runLater将从后台线程中执行的任务切换到JavaFX应用程序线程。

你需要对它们进行同步,其中一种方法是使用CountDownLatch类。

以下是一个示例:

Service<Void> service = new Service<Void>() {
        @Override
        protected Task<Void> createTask() {
            return new Task<Void>() {           
                @Override
                protected Void call() throws Exception {
                    //Background work                       
                    final CountDownLatch latch = new CountDownLatch(1);
                    Platform.runLater(new Runnable() {                          
                        @Override
                        public void run() {
                            try{
                                //FX Stuff done here
                            }finally{
                                latch.countDown();
                            }
                        }
                    });
                    latch.await();                      
                    //Keep with the background work
                    return null;
                }
            };
        }
    };
    service.start();

正是我正在寻找的。非常感谢! - ksarunas
仔细查看了这个答案后,我得出的结论是这个答案很糟糕。我建议使用ServiceTask,因为它们是专门设计的。请参考https://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm。 - SedJ601

8

我创建了一个Worker(任务)。一旦我需要显示弹出窗口,我调用Platform.runLater,但是我需要等待响应(这是输入对话框),但如果我创建新线程(Platform.runLater),它不会等待响应并且Worker继续执行...如何处理它。也许有一种方法可以暂停Worker线程等待来自Platform.runLater的输入,然后继续...? - ksarunas

0

现在回答已经晚了,但对于那些遇到这个错误的人,这是解决方案XD

你可以使用一个线程。

在线程中使用lambda表达式作为runnable,同时也使用runlater

Thread t = new Thread(() -> {
        //Here write all actions that you want execute on background

        Platform.runLater(() -> {
            //Here the actions that use the gui where is finished the actions on background.
        });
    });
t.start();

-2

您可以直接使用这段代码 不要忘记不能在线程中发送非最终变量。 您可以在线程中发送final变量

     //final String me="ddddd";
      new Thread(new Runnable() {
            @Override
            public void run() {
                    // me = me + "eee";
                    //...Your code....
              
            }
        }).start();

在你的代码中使用

尝试/捕获


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接