javafx在加载时显示progressindicator

时间:2016-01-13 17:49:51

标签: 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,因为应用程序将一直挂起,直到APIcall完成并加载新内容。

我尝试使用Threads和Platform.runLater(),但我无法让它工作。我的目标是显示ProgressIndicator,直到APIcall完成,框架构建并且场景被赋予gp作为新根。

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

1 个答案:

答案 0 :(得分:1)

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

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

Guava的ListenableFuture伪代码

// 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连接!还要考虑后台任务是否应检查中断标志