Les toolkits graphiques et les threads

Depuis une vingtaine d’années, les applications sont de plus en plus dotées d’interfaces graphiques, les GUI. Celles-ci ont été une révolution pour l’utilisation des machines. Cela dit, pour nous, développeurs, cela a introduit de nouvelles pratiques.

En fait, un toolkit graphique fonctionne généralement dans un thread dédié, l’Event-Dispatch-Thread en Swing. Il fonctionne de la manière suivante en boucle infinie :

  1. Recevoir du système d’exploitation les événements utilisateur tels que les clics de souris ou les entrées clavier.
  2. Notifier les composants de la vue qui ont reçu les événements (d’où le « dispatch » d’Event Dispatch Thread) de façon à ce que chacun d’eux déclenche le gestionnaire correspondant.
  3. Rafraîchir l’affichage.

Ces étapes se font en réalité plus ou moins simultanément, en particulier la première et la deuxième. Cela dit, ce fonctionnement a une implication : un gestionnaire d’événement d’un composant ne doit pas prendre longtemps à s’exécuter, quelques millisecondes tout au plus, sinon il empêche le rafraîchissement de la fenêtre. C’est comme ça que Windows par exemple peut afficher qu’un programme ne répond pas, parce qu’il est bloqué dans un gestionnaire d’événement.

J’ai un traitement long à lancer quand l’utilisateur clique sur un bouton, comment faire ?

C’est là que les threads interviennent. Ceux-ci permettent en effet de lancer de manière asynchrone un traitement. Autrement dit le fait que le nouveau thread lancé fasse un calcul intensif n’empêche pas le rafraîchissement de la GUI.

Néanmoins, il faut faire très attention avec les threads, car les toolkits graphiques ne sont généralement pas thread-safe, hormis certaines méthodes explicitement documentées comme telles. Ce billet explique pourquoi. Ceci peut se traduire par des affichages corrompus ou tout simplement des fenêtres qui ne s’affichent pas, si vous n’y prenez pas garde.

Dès lors, pour rafraichir un composant graphique depuis un thread, il convient d’utiliser les méthodes ou objets suivants :

  • En Swing, il faut utiliser SwingUtilities.invokeLater() dans le cas général, ou SwingUtilities.invokeAndWait() si vous désirez une réponse de l’utilisateur avant de poursuivre un traitement. A noter que depuis Java 6.0 vous avez aussi les SwingWorker qui peuvent aider mais qui n’est pas applicable dans tous les cas.
  • En SWT, il faut utiliser Display.getDefault().asyncExec() de façon à rafraîchir l’affichage.
  • Enfin, en JavaFX 2.0, qui est le successeur de Swing, il faut utiliser Platform.invokeLater().

Rafraîchir une GUI sur un objet en cours de calcul

Ayant déjà été confronté au problème dans mon jeu de Puissance 4 je vous partage une astuce qui peut vous servir si vous voulez rafraîchir votre GUI avec un objet en cours de calcul via une méthode du type SwingUtilities.invokeLater() : transférez à votre toolkit graphique une copie de votre objet et non l’original lui-même. ne copie par référence ne suffit pas, il faut une copie en profondeur avec un constructeur par recopie ou la méthode clone(). Si vous ne le faites pas, rien ne vous garantit qu’entre le moment où vous aurez soumis l’objet à votre toolkit graphique et le moment où il sera pris en compte pour l’affichage son état sera resté le même…

Cet article vous a plu ? Vous aimerez sûrement aussi :

Julien
Moi c’est Julien, ingénieur en informatique avec quelques années d’expérience. Je suis tombé dans la marmite étant petit, mon père avait acheté un Apple – avant même ma naissance (oui ça date !). Et maintenant je me passionne essentiellement pour tout ce qui est du monde Java et du système, les OS open source en particulier.

Au quotidien, je suis devops, bref je fais du dév, je discute avec les opérationnels, et je fais du conseil auprès des clients.

Son Twitter Son LinkedIn

gojul

Recent Posts

On accueille le nouveau CTO 🎉

Un nouveau capitaine technique débarque à la barre de WeLoveDevs ! Après le rachat par…

3 jours ago

AI Act for Developers : comprendre les 5 niveaux de risques

L’AI Act pour les développeurs, c’est la première loi vraiment impactante depuis le RGPD. Et…

1 semaine ago

Angular, mais en mode « easy » : interview avec Gaetan Redin.

"Venez, faites le module 1 et on en reparle." C’est le défi lancé par Gaetan…

2 semaines ago

OWASP Top 10 : 10 erreurs que les développeurs web font tous les jours (et comment les éviter)

L’OWASP Top 10, c’est un outil pour les développeurs web. Et pourtant, il est largement…

3 semaines ago

RGPD pour les développeurs : coder la confiance avant tout.

Dans cet article, on va parler du RGPD pour les développeurs. C’est un sujet que…

1 mois ago

Monolithe vs Microservices : comment choisir la bonne architecture pour votre application ?

En 2025, le débat monolithe vs microservices n’est toujours pas tranché. Faut-il garder une architecture…

1 mois ago