Asynchronous JavaFX显示加载对话框以进行更长的操作

Asynchronous JavaFX显示加载对话框以进行更长的操作,asynchronous,concurrency,javafx,runnable,Asynchronous,Concurrency,Javafx,Runnable,我在控制器类中得到了一些操作,这可能需要一些时间。因此,我想在运行此操作时显示一个加载对话框 我试过这个: Platform.runLater(new Runnable() { @Override public void run() { loadingDialog.show(); } }); Boolean opSuccess = myService.operate(); Platform.runLater(new Runnable() { @Override

我在控制器类中得到了一些操作,这可能需要一些时间。因此,我想在运行此操作时显示一个加载对话框

我试过这个:

Platform.runLater(new Runnable() {
  @Override
  public void run() {
     loadingDialog.show();
  }
});

Boolean opSuccess = myService.operate();

Platform.runLater(new Runnable() {
   @Override
   public void run() {
     loadingDialog.hide();
   }
});

if (opSuccess) {
   // continue
}
现在,问题是,加载对话框永远不会显示。UI只会阻塞一段时间,然后在“//continue”上继续

看来,runLater调用被阻塞操作(operative)阻塞了

在运行myService.operate()之前,我还尝试了ConditDownLatch,以等待loadingDialog.show()完成。但是latch.await()方法永远不会完成

所以我的问题是,在myService.operate()完成并返回true或false之前,我如何显示loadingDialog?我是否必须将operate()调用放入另一个线程并异步运行它,还是有更简单的方法


谢谢您的帮助。

您确定您的整个代码没有在JavaFX线程中运行吗? 控制器类的方法通常会这样做,我认为这是由于您的描述

但是,最好使用这个类。您将找到一个教程和一个简短的应用程序代码段:

// here runs the JavaFX thread
// Boolean as generic parameter since you want to return it
Task<Boolean> task = new Task<Boolean>() {
    @Override public Boolean call() {
        // do your operation in here
        return myService.operate();
    }
};

task.setOnRunning((e) -> loadingDialog.show());
task.setOnSucceeded((e) -> {
    loadingDialog.hide();
    Boolean returnValue = task.get();
    // process return value again in JavaFX thread
});
task.setOnFailed((e) -> {
  // eventual error handling by catching exceptions from task.get()  
});
new Thread(task).start();
//这里运行JavaFX线程
//布尔值作为泛型参数,因为您希望返回它
任务=新任务(){
@重写公共布尔调用(){
//你在这里做手术吗
返回myService.operate();
}
};
task.setOnRunning((e)->loadingDialog.show());
task.setonsucceed((e)->{
loadingDialog.hide();
布尔返回值=task.get();
//在JavaFX线程中再次处理返回值
});
task.setOnFailed((e)->{
//通过捕获task.get()中的异常进行最终错误处理
});
新线程(任务).start();

我假设了Java8和使用Lambda表达式的可能性。当然,没有它们是可能的。

您最好使用JavaFx-Tasks和services中的并发机制/工作接口,而不是使用Platform.runLater()。任务和服务允许您在单独的线程中管理长时间运行的任务。它们还提供回调以指示任务的进度

你可以在


还可以查看任务和服务的集成JavaFX示例-

提供一个。你说得对。我上面的代码段在FX线程中运行,因为它是控制器。但我意识到,当我尝试在不使用Runlater的情况下更新UI组件时,会遇到奇怪的并发异常。那么,它是否会改变您提供的任务解决方案?我还尝试了与我的第一个示例相同的代码,但没有稍后运行。只需使用:
loadingDialog.show();布尔成功=myService.operate();loadingDialog.hide()但结果是相同的。UI被阻止且未显示任何对话框。如果在FX线程之外更改UI,则会出现这些异常,否则不应出现这些异常。不,我的解决方案必须在FX线程中运行,所以它应该可以工作。当然,只要在FX线程中运行昂贵的计算,用户界面就会阻塞。使用
新线程(任务).start()你现在在一个单独的线程中运行它,当工作完成时调用回调(同样在FX线程中)。是的,谢谢。这是有效的。这有点复杂,因为我想从
operate()
修改和调用UI组件,但这是我的问题。因此,我必须以另一种方式重新构造代码,将UI调用与繁重的后台操作分离开来。