En général, SwingWorker est utilisé pour effectuer des tâches de longue durée dans Swing.
L'exécution de tâches longues sur l'Event Dispatch Thread (EDT) peut provoquer le blocage de l'interface graphique. SwingUtilities.invokeLater
et invokeAndWait
qui permet à l'interface graphique de rester réactive en donnant la priorité aux autres événements AWT avant d'exécuter la tâche souhaitée (sous la forme d'une commande Runnable
).
Cependant, le problème avec SwingUtilities
c'est qu'il ne permettait pas de renvoyer des données à partir de l'exécution. Runnable
à la méthode originale. C'est ainsi que SwingWorker
a été conçu pour répondre aux besoins.
Le tutoriel Java comporte une section sur SwingWorker .
Voici un exemple où un SwingWorker
est utilisé pour exécuter une tâche fastidieuse sur un thread séparé, et affiche une boîte de message une seconde plus tard avec la réponse.
Tout d'abord, une classe étendant SwingWorker
sera faite :
class AnswerWorker extends SwingWorker<Integer, Integer>
{
protected Integer doInBackground() throws Exception
{
// Do a time-consuming task.
Thread.sleep(1000);
return 42;
}
protected void done()
{
try
{
JOptionPane.showMessageDialog(f, get());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Le type de retour de la fonction doInBackground
et get
sont spécifiées comme le premier type de l'élément SwingWorker
et le second type est le type utilisé pour le retour de l'objet publish
et process
qui ne sont pas utilisées dans cet exemple.
Ensuite, afin d'invoquer le SwingWorker
le execute
est appelée. Dans cet exemple, nous allons accrocher un ActionListener
à un JButton
pour exécuter le AnswerWorker
:
JButton b = new JButton("Answer!");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
new AnswerWorker().execute();
}
});
Le bouton ci-dessus peut être ajouté à un JFrame
et cliqué dessus pour obtenir une boîte de message une seconde plus tard. Les éléments suivants peuvent être utilisés pour initialiser l'interface graphique d'une application Swing :
private void makeGUI()
{
final JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new FlowLayout());
// include: "class AnswerWorker" code here.
// include: "JButton" b code here.
f.getContentPane().add(b);
f.getContentPane().add(new JButton("Nothing"));
f.pack();
f.setVisible(true);
}
Une fois l'application lancée, il y aura deux boutons. L'un intitulé "Répondre !" et l'autre "Rien". Lorsque l'on clique sur le bouton "Answer !", rien ne se passe au début, mais si l'on clique sur le bouton "Nothing", cela fonctionne et démontre que l'interface graphique est réactive.
Et, une seconde plus tard, le résultat de la AnswerWorker
apparaîtra dans la boîte de message.