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 :

Gestion des threads dans une application swing


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    205
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 205
    Par défaut Gestion des threads dans une application swing
    Je ne sais pas trop où poster ma question ???

    Bon je la pose ici pour le moment !


    Bon en fait c'est une appli Swing, qui a une JFrame et 3 sous JPanel par exemple (appelés screen dans mon exemple et screens, la liste de ces JPanel)

    Et donc chaque JPanel représente un tableau de bord qui contient une valeur qui doit être raffraichie, et je cherche à calculer dans la JFrame la somme de ces valeurs, mais avec les Threads je m'embrouille un peu aussi, y'a l'EDT, et swingWorker, mais j'ai fait autrement, même si apparemment c'est pas thread safe ...

    Voilà le code :
    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
     
    // RefreshALL et calcul
    		JButton refresh2 = new JButton("RefreshAll");
    		refresh2.addActionListener(new ActionListener(){
    			public void actionPerformed(ActionEvent e) {
    				new Thread(new Runnable(){
    					public void run(){
    						try {
    							for (int i = 0; i < screens.size(); i++) {
    								Thread.sleep(50);
    								System.out.println("	--Nom  "+i+" :" +screens.get(i).getNomValeur());
    								screens.get(i).getRefresh().doClick();
    								if (i==0){
    									somme = 0.00;
    								}
    								somme += Double.valueOf(screens.get(i).getScreenCas().get(0).getPerformance().getText());
    							} 
    							sommeTotale.setText("Somme Totale : " + somme);
    						} catch (InterruptedException e) {
    							e.printStackTrace();
    						}
    					}
    				}).start();	
    				add(sommeTotale);
    			}
    		});
    et le problème, c'est que si je clique plusieurs fois d'affilée sur le bouton "refreshALL" ben il me foire le calcul, à cause des thread qui se croise !

    C'est dans l'initialisation de la somme, ou j'en sais rien, si quelqu'un à une idée merci !

  2. #2
    Membre expérimenté Avatar de Roy Miro
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    273
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 273
    Par défaut
    Bonjour,

    Pour le moment, je suppose que lorsque tu cliques sur "refresh all", tu créé un thread par screen qui va actualiser la valeur du screen. Tu as besoin de bloquer l'affichage de la somme jusqu'à ce que chacun de ces threads ait fini sa tâche.

    Tu as donc forcément 1 thread principal 'TP' et p-e n threads 't'(en supposant n screen).
    Tu pourrais créer un autre thread 'T' qui va, lui, créer les n thread t.

    Ensuite, TP va "joindre" T: Cela veut dire que, en supposant que TP récupère la somme totale pour l'afficher, il devra attendre que les n threads aient fini leur méthode run avant éventuellement d'actualiser son propre champ.

    Note: la somme totale peut-être représentée par un attribut sum de TP que tu passe à T qui lui va repasser aux t.

    Le problème dans ton code est que tu crééé un thread qui va s'exécuter de son côté (avec sa propre pile d'exécution), mais pendant ce temps ton code qui a créé le thread continue lui de s'exécuter jusqu'à atteindre et ce même si ton thread (qui vit sa vie à côté) n'a pas fini sa tâche.

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    205
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 205
    Par défaut


    Et il y a aussi le fait que en SWING, il y a l'histoire de l'EDT, qui normalement doit gérer tout, enfin, je m'attaquerais à sa plus tard !

    Donc je devrais faire hériter mes "screens" qui implémente JPanel, de Thread, ou Runnable ? ou un truc comme ca ?

    J'ai pas souvent programmé les THread, et je sais pas si c'est vraiment un système multithreadé que j'essaye de faire ...


    ET AUSSI, second problème, c'est que de la manière où j'ai programmé, je ne peux rien faire sur mes Threads, puisque je ne déclare pas d'instance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    JButton refresh2 = new JButton("RefreshAll");
    		refresh2.addActionListener(new ActionListener(){
    			public void actionPerformed(ActionEvent e) {
    				new Thread(new Runnable(){
    					public void run(){
    						try {
    							for (int i = 0; i < screens.size(); i++) {
    								Thread.sleep(50);
     
    .............
    .............
    }
    				}).start();
    je peux faire qu'une action, donc faudrait que je déclare une variable, c'est tout genre Thread t = new Thread ?


    Car disons qu'avant que je Thread mes "refresh" dans chaque JPanel, ben le refresh des JPanel était freezé pendant le temps de la mise à jour et donc, il attendait bien que ce soit fini pour passer au suivant ... Enfin je sais pas si je suis clair, merci en tout cas tu semble avoir compris mon problème ...

    Ou alors je décompose les actions de cette manière :
    1°) je refresh tous mes screen
    2°) je vais chercher la valeur de chacun

    Car actuellement je fais :
    1°) je refresh un screen, et je prends sa valeur
    2°) je refresh un screen, et j'ajoute sa valeur
    ... etc

  4. #4
    Membre expérimenté Avatar de Roy Miro
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    273
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 273
    Par défaut
    Bonjour,

    Si j'ai bien compris ton schéma, chacun de tes JPanel possède un bouton "maj". Chacun de ces boutons a sa méthode actionPerformed (comme tu as fait pour le refresh all).
    Pour un actionPerformed donné, tu as un code qui met à jour le JPanel auquel le bouton est lié. Donc quand tu clique sur ce bouton tu crééé un thread qui va mettre le JPanel à jour.
    Je te propose de sortir le code qui créé le thread de m.à.j de tes actionPerformed. Tu mets ce code dans une méthode à part. Puis tu appelles cette méthodes dans ton actionPerformed.
    Ensuite, dans le actionPerformed du refresh all, tu n'as plus qu'à appeler, pour chaque JPanel, cette méthode.

    Un exemple pour être plus clair:

    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
    public class MyPanel {
     
    private JPanel p;
    private JButton refresh;
    private String valeur;
     
    MyPanel(){
    ...
    refresh.addActionListener(new ActionListener(){
           public void actionPerformed(ActionEvent e) {
     
                     this.updatePanel();
           }
          });
           p.add(b);
    ...
    }
     
    void updatePanel(){
    //màj du panel
    MyRunnable myRunnable = new MyRunnable (valeur);
    Thread t = new Thread(myRunnable);
    }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class MyRunnable implements Runnable{
     
    private String stringToUpdate;
    MyRunnable (String s){
           this.stringToUpdate = s;
    }
     
    @Override
    public void run(){
         //aller chercher la nouvelle valeur et faire ce qu'il faut
          stringToUpdate = //nouvelle valeur
    }
    }
    Enfin, ta JFrame censé contenir tes MyPanel:
    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
     
    public class MyFrame {
     private JFrame f;
     private JButton refreshAll;
     private String somme;
     private MyPanel p1;
     private MyPanel p2;
     
     
    MyFrame(){
    ....
       refreshAll.addActionListener(new ActionListener(){
          public void actionPerformed(ActionEvent e) {
               Thread t = new Thread(new Runnable(){
                  public void run(){
                     update();
               }
             }});
    ...
    }
     
    void update(){
             p1.updatePanel();
             p2.updatePanel();
    }
     
    }
    Pour ne pas freezer quand tu cliques sur "refresh all", tu peux faire appel à l'EDT au niveau du actionPerformed du "refresh all" ou y créer un nouveau thread qui va appeler les updatePanel()

    Dis le si qqch n'est pas clair.

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    205
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 205
    Par défaut
    Salut, et merci pour ta réponse.

    Oui, je pense que c'est la solution à adopter, ca ordonnera un peu mieux les choses, bon là j'ai pas le temps, mais quand j'aurais essayé, je ferais un retour !


    Merci !

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    205
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 205
    Par défaut
    Bonsoir,

    Donc, je viens d'effectuer les modifications et ca fonctionne un peu mieux !

    Je suppose que tu avais omis, les Thread.Start(), après la création des Thread dans tes exemples de codes...

    Le souci, c'est que au premier coup que je clique "refresh All, il me calcul la "somme totale" et me donne Zéro "0.00", donc ca c'est car mes Thread ont pas encore mis la valeur à jour, et donc que toutes les valeurs de chacun de mes panels est initialisé à 0.00 et au 2ème coup, il me calcul la somme exacte ... Et le problème de si je clique à répétition qu'il me donne une somme fausse, ne se présente plus !


    Pour le "0.00" ca revient à ce que je disais au post précédents :

    Ou alors je décompose les actions de cette manière :
    I/1°) je refresh tous mes screen
    2°) je vais chercher la valeur de chacun

    Car actuellement je fais :
    II/1°) je refresh un screen, et je prends sa valeur
    2°) je refresh le screen suivant, et j'ajoute sa valeur
    ... etc


    code du refreshAll sur Jframe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // Update Panels
    	public void updatePanels(){
    		somme = 0.00;
    		for (int i = 0; i < screens.size(); i++) {
    			System.out.println("	--Nom  "+i+" :" +screens.get(i).getNom());
    			screens.get(i).updatePanel();
    			somme += Double.valueOf(screens.get(i).getScreenCas().get(0).getPerformance().getText());
    		} 
    		sommeTotale.setText("Somme Totale : " + somme);
    		add(sommeTotale);
    	}
    Le problème c'est qu'avec ce code, je ne vois pas le programme appuyé sur les boutons refresh de chaque panel, car j'utilise "update", bon c'est pas nécéssaire, mais ca donnait un rendu visuel qui montrait que les valeurs avaient été mises à jours et donc si je remplace dans le code précédents :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Ca :
    screens.get(i).updatePanel();
     
    Par ca :
    screens.get(i).GetRefresh2().DoCLick();
    Ben j'ai le rendu visuel, mais il me fait les mêmes erreurs qu'avant si je clique plusieurs fois sur le refresh ALL !

    Pourtant le code de mes Refresh des Jpanel est :
    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
     
    //Refresh2
    		refresh2 = new JButton("Refresh2");
    		refresh2.addActionListener(new ActionListener(){
    			public void actionPerformed(ActionEvent e) {
    				updatePanel();
    			}
    		});
    		add(refresh2);
     
     
    // UPDATE 
    	public void updatePanel(){
    		MyRunnable my = new MyRunnable(valeur, connector, this);
    		Thread t = new Thread(my);
    		t.start();
    	}
    Pourtant, tout ce que je fais de plus, c'est faire appel au bouton, qui lui même fait appel à updatePanel() !

Discussions similaires

  1. Utilisation des threads dans une application Perl/Tk
    Par Kroui dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 04/07/2011, 20h00
  2. Réponses: 0
    Dernier message: 24/06/2010, 12h11
  3. gestion des reporting dans une application wpf
    Par sanaaafkir dans le forum Windows Presentation Foundation
    Réponses: 6
    Dernier message: 16/05/2008, 14h02
  4. Gestion des droits dans une application Java
    Par Donaldo dans le forum Langage
    Réponses: 10
    Dernier message: 14/02/2008, 18h15
  5. XML/XSL et gestion des fichiers dans une application Web
    Par fatenatwork dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 01/02/2008, 14h09

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