6

我有一个用于数据分析的应用程序。该应用程序的很大一部分是能够根据组装的数据显示图表,并能够在一次批处理操作中导出大量任务。到目前为止,我一直在使用 JFreeChart,但我想使用本机 JavaFX 图表,以便导出的图表看起来仍然与它们在应用程序中的屏幕显示相同。

我在 JavaFX 2.2.1 (jdk 7u6) 上。

我可以批量生成图表,但这意味着我必须冻结用户界面 (UI),因为这些图表必须在 JavaFX 应用程序线程上呈现。我使用 Platform.runLater(new Runnable() { ... }); 用于此的命令,包裹在生成图表的代码周围。

如果我将每个单独的图表生成包装到 Platform.runLater(new Runnable() { ... }); GUI 没有像以前那样冻结,但我也不会收到任何反馈,因为我无法检测到每个单独的图表何时生成(它们在稍后阶段运行,我无法控制何时可能发生,据我所知也没有可用的回调)。

对于这个特定的事件,我想向用户显示一个进度条,并且我希望这个进度条随着实际的图表生成而更新。

关于如何实现这一点的任何建议或提示?

4

3 回答 3

5

这个问题在 Oracle JavaFX 论坛主题中得到了解决:在后台渲染图表

解决方案是有一个包含三个子任务的 SaveChartsTask:

  1. 在屏幕外场景图中创建图表。
  2. 将每个屏幕外图表的快照拍摄到 JavaFX 图像。
  3. 使用imageio例程将 JavaFX 图像导出到文件。

任务的 workDone 属性允许监视操作的过程。通过将全部工作拆分为子任务,尽可能将工作从 JavaFX 应用程序线程中分离出来,并根据需要使用 CountDownLatches 和 BlockingQueues 来同步操作,UI 能够保持响应。

于 2013-02-12T20:46:00.123 回答
1

因为您似乎是 JavaFX-2 的新手。我建议您阅读 oracle 文档中的 JavaFX-2 Concurrency文章。

您的问题很容易通过使用任务对象单独加载图表来解决(例如,每个图表一个任务)。引用教程页面:

任务用于实现需要在后台线程上完成的工作逻辑。

由于 Task 实现了工作接口,您可以使用您的 Task 来探测它们的Worker.State。引用手册:

可重用的 Worker 将从 CANCELLED、SUCCEEDED 或 FAILED 转换回 READY。

这将解决您关于反馈的问题,因为您将始终能够知道任务是否仍在运行,因为 Worker.State 对象具有以下可能的状态:

  • 取消
  • 失败的
  • 准备好
  • 跑步
  • 预定的
  • 成功

至于您的进度条,您可以使用updateProgress(double done, double max)来设置您的任务进度,然后通过将ProgressBar.progressProperty()绑定到Task.progressProperty( ) 来简单地设置进度条的进度。

编辑

回复您的评论:

问题是在这种情况下,在生成 JavaFX 图表时在任务内部执行的工作,并且代码需要在 JavaFX 应用程序线程内执行

从教程:

相反,请使用 javafx.concurrent 包提供的 JavaFX API,它负责与 UI 交互的多线程代码,并确保这种交互发生在正确的线程上。

这意味着在 Task 对象中执行的代码已经在 J​​avaFX 线程中执行。

我希望它有所帮助。干杯

于 2012-11-05T13:43:32.730 回答
0

要在 JFX 线程上运行 JavaFX Task,您可以安排任务以Platform.runLater(myJFXTask);.

于 2013-02-12T20:11:43.450 回答