1

バックグラウンドタスクを実行する前に、をキャンセルしSwingworkerて完了するのを待つことはできますか?doInBackground()または、 Swing Worker全体をキャンセルせずに、コードを実行するタスクに割り込みを送信することもできます。

私の問題は、コードインが完了done()する前にコードインを開始したくないということです。doInBackground()以前のコードではキャンセルが呼び出されることはありませんでした。Swingworker代わりに、がチェックし、クローズダウンが適切に設定されているかどうかを確認する揮発性ブール値を設定しましたWidgetControllerWidgetControllerこのフラグをチェックするのに時間がかかることがあることを除いて、これはすべて正常に機能したので、割り込みメソッドを使用できるようにする必要があります。

疑似例

ユーザーが[開始]をクリックするとダイアログが表示されます。WidgetDialogListenerこれにより、のインスタンスが作成されWidgetWorker、これが開始WidgetControllerされ、が表示されます。通常の表示がWidgetProgressDialog完了すると、実行内容の概要が表示されます。WidgetControllerShowWidgetReportWidgetController

WidgetControllerが実行されている間、WidgetProgressDialog進行状況を示すが表示されます。ユーザーがキャンセルボタンをクリックして進行を停止すると、実際に完了するのを待たずWidgetControllerに割り込みが送信さ れ、doneメソッドが呼び出されて表示されます。しかし、実際に完了するまで、これを実行したくありません。widgetcontrollerShowWidgetReportWidgetController

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スレッド。

4

0 に答える 0