バックグラウンドタスクを実行する前に、をキャンセルしSwingworker
て完了するのを待つことはできますか?doInBackground()
または、 Swing Worker全体をキャンセルせずに、コードを実行するタスクに割り込みを送信することもできます。
私の問題は、コードインが完了done()
する前にコードインを開始したくないということです。doInBackground()
以前のコードではキャンセルが呼び出されることはありませんでした。Swingworker
代わりに、がチェックし、クローズダウンが適切に設定されているかどうかを確認する揮発性ブール値を設定しましたWidgetController
。WidgetController
このフラグをチェックするのに時間がかかることがあることを除いて、これはすべて正常に機能したので、割り込みメソッドを使用できるようにする必要があります。
疑似例
ユーザーが[開始]をクリックするとダイアログが表示されます。WidgetDialogListener
これにより、のインスタンスが作成されWidgetWorker
、これが開始WidgetController
され、が表示されます。通常の表示がWidgetProgressDialog
完了すると、実行内容の概要が表示されます。WidgetController
ShowWidgetReport
WidgetController
WidgetController
が実行されている間、WidgetProgressDialog
進行状況を示すが表示されます。ユーザーがキャンセルボタンをクリックして進行を停止すると、実際に完了するのを待たずWidgetController
に割り込みが送信さ れ、doneメソッドが呼び出されて表示されます。しかし、実際に完了するまで、これを実行したくありません。widgetcontroller
ShowWidgetReport
WidgetController
class WidgetDialogListener implements ActionListener
{
public WidgetDialogListener()
{
}
public void actionPerformed(ActionEvent e)
{
StartFixSongsDialog.this.dispose();
WidgetProgressDialog wpd = new FixSongsDialog();
wpd.setVisible(true);
WidgetWorker ww = new WidgetWorker();
wpd.setSwingWorker(ww);
Executors.newSingleThreadScheduledExecutor().submit(ww);
}
}
class WidgetProgressDialog
{
....................
private void actionPerformed(ActionEvent e)
{
//Main.stopTask();
swingWorker.cancel(true);
}
}
class WidgetWorker extends SwingWorker<String, Object>
{
@Override
public String doInBackground() throws Exception
{
new WidgetController().startCreateWidgets();
return "";
}
@Override
protected void done()
{
ShowWidgetReport showReport = new ShowWidgetReport();
showReport.setVisible(true);
}
}
編集
ジェイコブが私に指摘したことを実際に終えるために、キャンセルされた未来を待つでAwaitingWorker
説明されたものを使用しました
abstract class AwaitingWorker<T, V> extends SwingWorker<T, V>
{
private final CountDownLatch actuallyFinishedLatch = new CountDownLatch(1);
protected abstract T performOperation() throws Exception;
@Override
protected final T doInBackground() throws Exception
{
try
{
return performOperation();
}
finally
{
actuallyFinishedLatch.countDown();
}
}
public void awaitActualCompletion() throws InterruptedException
{
actuallyFinishedLatch.await();
}
}
class WidgetWorker extends AwaitingWorker<String, Object>
{
@Override
public String performOperation() throws Exception
{
new WidgetController().startCreateWidgets();
return "";
}
@Override
protected void done()
{
try
{
awaitActualCompletion();
}
catch(InterruptedException ioe)
{
}
ShowWidgetReport showReport = new ShowWidgetReport();
showReport.setVisible(true);
}
}
おそらく解決策を正確に誤解しているかもしれませんが、どちらの方法でも、GUIスレッドは非GUIタスクが終了するのを待つことになりますが、私が欲しいのは、非GUIタスクが完了する前に完了することです。 GUIスレッド。