1

I have a SwingWorker called Task1,

class Task1 extends SwingWorker<Void, Void> {
        @Override
        public void doInBackground() {
            String[] args = {};
            try {
                FeatureSetBuilder.main(args); //<---It is a static method


            } catch (Exception e1) {
                e1.printStackTrace();
            }

            return null;
        }
        public void done() {

            UISettings.FP_GENERATOR_DIALOG_2.cancelButton.setEnabled(true);
            loadingDialog.progressBar.setIndeterminate(false);
            loadingDialog.setVisible(false);
        }
    }

And I have a button that will execute Task1,

         public void actionPerformed(ActionEvent e) {
                System.out.println("FeatureSetBuilder - Start");
                String[] args = {};
                try {
                    task1 = new Task1();
                    task1.execute();
                    loadingDialog.popOut(task1);
                    task1.cancel(true);



                } catch (Exception e1) {
                    e1.printStackTrace();
                }
                System.out.println("FeatureSetBuilder - Finished");

            }

When I click this botton, a dialog with a progress bar will pop out to indicate that the method FeatureSetBuilder.main(args) is running. When task1 completes, the method done() will then be called and close that dialog.

It works fine.

I want to add a Cancel button to that dialog so the user can terminate task1 whenever he wants.

Here is my Cancel button,

 cancelButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Stop the current SwingWorker");
                    task.cancel(true);
                    setVisible(false);
                }
            });

When I press the the Cancel button, the task 1 seems being terminated as "FeatureSetBuilder - Finished" is printed out. However, the static method FeatureSetBuilder.main(args) is still running.

Sanjay Manohar
  • 6,920
  • 3
  • 35
  • 58
Yu Coleman
  • 35
  • 4
  • This has little to do with Swing and all to do with -- `"how do I stop running Java code?"` First thing I'd do would be not to run another class's main method, but rather make the code more OOP-compliant. Next I'd look into some notification mechanism to allow any process to ask the running code to cleanly stop itself. As expected, the devil will be in the details. – Hovercraft Full Of Eels Nov 06 '15 at 17:04

1 Answers1

3

Your doInBackground method should be periodically checking whether the task has been cancelled. Example from SwingWorker class' javadoc:

@Override
public List<Integer> doInBackground() {
    while (! enough && ! isCancelled()) {
            number = nextPrimeNumber();
            publish(number);
            setProgress(100 * numbers.size() / numbersToFind);
        }
    }
    return numbers;
}

I really recommend that you read the javadocs of all classes/methods in SwingWorker and related classes. EventDispatchThread related problems can be very tricky.

Jaroslaw Pawlak
  • 5,538
  • 7
  • 30
  • 57
  • 1
    And see http://stackoverflow.com/questions/9536555/utility-of-future-cancelboolean-method – Sanjay Manohar Nov 06 '15 at 16:43
  • 1
    Besides checking for `isCanceled`, since OP is calling `task.cancel(true)` I would also handle interruption (as in `InterruptedException ` and `Thread.interrupted()`). Relevant Oracle Tutorial pages: [Canceling Background Tasks](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/cancel.html), [Interrupts](https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html). – Anthony Accioly Nov 06 '15 at 16:44
  • I get it. Thank you so much – Yu Coleman May 14 '16 at 09:51