【问题标题】:JavaFx ProgressIndicator updateJavaFx ProgressIndicator 更新
【发布时间】:2018-04-06 20:58:04
【问题描述】:

我知道,这个问题已经得到了足够多的回答,但没有一个解决方案适合我的问题。

案例:

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

我的问题:

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

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

提前感谢您的帮助。

【问题讨论】:

  • 你为什么通过调用join()来阻塞UI线程? (其实线程构造函数中Platform.runLater(..)的作用到底是什么?为什么不直接调用start()?)
  • 这就是解决方案...
  • 我什至不知道问题是什么。
  • 没有 Platform.runLater(..) = 线程“导入 4”java.lang.IllegalStateException 中的异常:不在 FX 应用程序线程上; currentThread = 导入 4
  • 哪一行给了你这个例外?

标签: java multithreading javafx task progress-indicator


【解决方案1】:

出于某种原因,您故意强制 UI 线程等待您的后台任务完成,方法是将对 join() 的调用包装在对 Platform.runLater() 的调用中。因此,在任务完成之前,UI 线程无法执行任何其他操作(例如渲染进度指示器)。

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

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

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

【讨论】:

    猜你喜欢
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 2014-11-26
    • 1970-01-01
    • 2023-03-13
    • 2013-01-30
    • 2015-09-09
    • 1970-01-01
    相关资源
    最近更新 更多