juin
2006
Le portail anglophone java.sun.com a publié il y a quelques jours un article qui présente quelques unes des petites améliorations de Java SE 6 (Mustang).
On peut y lire en particulier toute une section concernant la « nouvelle » classe SwingWorker… En effet même si elle n’a jamais fait partie de l’API standard, ce n’est pas vraiment une nouvelle classe puisqu’elle existe depuis pas mal de temps, et qu’elle disponible en téléchargement dans le tutoriel de Sun concernant les Threads et Swing…
Elle sera ainsi finalement intégré dans l’API de Mustang, mais pour cela elle a été totalement remanié afin de bénéficier des améliorations apportées au langage entre-temps (en particuliers avec Java 5.0).
Mais a quoi sert-elle ?
Comme chaque développeur Swing le sait (ou devrait le savoir), Swing utilise un thread dédié, l’Event-Dispatching Thread (EDT), qui s’occupe à la fois de mettre à jour l’affichage et de traiter les différents évènements de l’application. Ainsi, toutes les actions que l’utilisateur effectuera via l’interface graphique (clic de souris, raccourci-clavier, etc…) seront exécuté dans ce thread.
Cela implique que tout code qui modifie ou qui dépend de l’état d’un composant Swing doit être exécuté depuis le thread de l’EDT (mis à part quelques exceptions…). A l’inverse, il faut éviter d’effectuer des traitements long ou bloquant dans ce thread, car cela l’empêchera de mettre à jour l’affichage et de traiter les évènements, et on se retrouve alors avec une interface figé…
C’est pour cela qu’on est obligé de jouer avec les méthodes SwingUtilities.invokeLater() et SwingUtilities.invokeAndWait() afin de « passer » les traitements à l’EDT :
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// mise à jour de l'interface graphique
}
});
Problème : cela s’avère assez complexe à gérer, et oblige à jongler entre différents threads…
La classe SwingWorker permet ainsi de gérer facilement ces tâches. Elle se présente comme une classe abstraite qu’il faut étendre pour redéfinir la méthode doInBackground(). Le code de cette méthode sera exécuté dans un thread séparé, et une fois qu’il sera fini, la méthode done() sera exécuté dans le thread d’EDT afin de mettre à jours l’affichage de l’application.
De plus, elle permet de gérer simplement l’état d’avancement du traitement, grâce à la méthode setProgress(), qui générera un évènement afin de modifier l’état d’une barre de progression, ou encore la méthode publish(), qui, appellé depuis la méthode doInBackground(), permet de « passer » des objets vers une méthode process() qui sera exécuté dans l’EDT…
Il ne nous reste donc plus qu’à redéfinir les méthodes que l’on a besoin afin que les différents traitements soient exécutés dans leurs threads respectifs…
Plus d’info dans la javadoc de SwingWorker…
Tutoriels
Discussions
- Difference de performances Unix/Windows d'un programme?
- Définition exacte de @Override
- Classes, méthodes private
- [ fuite ] memoire
- jre 1.5, tomcat 6.0 et multi processeurs
- [REFLEXION] Connaitre toutes les classes qui implémentent une interface
- Possibilité d'accéder au type générique en runtime
- Recuperation du nom des parametres
- L'apparition du mot-clé const est-il prévu dans une version à venir du JDK?