6

データ分析に使用するアプリケーションがあります。このアプリケーションの大きな部分は、収集されたデータに基づいてチャートを表示できる機能と、1 回のバッチ操作で多数のタスクをエクスポートできる機能です。今まで JFreeChart を使用してきましたが、ネイティブ JavaFX チャートを使用して、エクスポートされたチャートがアプリケーションの画面上と同じように見えるようにしたいと考えています。

私は JavaFX 2.2.1 (jdk 7u6) を使用しています。

1 つのバッチでグラフを生成できますが、これらのグラフは JavaFX アプリケーション スレッドでレンダリングする必要があるため、ユーザー インターフェイス (UI) をフリーズする必要があります。Platform.runLater(new Runnable() { ... }); を使用します。このためのコマンドで、チャートを生成するコードをラップします。

代わりに、個々のチャート生成を Platform.runLater(new Runnable() { ... }); にラップするとします。以前のように GUI がフリーズすることはありませんが、個々のチャートがいつ生成されるかを検出できないため (後の段階で実行され、いつ発生するかを制御できないため)、フィードバックも得られません。 、また、私が知る限り、利用可能なコールバックはありません)。

この特定のイベントでは、進行状況バーをユーザーに表示したいと思います。この進行状況バーを実際のチャート生成と共に更新したいと考えています。

これをどのように達成できるかについての提案やヒントはありますか?

4

3 に答える 3

5

この質問は、Oracle JavaFX フォーラムのスレッド「Render charts in background 」で解決されました。

解決策は、3 つのサブタスクを持つ 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オブジェクトを使用してチャートを個別にロードすることで簡単に解決できます (たとえば、チャートごとに 1 つのタスク)。チュートリアルページを引用:

タスクは、バックグラウンド スレッドで実行する必要がある作業のロジックを実装するために使用されます。

Task はWorkインターフェイスを実装しているため、Taskを使用してWorker.Stateを調べることができます。マニュアルの引用:

再利用可能なワーカーは、CANCELLED、SUCCEEDED、または FAILED から READY に戻ります。

Worker.State オブジェクトには次の可能な状態があるため、タスクがまだ実行中かどうかを常に知ることができるため、これによりフィードバックに関する問題が解決されます。

  • キャンセル
  • 失敗した
  • 準備
  • ランニング
  • 予定
  • 成功した

進行状況バーについては、updateProgress(double done, double max)を使用してタスクの進行状況を設定し、次にProgressBar.progressProperty()Task.progressProperty( ) にバインドして進行状況バーの進行状況を設定するだけです。

編集

あなたのコメントに答える:

問題は、この場合、JavaFX チャートの生成時にタスク内で実行される作業であり、そのコードは JavaFX アプリケーション スレッド内で実行する必要があります。

チュートリアルから:

代わりに、javafx.concurrent パッケージで提供される JavaFX API を使用してください。これは、UI とやり取りするマルチスレッド コードを処理し、このやり取りが正しいスレッドで行われるようにします。

つまり、Task オブジェクト内で実行されるコードは、JavaFX スレッドで既に実行されています。

お役に立てば幸いです。乾杯

于 2012-11-05T13:43:32.730 に答える
0

JFX スレッドでJavaFX を実行するTaskには、タスクを で実行するようにスケジュールできますPlatform.runLater(myJFXTask);

于 2013-02-12T20:11:43.450 に答える