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 :

Thread et Swing


Sujet :

AWT/Swing Java

  1. #1
    Membre averti
    Inscrit en
    Décembre 2005
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 19
    Par défaut Thread et Swing
    Bonjour,

    J'ai un problème au niveau de mon apllication, qui fait un traitement long (plusieurs heures) quand on appuie sur un boutton, et pour cela il faut le mettre dans un thread.

    J'ai donc lu ce tuto
    http://gfx.developpez.com/tutoriel/j...ing-threading/

    et je l'ai appliqué à mon application.

    Effectivement maintenant le boutton n'apparait plus comme enfoncée (bon signe) mais les autres bouttons de mon applications ne repondent toujours pas (notamment la croix pour fermer l'application ...).


    Quelqu'un serait pourquoi?

    Merci.

  2. #2
    Membre chevronné Avatar de xixi31
    Inscrit en
    Juin 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Juin 2005
    Messages : 423
    Par défaut
    salut,

    Le plus simple serait que tu fournisses un peu de code pour illustrer, parce que comme ca, ca va pas être évident de t'aider...

    xixi

  3. #3
    Membre averti
    Inscrit en
    Décembre 2005
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 19
    Par défaut
    ok, si ca peux aider ....

    code du boutton

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    begin.addActionListener(new ActionListener() {
    				public void actionPerformed(ActionEvent e) {
    					new Thread(new Runnable() {
    						public void run() {
    							SwingUtilities.invokeLater(new Runnable() {
    								public void run() {//traitement	}
    							});
    						}
    					}).start();
    				}
    			});
    exemple de code que je voudrais qui marche en parralèle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	f.addWindowListener(new WindowAdapter() {
    				public void windowClosing(WindowEvent e) {
    					System.exit(0);
    				}
    			});

  4. #4
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Fais voir le code du run de ton thread, j'ai comme l'impression que tu fais les traitements dans l'EDT alors qu'il faudrait que tu les fasse en dehors.....

  5. #5
    Membre chevronné Avatar de xixi31
    Inscrit en
    Juin 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Juin 2005
    Messages : 423
    Par défaut
    le mieux serait que tu effectue ton long traitement dans un autre thread que l'edt. c'est déjà ton cas??

  6. #6
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    C'est le cas

    Grosso modo le SwingUtilities.invokeLater() ne s'emploie que quand tu dois faire des modifications sur ton interface graphique, et surtout pas pour effectuer des calculs

  7. #7
    Membre averti
    Inscrit en
    Décembre 2005
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 19
    Par défaut
    bon voilà un bout de code du traitement (le reste c'est du même ordre )

    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
     
    while(true){
    										try{
    											wm un = new wm();
    											un.analyse(new URL(httpLink.getText()), lieux.getSelectedIndex()+3);
    											if(miniPowa.getText().compareTo("") == 0){
    											}
    											else{
    												Object resu =un.findMoshu(Integer.parseInt(miniPowa.getText()),Integer.parseInt(maxiPowa.getText()));
    												if(resu != null){
    													Runtime.getRuntime().exec(lecteurPath.getText() + " " + sonPath0.getText());
    													JOptionPane.showMessageDialog(null, "Alerte");
    												}
     
    }catch(Exception d){
    											d.printStackTrace();
    										}
    }
    Sinon si je mets du code dans un autre thread sans utiliser le invokeLater je vais pas respecter la règle du thread unique et qui d'après le tutoriel que j'ai lu est déconseillé ( car ca sera plus "thread safe"). C'est bien ca, non?

  8. #8
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    J'ai comme l'impression que tu n'a pas saisi toute la subtilité de bouzin....

    La règle du thread unique ne s'applique qu'aux modifications directes de l'interface, (encore heureux, sinon quelle serait l'utilité de créer de threads pour effectuier des calculs lourds....)

    Grosso merdo tu dois procéder de la façon suivante:

    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
     
     
    while(true){
      try{
        wm un = new wm();
        un.analyse(new URL(httpLink.getText()), lieux.getSelectedIndex()+3);
        if(miniPowa.getText().compareTo("") == 0){
        }
        else{
                Object resu =un.findMoshu(Integer.parseInt(miniPowa.getText()),Integer.parseInt(maxiPowa.getText()));
            if(resu != null){
                Runtime.getRuntime().exec(lecteurPath.getText() + " " + sonPath0.getText());
                SwingUtilities.invokeLater(new Runnable(){ public void run(){JOptionPane.showMessageDialog(null, "Alerte");});
                    }
        }
      }catch(Exception d){
        d.printStackTrace();                                        }
      }
    }

  9. #9
    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,


    La règle du thread unique ne concerne que l'accès aux composants de ton interface graphique, mais tous tes traitements long doivent être effectué dans un autre thread.

    Si tu utilises invokeLater() ton traitement long sera effectué dans l'EDT qui ne pourra plus mettre à jours l'affichage... Dans ton code tu utilises un Thread qui se contente de passer le traitement à l'EDT via invokeLater(), ce qui bloque toujours l'EDT, et ton Thread ne fait rien !!! La seule différence c'est que l'EDT aura le temps de finir de traiter l'évenement "onclick" sur le bouton et qu'il pourra donc le redéssiner dans son état normal avant de passer à sà tâche suivante : le traitement long que tu lui a passer via l'EDT...

    Et pendant qu'il effectuera ce traitement ton interface paraitra figé, puisqu'il ne pourra plus s'en occuper...


    Donc il faut bien que ce soit ton thread qui fasse le traitement long, et tu ne doit utiliser invokeLater() QUE pour mettre à jour l'affichage (et donc des traitements courts), par exemple :
    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
    bbegin.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            new Thread(new Runnable() {
                public void run() {
     
                    // traitement long ici
     
                    final String value = ...; // resultat du traitement
     
                    // On n'utilise invokeLater() que si on a besoin
                    // de mettre à jours un composant graphique
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            monJLabel.setText( value );
                        }
                    });
                }
            }).start();
        }
    });
    a++

  10. #10
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Oups pardon j'avais oublié la création du runnable pour le invokeLater je viens de m'en rendre compte...
    Con de mime


    Euh par contre, pour le choix de l'exemple adiguba, ce n'est pas le top car le setText() est une des rares méthodes présentes dans Swing qui soit thread-safe

  11. #11
    Membre averti
    Inscrit en
    Décembre 2005
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 19
    Par défaut
    ok merci j'ai compris le truc .
    J'ai testé mon appli et ca marche, merci

  12. #12
    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
    Citation Envoyé par sinok
    Euh par contre, pour le choix de l'exemple adiguba, ce n'est pas le top car le setText() est une des rares méthodes présentes dans Swing qui soit thread-safe
    Euh... Peut-être (je ne vois rien de tel dans la doc). Mais en général je préfère ne pas me poser de question et le faire dans l'EDT dans tous les cas...

    Citation Envoyé par alladdin
    ok merci j'ai compris le truc .
    Penses à utiliser le bouton alors

    a++

  13. #13
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Euh... Peut-être (je ne vois rien de tel dans la doc)
    Au temps pour moi, elle est safe pour les JtextComponent et classes filles, par pour un JLabel

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

Discussions similaires

  1. [Thread et Swing] Affichage retardé
    Par esteban dans le forum EDT/SwingWorker
    Réponses: 2
    Dernier message: 06/07/2007, 14h19
  2. Réponses: 4
    Dernier message: 03/11/2006, 15h35
  3. [Thread du Swing] Rend-moi la main quand t'as fini!
    Par janef dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 25/02/2006, 15h51
  4. [SWING] Exception bizarre avec Thread
    Par Gob4 dans le forum Débuter
    Réponses: 2
    Dernier message: 13/09/2005, 21h55
  5. [SWING][THREAD]Méthodes pour afficher une Frame
    Par pompidouwa dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 05/05/2004, 10h35

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