スタートとストップを言う2つのボタンがあるシンプルなJavaFX2アプリがあります。スタートボタンがクリックされたときに、処理を実行し、進行中にUI(プログレスバーなど)を更新するバックグラウンドスレッドを作成したいと思います。停止ボタンがクリックされたら、スレッドを終了させたいです。
ドキュメントから収集したjavafx.concurrent.Task
クラスを使用してこれを実行しようとしましたが、これには問題なく機能します。しかし、[スタート]をクリックすると、UIは通常のままではなく、フリーズ/ハングします。
彼女は、ボタンを表示するためのメインのMyprogram extends Application
クラスのコードです。
public void start(Stage primaryStage)
{
final Button btn = new Button();
btn.setText("Begin");
//This is the thread, extending javafx.concurrent.Task :
final MyProcessor handler = new MyProcessor();
btn.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent event)
{
handler.run();
}
});
Button stop = new Button();
stop.setText("Stop");
stop.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent event)
{
handler.cancel();
}
}
);
// Code for adding the UI controls to the stage here.
}
MyProcessor
クラスのコードは次のとおりです。
import javafx.concurrent.Task;
public class MyProcessor extends Task
{
@Override
protected Integer call()
{
int i = 0;
for (String symbol : feed.getSymbols() )
{
if ( isCancelled() )
{
Logger.log("Stopping!");
return i;
}
i++;
Logger.log("Doing # " + i);
//Processing code here which takes 2-3 seconds per iteration to execute
Logger.log("# " + i + ", DONE! ");
}
return i;
}
}
非常に単純ですが、コンソールメッセージは引き続き表示されますが、[スタート]ボタンをクリックするたびにUIがハングします(Logger.log
は単にSystem.out.println
を実行します)
私は何が間違っているのですか?
Task
はRunnable
を実装しているため、handler.run();
を呼び出すと、実際にはUIスレッドでcall
メソッドを実行します。それはUIをハングさせます。
エグゼキュータを介して、または単にnew Thread(handler).start();
を呼び出すことにより、バックグラウンドスレッドでタスクを開始する必要があります。
これは、 javadoc または JavaFX同時実行チュートリアル で説明されています(あまり明確ではないかもしれません)。