JavaFx ProgressIndicator更新

时间:2017-10-25 16:53:44

标签: java multithreading javafx task progress-indicator

我知道,这个问题的答案已经绰绰有余,但即使是一个解决方案也不适合我的问题。

案例:

我想将1:n文件导入数据库。到现在为止还挺好。 对于每个文件,ProgressIndicator应重置进度值。 是的,确实如此。在将我的东西导入数据库时​​,GUI似乎“卡住”,直到下一个文件导入开始。

我的问题:

值重置,但ProgressIndicator不重置。 但是值正在正确更新。 System.out.println(progressIndicator.getProgress());显示更新后的结果,直至达到1.0。 在导入完成之前,它会直接跳转到100%并且永远不会重置..通过以下更多的导入,并且正在使用正确的值不断更新进度。在Progress达到1.0 = 100%后,下一个Import开始。我的错误在哪里?

ProgressUpdater类:

public void activateBind(ReadOnlyDoubleProperty binding) {
    if (pg != null) {
        pg.progressProperty().unbind();
        pg.progressProperty().bind(binding);
    }
}

注意,所有使用的类都会为每个文件导入进行初始化。 PS:是的,我在代码中拼错了“ProgressIndicator”。

控制器类:

@FXML
ProgressIndicator progessIndicator;

ImportTask task = new ImportTask(dbConnector, insertStatements, this);
final ProgressUpdater pgup = new ProgressUpdater(progessIndicator, dbConnector.getPercentVal());
pgup.activateBind(task.progressProperty());
new ImportThread(task, counter);

导入任务类:

@Override
protected Void call() throws Exception {
    for (int i = 0; i < insertStatements.size(); i++) {
        dbC.executeInsert(insertStatements.get(i));
        updateProgress(dbC.getCurrent(), dbC.getEnd());
    }
    mc.executeImport();
    return null;
}

ImportThread类从Thread扩展:

public ImportThread(Task task, int d) {
    super(task, "Import " + d);
    setDaemon(true);
    Platform.runLater(new Runnable() {

        @Override
        public void run() {
            start();
            try {
                join();
            } catch (InterruptedException e) {
                System.out.println("JOIN ERROR");
                e.printStackTrace();
            }
        }
    });
}

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

出于某种原因,您通过在join()的调用中打包Platform.runLater()来故意强迫UI线程等待后台任务完成。因此,UI线程无法执行任何其他操作(例如渲染进度指示器),直到任务完成。

如果你想让线程在创建时立即启动(这不是一个好主意,tbh),只需在构造函数中调用start()

public ImportThread(Task task, int d) {
    super(task, "Import " + d);
    setDaemon(true);
    start();
}

没有明显的理由Thread.start()需要在FX应用程序线程上执行,因此这里不需要Platform.runLater()