1

Can I cancel a Swingworker and wait for it to complete before running background task? Or alternatively, can I send an interrupt to a task that runs the code in doInBackground() without cancelling the whole swing worker.?

My problem is I do not want the code in done() to start before the code in doInBackground() has completed. Earlier code never called cancel on the Swingworker instead I just set a volatile boolean that the WidgetController would check and if set closedown gracefully. This all worked fine except the WidgetController sometimes took to long to check this flag, so I need to be able use the interrupt method.

Pseudo Example

A dialog is displayed when user clicks start this invokes WidgetDialogListener this creates instance of WidgetWorker, this starts WidgetController, displays a WidgetProgressDialog and on normal completion of WidgetController displays ShowWidgetReport showing a summary of what WidgetController did.

Whilst the WidgetController is running, the WidgetProgressDialog is displayed showing progress. If the user clicks on the cancel button to stop progress this causes an interrupt to be sent to WidgetController then without waiting for widgetcontroller to actually complete the done method gets called causing ShowWidgetReport to display. But I don't want it to do this until WidgetController has actually completed.

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);
    }
}

Edit

I used the AwaitingWorker described at Waiting for a cancelled future to actually finish that Jacob pointed me to

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);
    }
}

Maybe have misunderstood exactly the solution but it seems whichever way you do it a gui thread ends up waiting for a non-gui task to finish, whereas what I want I want is for the non-gui task to complete before anything is done on the gui thread.

Community
  • 1
  • 1
Paul Taylor
  • 13,411
  • 42
  • 184
  • 351
  • See http://stackoverflow.com/questions/3522427/waiting-for-a-cancelled-future-to-actually-finish?rq=1 for ideas if you haven't already. – Jacob Raihle Jul 20 '12 at 13:25
  • @Paul Taylor not sure what do you really ..., can you please to [simulating your issue (just to add cancel() to the JButton)](http://stackoverflow.com/a/6186188/714968) – mKorbel Jul 20 '12 at 13:47
  • @mKorbel hi im sorry I dont understand what you are asking me – Paul Taylor Jul 20 '12 at 14:31

0 Answers0