これを行うための標準的な、または既製の方法に最も近いのは、progressによって提供されるプロパティおよび/またはパブリッシュ/プロセス メソッドのペアSwingWorkerです。バックグラウンド作業が完了したことを示すために、メソッドの最後でこれを「I'm finished」値に設定できます。Swing ワーカーで待機しているスレッドは、「キャンセル中...」メッセージを表示し、進行状況を定期的にチェックして、完了したかどうかを確認できます。待機中のスレッドが Swing EDT の場合は、Timer を使用して進行状況プロパティを定期的にチェックし、完了したらキャンセル メッセージをクリアする必要があります。
以下は、頑固なバックグラウンド スレッドを実行するサンプル コードです。このスレッドはキャンセルされ、進行状況が 100 に達するまで待機します。
@Test
public void testSwingWorker()
{
SwingWorker worker = new SwingWorker() {
@Override
protected void process(List chunks)
{
for (Object chunk : chunks)
{
System.out.println("process: "+chunk.toString());
}
}
@Override
protected void done()
{
System.out.println("done");
}
@Override
protected Object doInBackground() throws Exception
{
// simulate long running method
for (int i=0; i<1000000000; i++)
{
double d = Math.sqrt(i);
}
System.err.println("finished");
publish("finished");
setProgress(100);
return null;
}
};
Thread t = new Thread(worker);
t.start();
try
{
worker.get(1, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
}
catch (ExecutionException e) {
}
catch (TimeoutException e) {
}
worker.cancel(true);
// now wait for finish.
int progress = 0;
do
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}
progress = worker.getProgress();
System.out.println(String.format("progress %d", progress));
}
while (progress<100);
}
もう 1 つの方法は、メソッドのペアを使用しpublish\processて、バックグラウンド スレッドが終了したことを示す特別な値を EDT にプッシュすることです。次に、 SwingWorker のprocessオーバーライド メソッドがこの特別な値を取得し、「キャンセル中...」メッセージを非表示にします。これの利点は、ポーリングやタイマーが必要ないことです。コード例はdone、タスクがキャンセルされるとすぐに呼び出されますが、タスクがキャンセルされた場合でもパブリッシュ/プロセス メソッドのペアが機能することを示しています。