Arrêter/annuler SwingWorker thread?

j'essaie de trouver comment empêcher un fil SwingWorker de fonctionner quand j'appuie sur un bouton. J'ai regardé autour de moi et j'ai du mal à trouver comment faire ça. Pour le moment c'est ce que j'ai:

new MySwingWorkerClass(args).execute();

je crée alors un bouton que je veux utiliser pour arrêter le thread:

button = new JButton("Stop");
button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) 
        {
        // Stop the swing worker thread
        }
});

j'ai déjà cherché une réponse, jusqu'à présent j'ai réussi à trouver la méthode d'annulation. Je ne comprends pas comment l'utiliser pour arrêter mon swing travailleur. J'ai essayé ce qui suit, mais il ne fonctionne pas:

SwingWorker.cancel(true);
26
demandé sur mre 2011-11-10 21:31:59

4 réponses

vous devez garder un référence SwingWorker, puis vous utilisez cette référence pour annuler le thread worker.

MySwingWorker myWorker = new MySwingWorkerClass(args).execute();

button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) 
    {
        // Stop the swing worker thread
        myWorker.cancel(true);
    }
});

Voici un exemple complet:

enter image description here

public class WorkerDemo extends JFrame {
    private boolean isStarted = false;
    private JLabel counterLabel = new JLabel("Not started");
    private Worker worker = new Worker();
    private JButton startButton = new JButton(new AbstractAction("Start") {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            if(!isStarted) { 
                worker.execute();
                isStarted = false;
            }
        }

    });
    private JButton stopButton = new JButton(new AbstractAction("Stop") {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            worker.cancel(true);
        }

    });

    public WorkerDemo() {

        add(startButton, BorderLayout.WEST);
        add(counterLabel, BorderLayout.CENTER);
        add(stopButton, BorderLayout.EAST);
        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    class Worker extends SwingWorker<Void, Integer> {

        int counter = 0;

        @Override
        protected Void doInBackground() throws Exception {
            while(true) {
                counter++;
                publish(counter);
                Thread.sleep(60);
            }
        }

        @Override
        protected void process(List<Integer> chunk) {

            // get last result
            Integer counterChunk = chunk.get(chunk.size()-1);

            counterLabel.setText(counterChunk.toString());
        }

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new WorkerDemo();
            }

        });
    }

}
38
répondu Jonas 2012-02-07 18:51:06

vous devez vérifier périodiquement son drapeau annulé (i.e. isCancelled()). SwingWorker laisse à vous le soin de gérer l'interruption.

Pour plus d'informations, voir Annulation De Tâches En Arrière-Plan.

14
répondu mre 2016-03-22 01:10:36

Vous pouvez essayer de surcharger la méthode done () et la mettre dans try catch et catch the java.util.simultané.CancellationException. Quelque chose comme

. . .

@Overide
done() {
   try {
     get();
   } catch (CancellationException e) {
       // Do your task after cancellation
   }
}

. . .

2
répondu rahul pasricha 2012-02-14 15:21:37

je pense que vous devez redémarrer le compteur après chaque arrêt.

pour startButton, vous devez faire redémarrer worker comme dans

private JButton startButton = new JButton(new AbstractAction("Start") {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            if(!isStarted) { 
                worker = new Worker();     // New line
                worker.execute();
                isStarted = false;
            }
        }
    });

pour arrêter vous pouvez utiliser

worker.setStopFlag(); // in stopButton actionPerformed block.

dans la classe ouvrière private boolean stopFlag = false;

if( stopFlag)
break;

après le fil.sommeil(60); et enfin mettre setter pour stopFlag à la fin de la classe ouvrière comme

void setStopFlag(){
    stopFlag = true;
}

en passant, vous pouvez utiliser cancel (true) si vous voulez avoir exception à la sortie.

2
répondu Hatto 2013-02-06 15:23:21