javafx 在加载时显示进度指示器

标签 java javafx

这是我的应用程序的主窗口:

screenshot

我希望能够更新窗口,所以我写了一个方法reset按 F5 触发:

public void reset() {
    final ProgressIndicator pi = new ProgressIndicator(-1.0f);

    final HBox hb = new HBox(pi);
    final VBox vb = new VBox(hb);

    hb.setAlignment(Pos.CENTER);
    vb.setAlignment(Pos.CENTER);

    scene.setRoot(vb);

    //this.show();
}

如果我运行它,它看起来像这样:

screenshot

但是,如果我取消注释 //this.show(); 行这将被执行:

public void show() {
    final VBox box = API_CALL_AND_BUILDING_BOX_MAGIC_WHICH_I_STRIPPED;

    gp.getChildren().clear();
    gp.getChildren().add(box);

    scene.setRoot(gp);
    stage.sizeToScene();
}

我将永远无法看到我的 ProgressIndicator,因为应用程序将挂起,直到 API 调用完成并加载新内容。

我尝试了一些 Threads 和 Platform.runLater() 但无法让它工作。我的目标是显示 ProgressIndicator,直到 API 调用完成、盒子构建完毕并且场景被给出 gp作为新的根。

我希望我的目标和问题是可以理解的:)

最佳答案

您需要创建另一个专用于从远程源获取数据的 JVM 线程。应用程序的主线程绝不能因网络操作而阻塞:在键盘事件处理程序中,您只需使用进度指示器重新绘制主窗口,然后等待另一个事件,该事件可以是:

  • 后台操作完成(成功、不成功)
  • 用户中断(鼠标/键盘)
  • 超时到期

伪代码 ListenableFuture通过 Guava

// Initialize in ctor use MoreExecutors
private final ListeningExecutorService service;

// Keep to call .cancel()
private ListenableFuture<APIData> currentRequest;

// Run in the GUI thread
public void onRefreshEvent() {
  showProgressIndicator();
  currentRequest = service.submit(/* Some Callable<APIData> */);
  Futures.addCallback(currentRequest , this, this);
}

// From FutureCallback<T>
public void onFailure(Throwable t) {} // TODO
public void onSuccess(APIData d) {}   // TODO

// From Executor
public void execute(Runnable cmd) {
  Platform.runLater(cmd);
}

不要忘记考虑套接字连接和读取超时,以及池化 HTTP 连接!还要考虑后台任务是否应该检查中断标志

关于javafx 在加载时显示进度指示器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34773577/

相关文章:

java - 在线程内创建线程 - 好的做法?

javafx - 在 JavaFX 中将堆栈跟踪打印到 Textarea 中

Javafx BorderPane 强制重叠

java - 如何打印媒体和样式 slider 的持续时间| JavaFX

java - 硬编码按钮不会出现在设计 View 或正在运行的程序中

java - JDO 查询中的多个类

java - 当所有消息被消费完后如何触发一个方法?

Java UDP 服务器-客户端显示方形字符

JavaFX cas 文件版本错误

java - 如何从文本字段获取数字值