当我运行另一个线程时,JavaFx 进度指示器卡住

标签 java multithreading javafx-2

所以我一直在尝试实现一个进度指示器,但没有成功。尽管已经阅读了一些有关 Platform.RunLater 和 Tasks 的内容,但我不确定我是否很好地理解使用 JavaFx 管理线程。这是我的用例。

我的程序允许用户连接到数据库并查看数据库中的一些架构和其他对象。有时连接到大型数据库并提取其所有表和信息需要一段时间,所以我想显示一个进度指示器。我根本不想更新进度,我只是想让进度指示器在进程运行以从数据库中提取所有内容时以 -1 值可见。理想情况下,我将从 FXML 文件中加载一个不可见的进度指示器。当我开始从数据库中提取信息的过程时,我想让它可见。

当我试图让我的进度可见时,它从未出现,所以我决定开始让它可见并使其不可见,只是为了看看会发生什么。当我打开程序时,进度指示器旋转得很好,但是当我尝试连接到数据库时,它就停止旋转并卡住了。我认为这就是当我尝试使其可见时发生的情况,这就是它从未出现的原因。

以下是我当前的代码,我将不胜感激任何详细的帮助和解释,以便我能够理解发生了什么。谢谢

来自完成大部分工作的方法。

                //make progress indicator visible
                pi.setVisible(true);

                // separate non-FX thread
                ExtractorThread t = new ExtractorThread();
                t.setCp(cp);
                t.start();

                //Wait until the thread is done
                try{
                    t.join();
                }
                catch(Exception e){
                    e.printStackTrace();
                }

                //Retrieve the dbextractor from the thread
                DbExtractor dbe = t.getDbe();
                //move on to the next page in the application
                this.caster.goToDataSource(c, cp, dbe);

ExtractorThread 完成这项工作。

private class ExtractorThread extends Thread{
    private ConnectionProperties cp;
    private DbExtractor dbe;

    public void run() {
        dbe = new DbExtractor(cp);
        try {
            dbe.extract();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   

    }

    public DbExtractor getDbe() {
        return dbe;
    }

    public void setCp(ConnectionProperties cp) {
        this.cp = cp;
    }
}

如果我应该使用 Platform.RunLater,我不知道在哪里使用它或为什么使用它。任何帮助将不胜感激,谢谢!

最佳答案

使用javafx.concurrent API。扩展任务而不是线程:

private class ExtractorThread extends Task<DbExtractor>{
    private ConnectionProperties cp;

    public DbExtractor call() throws Exception {
        dbe = new DbExtractor(cp);
        dbe.extract();
        return dbe;   

    }


    public void setCp(ConnectionProperties cp) {
        this.cp = cp;
    }
}

然后执行:

        //make progress indicator visible
        pi.setVisible(true);

        // separate non-FX thread
        final ExtractorThread t = new ExtractorThread();
        t.setCp(cp);
        t.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
            public void handle(WorkerStateEvent event) {
               DbExtractor dbExtractor = t.getValue();
               this.caster.goToDataSource(c, cp, dbe);
            }
        });
        t.setOnFailed(...); // similarly, to handle exceptions
        new Thread(t).start();

关于当我运行另一个线程时,JavaFx 进度指示器卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22274576/

相关文章:

iOS:UILabel 倒计时卡在其他 UI 操作上

asp.net - 绑定(bind)多个gridview的线程

JavaFX - 通过输入更新 WebView 中变量的值

javafx 8 : How to update TreeCell in TreeView on SlectedItemProperty Change

java - 如何在 Java 的 mongodb 中从 BasicDBList 创建 List<String>?

java - URL.openStream 很慢

c# - 使用多线程处理大型 Excel 文件

java - 强制更新 UI

java - PHP - WAMP 服务器 (Windows) 中的串行端口(com 端口)访问被拒绝

Javafx 10 或更早版本可供下载以创建可运行的 jar 文件