2015-01-08 5 views
8

Java SwingWorkerクラスに相当するJavaFXはありますか?JavaFX SwingWorker相当ですか?

私はJavaFX Taskを認識していますが、文字列メッセージまたは進捗状況だけを公開することができます。私はちょうど私が(任意のタイプのメッセージを公開して)SwingWorkerでやったように、GUIスレッドでメソッドを呼びたいと思っています。

相続人は、私が何を意味するかの例です:

class PrimeNumbersTask extends 
     SwingWorker<List<Integer>, Integer> { 
    PrimeNumbersTask(JTextArea textArea, int numbersToFind) { 
     //initialize 
    } 

     @Override 
    public List<Integer> doInBackground() { 
     while (! enough && ! isCancelled()) { 
       number = nextPrimeNumber(); 
       publish(number); 
       setProgress(100 * numbers.size()/numbersToFind); 
      } 
     } 
     return numbers; 
    } 

     @Override 
    protected void process(List<Integer> chunks) { 
     for (int number : chunks) { 
      textArea.append(number + "\n"); // HERE: execute in GUI thread 
     } 
    } 
} 

ソリューション

あなたの答えをありがとうございました。私が探していた解決策はPlatform.runLater(Runnable guiUpdater)です。

答えて

7

次のように私はあなたのSwingWorkerを書き換えます:

class PrimeNumbersTask extends Task<List<Integer>> { 
    PrimeNumbersTask(TextArea textArea, int numbersToFind) { 
     // initialize 
    } 

    @Override 
    protected List<Integer> call() throws Exception { 
     while (!enough && !isCancelled()) { 
      number = nextPrimeNumber(); 
      updateMessage(Integer.toString(number)); 
      updateProgress(numbers.size(), numbersToFind); 
     } 
     return numbers; 
    } 
} 

用途:

TextArea textArea = new TextArea(); 
PrimeNumbersTask task = new PrimeNumbersTask(numbersToFind); 
task.messageProperty().addListener((w, o, n)->textArea.appendText(n + "\n")); 
new Thread(task).start(); // which would actually start task on a new thread 

説明:

はい、私たちはSwingWorkerとしてpublish()方法を持っていませんJavaFXではそうですが、あなたの中にありますupdateMessage()を使用している場合は、このプロパティにリスナーを登録し、メッセージが更新されるたびに新しい行を追加できるため、十分です。

これで十分でない場合は、いつでもPlatform.runLater()を使用してGUIの更新をスケジュールできます。あなたはあまりにも多くのGUI更新とGUIのスレッドを行っている場合は減速している、あなたは、次のイディオムを使用することができます。Throttling javafx gui updates

+0

私はすでにその解決策について考えていましたが、回避策に似ているようです(okですが、すべての場合にそうではありません)。 Platform.runLater()メソッドは、まさに私が探していたものです。 – Crine

+0

タスクの新規インスタンスを作成しただけで、PrimeNumbersTaskのバックグラウンド作業を開始しませんでした。私はそれをスレッドに入れて起動する必要があると思います。さもなければ、task.run()を呼び出すだけでGUIがブロックされていれば、私は行を追加することができます:new Thread(task).start();これがいいのかどうか教えてください – Ewoks

-1

SwingWorkerを使用しないでください。 SwingWorker.javaソースのコードのこの部分にそれを使用しないように、引数の十分なはずです:

private static final int MAX_WORKER_THREADS = 10; 

代わりExecutorとそれに一緒に来てサービスを自分が慣れます。

JavaFXとはまったく関係がありません。単なるJavaです。しかし、あなたの質問はJavaFXに関連していました。次に、Update UI in JavaFX Application Thread using Platform.runLater()の例を示します。

+0

Platform.runLater()のコード例をありがとうございます:) – Crine

+0

あなたの嫌いなことを理解していますが、 'SwingWorker'が実際に非EDTからEDTへのチャンクの転送(' process')毎回 'Runnable'を実行します。 'publish'のソースを見ると、' sun.swing'パッケージに 'AccumulativeRunnable'インスタンスが含まれています。これが何を意味しているのか、完全なJavaFX newbであるかどうかわかりません。 –

0

別にあなただけの文字列を渡すことができupdateMessage方法から、あなたが渡すことができupdateValue方法がありますオブジェクト全体であるので、私はあなたも同様の方法でそれを使うことができると信じています。このアプローチは、Task文書の「部分結果を返すタスク」セクションに記載されています。もう1つのアプローチは、Platform.runLater()アプローチが他の答えにも記載されています。

これらのアプローチの重要な違いは、最初のものが結果を統合することです。つまり、複数のupdateValue呼び出しでは、FXスレッドのフラッディングを防ぐためにいくつかを省略することができます。

一方、プラットフォーム。runLaterアプローチはすべての中間結果を送信しますが、高頻度の更新がある場合はFXスレッドに洪水の危険があるため、手作業で回避する必要があります。答えはThrottling javafx gui updates

関連する問題