IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

EDT/SwingWorker Java Discussion :

Thread vs SwingWorker


Sujet :

EDT/SwingWorker Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 70
    Par défaut Thread vs SwingWorker
    Bonjour,

    je viens de découvrir l'existence de SwingWorker, et je me demandais ce que ça apportait de plus qu'un simple Thread...

    J'ai un peu googeulisé le truc, et apparemment, SwingWorker serait utilisé quand on veut modifier des éléments d'une GUI, et autrement on prendrait un Thread classique...

    Sauf que personnellement j'ai toujours mis à jour mes GUI avec des Thread, et ça ne m'a jamais posé de problème jusqu'à maintenant !

    Je viens encore à l'instant de faire une JProgressBar mise à jour depuis un Thread, lancé lui même depuis un click sur un JButton, et elle marche nickel (pourtant le Thread est très lourd, il rend la main à swing en faisant des appels à yield() de temps en temps dans la boucle de traitement)

    Donc ma question est simple, que pourrait m'apporter de plus cette classe SwingWorker ? (si ce n'est m'embrouiller la tête avec de nouvelles méthodes alors ma fonction run() me convenait)

    Merci !

    PS : J'me rend compte que le sujet à déjà du être abordé 20 fois, mais comme j'ai pas écris ça pour rien, je le poste quand même

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    le swingworker présente quelques facilités:

    la notion de propriétés et de propertychangelistener, qui permet d'ajouter des listener, par exemple sur la progression de la tâche
    l'appel d'une méthode done() en fin de travail (permet de faire des trucs spécifiques à la fin du boulot)
    une méthode progress qui est garantie d'etre appelée au sein de l'event dispatch thread (ce qui permet de manipuler les composant swing)

    Pour info, bien souvent on manipule allègrement les composant swing depuis n'importe quel thread. Masi ces composants ne sont pas thread-safe et devraient, normalement, n'être accéder que depuis le Thread AWT. Swingworker gère çà.

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 277
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 277
    Par défaut
    Si je ne dis pas de bêtises, les composants Swing (sauf certains et c'est spécifié dans la doc), ne sont pas thread safe.
    Ils doivent dont être "manipulés" dans l'EDT, le thread responsable des traitements liés à l'interface graphique.
    Si tu ne le fais pas, tu peux avoir des problèmes.
    Il vaut donc mieux le faire, ça t'éviterait un jour de tomber sur des bugs bizarres.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 70
    Par défaut
    ok, donc en gros dans les 3/4 des usages basiques un thread pourrait faire l'affaire, mais dans le cas de grosses usines à gaz où les threads se multiplient et touchent aux mêmes objets graphiques (genre la GUI d'eclipse ou de netbeans, pas mon truc à 3 JButtons qui se battent en duel !) il faut mieux faire ça proprement avec SwingWorker.

    Pour finir les bonnes pratiques recommandent de faire du SwingWorker tout le temps même avec des Threads simples dès lors qu'on touche à swing, comme ça pas de mauvaises surprises.


    Bon... Ca m'embête, j'm'étais bien habitué à mes threads...

    Je vais donc devoir faire de l'auto-persuasion pour me faire écrire doInBackground() plutôt que run()

  5. #5
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par cho7 Voir le message
    ok, donc en gros dans les 3/4 des usages basiques un thread pourrait faire l'affaire, mais dans le cas de grosses usines à gaz où les threads se multiplient et touchent aux mêmes objets graphiques il faut mieux faire ça proprement avec SwingWorker.
    Non, même avec un seul Thread, même si c'est rare, tu pourrais avoir des problème. N'oublie pas que les gestion de bases d'évènement font aussi des modifs sur les composants. Exemple, tu réagit à un redimensionnement de fenetre en redessinant une ilmage, tu manipule le JPanel contenant l'image dans un Thread à part, mais swing va aussi manipuler ce JPanel pour le redimensionner.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 277
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 277
    Par défaut
    Si tu ne veux pas utiliser SwingWorker, tu peux.
    Dans ce cas là, dans les threads où tu as besoin de toucher à l'interface, place ces modifs dans un runnable que tu passes à la méthode invokeLater.
    C'est juste que SwingWorker masque tout ça et au final c'est plus simple.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 70
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Non, même avec un seul Thread, même si c'est rare, tu pourrais avoir des problème. N'oublie pas que les gestion de bases d'évènement font aussi des modifs sur les composants. Exemple, tu réagit à un redimensionnement de fenetre en redessinant une ilmage, tu manipule le JPanel contenant l'image dans un Thread à part, mais swing va aussi manipuler ce JPanel pour le redimensionner.
    Hum, vu sous cet angle... Bon, promis j'essais de mettre du SwingWorker dans mes prochaines applis

    Merci pour l'éclaircissement !

  8. #8
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,



    Tu peux tout à fait utiliser un thread, mais dans ce cas tu devras utiliser SwingUtilities.invokeLater() lorsque tu veux mettre à jour la GUI. Sinon tu risques de te retrouver avec des erreurs aléatoires selon les exécutions.

    Le fait que tu utilises des yield() me laisse craindre le pire : ce ne serait pas une rustine permettant de cacher ces erreurs aléatoires ???


    SwingWorker permet de faire un cadre de travail pour ce genre de tâche :
    • doInBackground() te permet d'exécuter les actions "lourdes" dans une tâche de fond, sans que cela ne bloque l'interface graphique.
    • done() (optionel) te permet de mettre à jours l'affichage à la fin du traitement.
    • process() (optionel) te permet de mettre à jours des données intermédiaire récu pendant le traitement via publish()
    • Enfin setProgress() te permet de mettre à jour une ProgressBar via un PropertyListener. Le seul défaut c'est qu'à ma connaissance il n'y ait rien de tout fait dans l'API standard, mais ce n'est pas la mort à coder pour que les modifications du SwingWorker soit répercuté sur une progressbar :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      class ProgressBarListener implements PropertyChangeListener {
       
      	private final JProgressBar progressBar;
       
      	public ProgressBarListener(JProgressBar progressBar) {
      		this.progressBar = progressBar;
      	}
       
      	@Override
      	public void propertyChange(PropertyChangeEvent evt) {
      		// En cas de changement de la valeur de progression
      		if ("progress".equals(evt.getPropertyName())) {
      			// On change directement la valeur de la ProgressBar
      			this.progressBar.setValue(((Integer)evt.getNewValue()).intValue());
      		} else if ("state".equals(evt.getPropertyName())) {
      			// En cas de changement de l'état du SwingWorker :
      			SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
      			switch(state) {
      			case PENDING: // En attente de démarrage
      			case STARTED: // Démarrage du SwingWorker
      				// On initialise la progressBar au minimum
      				this.progressBar.setValue(this.progressBar.getMinimum());
      				break;
      			case DONE: // SwingWorker terminé :
      				// On met au maximum
      				this.progressBar.setValue(this.progressBar.getMaximum());
      				break;
      			}
      		} 
      	}
      }




    Je pense que le mieux serait de prendre un cas concret, et de le faire avec les deux méthodes pour vori ce que ca donne comme différence


    a++

  9. #9
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 909
    Billets dans le blog
    54
    Par défaut
    Citation Envoyé par cho7 Voir le message
    Sauf que personnellement j'ai toujours mis à jour mes GUI avec des Thread, et ça ne m'a jamais posé de problème jusqu'à maintenant !
    Citation Envoyé par fr1man Voir le message
    Il vaut donc mieux le faire, ça t'éviterait un jour de tomber sur des bugs bizarres.
    Citation Envoyé par tchize_ Voir le message
    Non, même avec un seul Thread, même si c'est rare, tu pourrais avoir des problème.
    Yep et c'est en parti la faute de Sun car jusqu'aux alentours de 2002~2003 ils n'ont jamais vraiment insiste sur ce fait et pas mal de leurs exemples et didacticiels anterieurs, certains aussi vieux que l'AWT elle-meme, presentent ces defauts. De meme on trouvera nombre de livres faits par des auteurs et maisons d'editions tres respectables qui passent allegrement sur la chose.

    La regle a retenir avec les acces directs venant d'une autre Thread c'est : ce n'est pas parce que ca fonctionne la, maintenant, tout de suite sur ton ordi, sur cet OS et avec cette JVM, que cela fonctionnera forcement sur un autre ordi, un autre OS et une autre JVM (differente version, different vendeur). Donc il faut revenir aux methodes conseillees/indiquees.

    Je pressent quelques problemes similaires dans JavaFX : aucun des didacticiels et tres peu de presentations actuelles parlent du modele de threading et des interraction entre la thread de JavaFX (si jamais il y en a une), celle de l'interpreteur (dans le cas ou on veut faire du JavaFX interprete au lieu de compile), l'EDT quand on manipule directement les wrappers fournis ou quand on se fait ses propres SwingComponent, les divers threads des TimeLine (a moins qu'il n'y en ait qu'une seule partagee par toutes les TimeLine comme le suggerait une presentation du dernier JavaOne) et les threads annexes qu'on peut etre ammenees a creer pour manipuler entre autre sockets, longs chargements et acces aux BD... Sans parler des propagations des valeurs quand on fait du binding ou du trigger replace...
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. JProgressBar et Thread avec SwingWorker
    Par sebastien61 dans le forum EDT/SwingWorker
    Réponses: 5
    Dernier message: 13/05/2009, 16h08
  2. Lancé un thread SwingWorker depuis un autre thread SwingWorker
    Par romuluslepunk dans le forum EDT/SwingWorker
    Réponses: 5
    Dernier message: 14/03/2009, 18h58
  3. [SwingWorker] doInBackground() récursif = threads résiduels ?
    Par chrisRg2r dans le forum EDT/SwingWorker
    Réponses: 6
    Dernier message: 17/09/2008, 17h53
  4. [SwingWorker] Thread.sleep(x) et done()
    Par SpecialCharacter dans le forum EDT/SwingWorker
    Réponses: 4
    Dernier message: 15/02/2008, 15h42
  5. SwingWorker Thread et JProgressBar
    Par keub51 dans le forum EDT/SwingWorker
    Réponses: 8
    Dernier message: 13/02/2008, 15h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo