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

AWT/Swing Java Discussion :

Tache longue, progression et Swing


Sujet :

AWT/Swing Java

  1. #1
    Invité
    Invité(e)
    Par défaut Tache longue, progression et Swing
    Bonjour a tous,

    Je suis actuellement en train de finaliser un projet lié consistant a implémenter un algorithme génétique pour le problème du voyageur de commerce. L'algorithme est appliqué a un espace de 25 villes du monde. Je souhaitais a présent ajouter une gui permettant de régler les paramètres de l'algorithme, et pouvant afficher de façon graphique le trajet trouvé. J'exécute mon algorithme génétique, récupère le meilleur trajet trouvé, puis convertis les coordonnées (latitude / longitude) des villes par un service web fourni par Yahoo avant de les afficher. Seulement, le temps de déroulement de l'algorithme génétique et la récupération des coordonnées est "important" (une dizaine de secondes).

    Je souhaite donc faire en sorte que ce processus ne bloque pas le Gui, et affiche un avancement a l'utilisateur. Mon algorithme génétique ayant été codé comme une boite noire (je lance une méthode et obtiens le résultat final une fois tous les traitements effectués), j'ai procédé de la façon suivante pour obtenir l'avancement du processus :
    1. Créé un nouveau SwingWorker dans l'événement lançant l'AG
    2. Surchargé sa méthode doInBackground : j'y crée 2 threads : l'un lance le long processus, l'autre vérifie a intervalles réguliers son avancement (via un getter sur la longue tache) et publish cet avancement
    3. Surchargé sa méthode process qui récupère donc régulièrement l'avancement de la méthode "publié" dans le second thread de doInBackground, et met a jour l'interface


    Mon approche est-elle correcte ? Elle semble fonctionner, mais y a-t-il des choses auxquelles je dois être particulièrement attentif ? En termes de threads, j'ai surtout eu des cours théoriques, et peut-être un TP dessus l'an dernier, autant dire qu'il y a sans aucun doute des choses auxquelles je ne fais pas attention, c'est ce que j'aurais aime confirmer ou infirmer

    Merci de votre aide


    PS : je joins un exemple simplifie de ce que mon implémentation peut donner
    Fichiers attachés Fichiers attachés

  2. #2
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Pour moi cela semble correct.

    J'ai toutefois un conseil :
    • doInBackground() est lui-même lancé dans un thread. Mais il devient inutile car il ne fait qu'attendre que les deux threads se terminent. En fait tu pourrais te passer d'un de tes deux threads :
      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
      			@Override
      			protected Object doInBackground() throws Exception {
       
      				// Cree une instance de longue tache
      				final LongTask lt = new LongTask(times);
       
      				// Ce premier thread lancera l'execution de la longue tache
      				Thread tLaunch = new Thread(new Runnable() {
       
      					public void run() {
      						lt.longLaunch();
      					}
      				});
      				tLaunch.start();
       
      				while (lt.isOver() == false) {
      					publish(lt.getProgress());
      					try {
      						Thread.sleep(100);
      					} catch (Exception e) {
      						// ...
      					}
      				}
      				tLaunch.join();
      				publish(lt.getProgress());
      				return null;
      			}



    Sinon quelques remarques :
    • Même si tu effectues des publish() avec une seule valeur, il est possible que la méthode process() reçoivent plusieurs valeurs, dont il est préférable de parcourir tous les éléments de la liste, ou de récupérer le dernier dans ton cas (et non pas le premier).
    • Tu devrais également paramétrer la classe, afin de t'éviter certain cast :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      		SwingWorker<Object, Integer> worker = new SwingWorker<Object, Integer>() {
       
      			@Override
      			protected void process(List<Integer> progress) {
      				// Recupere l'avancement et met a jour l'interface (progress bar)
      				Integer currentValue = progress.get(progress.size()-1);
      				jpb.setValue(currentValue);
      			}
    • En principe tu devrais plutôt utiliser setProgress() de ton SwingWorker pour signaler l'avancement. Mais il faut alors utiliser un PropertyListener pour associer ces valeurs au JProgressBar ce qui peut rendre le tout plus lourd à écrire.
      L'utilisation de process() n'est pas la solution "normale" mais c'est tout aussi bien !
    • A la place du thread qui surveille ta tâche, tu pourrais utiliser le principe des listeners sur ta tâche longue. A chaque fois qu'il modifie son avancement, il émet un évènement que tu interceptes pour mettre à jour l'affichage...


    a++

  3. #3
    Invité
    Invité(e)
    Par défaut
    Wow alors ça c'est de la réponse ! Avant toute chose, merci beaucoup adiGuba
    Quelques remarques suite a tout cela :

    • Le coup de supprimer un thread : exact, j'avais oublié que ce qui est dans le SwingWorker est déjà dans un thread séparé...
    • Pour la récupération des valeurs dans process, en effet, c'était mal ! J'avais fait comme si la liste etait une pile (ne me demande pas pourquoi )
    • Pour le paramétrage de la classe, encore exact, décidément
    • Et enfin pour les PropertyListener... Eh bien tout simplement, je n'en connaissais pas l'existence ! Je ne sais pas si je l'implémenterai pour ce projet, car je devrais le faire passer a mon directeur de mémoire d'ici peu, mais je vais me pencher un peu dessus, ça semble vraiment intéressant... Merci d'avoir évoqué ça !


    Voilou
    Merci encore de la reponse je marque le sujet comme

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 03/02/2014, 11h03
  2. Indiquer la progression d'une tache assez lourde
    Par Steven62 dans le forum Silverlight
    Réponses: 2
    Dernier message: 14/08/2009, 18h35
  3. Bar de progression (pour calcul en tache de fond)
    Par batataw dans le forum Langage
    Réponses: 2
    Dernier message: 09/06/2009, 18h05
  4. [Swing][Thread] affichage fenetre pdt tache longue
    Par rems033 dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 09/08/2007, 14h39
  5. Sérialisation & info de progression via SWING
    Par Crypt dans le forum Langage
    Réponses: 18
    Dernier message: 25/11/2006, 12h30

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