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);
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:
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();
}
});
}
}
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.
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
}
}
. . .
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.