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 :

Swing et thread


Sujet :

EDT/SwingWorker Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de trax44
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    300
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 300
    Par défaut Swing et thread
    Faut il lancé ça GUI swing dans un thread a part ?
    J'ai vu pas mal de programme qui font ça et des elements de la faq qui en parle mais d'après ce que j'avais compris le fait de rendre visible une JFrame par exemple fait lancé un thread propre a la GUI.
    Personnelement, je n'ai jamais eu besoin de thread pour ça dans mes applications, et je n'ai jamais rencontré de problèmes ; mais peut etre que je n'étais pas dans les bonnes conditions. Alors threadé ou pas threadé ?

    Cordialement
    trax

  2. #2
    Membre chevronné Avatar de spekal
    Inscrit en
    Mai 2005
    Messages
    502
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 502
    Par défaut
    Oui, il faut toujours créer un thread à part, ou, plus exactement, toujours se placer dans le dispatching thread, dès le départ.

    Voici le modèle de la méthode main d'un programme swing, extrait d'une HelloWorld :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public static void main(String[] args) {
            //Schedule a job for the event-dispatching thread:
            //creating and showing this application's GUI.
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
    Au départ, sun disait que ce n'était pas la peine ; puis ils ont découvert un bug de conception, et, finalement, il faut toujours le faire.

  3. #3
    Membre éclairé Avatar de trax44
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    300
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 300
    Par défaut
    il a pas été corrigé depuis parce que pas mal de code présent sur le site de sun n'implemente pas de thread pour la GUI (ancien code ou code recent) ?

  4. #4
    Membre averti

    Profil pro
    Étudiant
    Inscrit en
    Juin 2005
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2005
    Messages : 32
    Par défaut
    Si tu sais lire l'anglais, je te conseille de télécharger le chapitre gratuit de: Desktop Java Live.

    Il couvre les Threads avec Swing. Je n'y ai que jeté un oeil pour le moment mais il sembe très bien fait.

    Sinon, il y a aussi un très bon article de Romain Guy sur Progx (recherche dans les archives)...

  5. #5
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 904
    Billets dans le blog
    54
    Par défaut
    Citation Envoyé par trax44
    il a pas été corrigé depuis parce que pas mal de code présent sur le site de sun n'implemente pas de thread pour la GUI (ancien code ou code recent) ?
    Disons qu'il ne suivent pas toujours eux-meme leurs propres recommandations (comme tout un chacun).

    Suivant les versions de la JVM et les OS sur lequel le programme s'execute ca peut plus ou moins causer de problemes.

    Dans mon cas j'utilisais des Window avec une barre de progression et un label de message pour afficher des ecrans de demarrage et la progression du lancement des mes programmes et ben d'un coups dans Java 1.5 et sous Linux (et uniquement avec cette version sous cet OS) le programme crashait lors de son initialisation car je manipulais la Window depuis la thread du main(). J'ai donc du tout deporter dans l'EDT a grands coups de SwingUtilities.invokeAndWait() et SwingUtilities.invokeLater(). Et hop tout remarche partout pareil partout sans se vautrer !
    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

  6. #6
    Membre éclairé Avatar de soad
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    520
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2004
    Messages : 520
    Par défaut
    juste une petite question aussi:

    Toute les modifications d'une interface swing doit être fait avec SwingUtilities ?

    par exemple un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    jTextField.setText("HAHAHAHAH");


    doit être fais comme cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
         public void run() {
               jTextField.setText("HAHAHAHAH");
         }
    });
    C'est un peu lourd non ?

  7. #7
    Expert confirmé
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Par défaut
    Tout modification de l'interface dans un thread séparé de l'EDT devrait être fait ainsi, mais il n'y a pas besoin de le faire quand on est dans l'EDT puisque invokeLater ajoute tout simplement l'événement dans l'EDT.

  8. #8
    Membre Expert
    Avatar de afrikha
    Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2005
    Messages : 1 600
    Par défaut
    Oui c'est un peu lourd, mais java 6 palièra ce problème grâce à la classe SwingWorker qui utilisera notamment la nouvelle (magnifique) api java.util.concurrent.
    Tu peux te procurer cette classe sur le site de Sun.
    Cherche sur google tu trouveras plein d'informations là-dessus.


    Mes publications
    Lisez
    Les régles du forum
    Pensez au bouton

  9. #9
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par TulipeMoutarde
    Si tu sais lire l'anglais, je te conseille de télécharger le chapitre gratuit de: Desktop Java Live.

    Il couvre les Threads avec Swing. Je n'y ai que jeté un oeil pour le moment mais il sembe très bien fait.

    Sinon, il y a aussi un très bon article de Romain Guy sur Progx (recherche dans les archives)...
    Les deux liens sont morts..
    Pour le liens ProgX c'est pas grave, je l'avait déja http://www.progx.org/

    mais pour le chapitre gratuit, ça m'embête un peu plus..

  10. #10
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    J'essaierai de reprendre ça quand j'aurai le temps...
    Merci pour l'info en tout cas!

  11. #11
    Membre averti

    Profil pro
    Étudiant
    Inscrit en
    Juin 2005
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2005
    Messages : 32
    Par défaut
    Citation Envoyé par Blaise1
    Les deux liens sont morts..
    Pour le liens ProgX c'est pas grave, je l'avait déja http://www.progx.org/

    mais pour le chapitre gratuit, ça m'embête un peu plus..

    bizarre je premier lien marche pourtant chez moi ?!

    Sinon va sur http://www.sourcebeat.com/ et cherche le livre Desktop Java Live de Scott Delap

  12. #12
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Citation Envoyé par spekal
    Oui, il faut toujours créer un thread à part, ou, plus exactement, toujours se placer dans le dispatching thread, dès le départ.

    Voici le modèle de la méthode main d'un programme swing, extrait d'une HelloWorld :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public static void main(String[] args) {
            //Schedule a job for the event-dispatching thread:
            //creating and showing this application's GUI.
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
    Au départ, sun disait que ce n'était pas la peine ; puis ils ont découvert un bug de conception, et, finalement, il faut toujours le faire.
    Wow! J'ai essayé, et ça ne marche pas top du tout!
    Voici le code de ma méthode createAndShowGUI() :

    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
     
    	public static void showGUI(){
    		try {
    			MaFrame inst = new MaFrame();
    			inst.setVisible(true);
    			DisplayLogo logo = new DisplayLogo();
    			Thread t1=new Thread(logo);
    			t1.start();
    			while(t1.isAlive()){
    			}
    			logo.garbageCollecting();
    			logo.removeAll();
    			logo=null;
     
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    où MaFrame est ma classe principale qui représente la frame principale de mon appli, et DisplayLogo est une classe qui est sensée afficher un splashscreen.

    Avec le coup du thread, mon splashscreen ne s'affiche pas et bloque toute l'appli. C'est grave docteur?

  13. #13
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 904
    Billets dans le blog
    54
    Par défaut
    A quoi sert la thread sur le logo ?

    Sinon j'ai peur qu'il ne te faille revoir ta fonction et insérer un ou plusieurs SwingUtilities.invokeAndWait() ou SwingUtilities.invokeLater() pour repartir ta procédure d'initialisation sur plusieurs troncons de l'EDT de manière à insérer un ou plusieurs cycle de repeinture (et de propagation d'évènements) entre les instructions et pouvoir ainsi voir s'afficher ton splash screen. Qq chose du genre (pas testé) :

    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
     
    /** Should be executed at EDT.
    */
    public static void createAndShowGUI(){
      /** @todo Verify we are at EDT and if not use SwingUtilities.invokeLater() to self-invoke. */
      try {
         // Create and display logo.
         final DisplayLogo logo = new DisplayLogo();
         // Initialize GUI. 
         // Normally the logo should have had time to appear.
         SwingUtilities.invokeAndWait(new Runnable() {
           /** @inheritDoc
            */
           public void run() {
              // We may want to update a progress bar on the logo or display initialization messages.
              MaFrame inst = new MaFrame(logo);
              inst.setVisible(true);
           }
         })
         logo.garbageCollecting();
         logo.removeAll();
       }
       catch (Exception e) {
         e.printStackTrace();
       }
    }
    Et dans le constructeur de ta classe MaFrame, si tu dois mettre à jour le logo alors à nouveau tu utilises SwingUtilities.invokeAndWait(). Le but du jeu n'est pas de forcement aller vite mais d'arriver à faire s'afficher les notifications sur l'écran de démarrage (rappel on insère ainsi des phases de repeinture entre des phases "actives" où le code s'exécute). Je pense que tu as plus de chance de voir les messages apparaitre avec SwingUtilities.invokeAndWait() qu'avec SwingUtilities.invokeLater() en effet on est déjà dans l'EDT (à priori) et donc il n'y aura pas de repeinture tant que l'initialisation de la frame ne sera pas terminée.

    Tu peux aussi également utiliser un Timer Swing plutot qu'une Thread pour patienter qq millisecondes entre l'initialisation de ton logo et le début de la construction/affichage de la frame.
    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

  14. #14
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Le thread sur le logo sert à ce que le splashscreen s'affiche tout en laissant à l'utilisateur la possibilité d'atteindre et d'utiliser l'IHM principale avant la fin du splashscreen. Enfin, c'est ce que j'en ai compris (c'est pas moi qui l'ait codé)
    Parce qu'en fait, le splashscreen étend JPanel, implémente l'interface Runnable et fait ça dans son run() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    this.setVisible(true);
    try {
    	Thread.sleep(3000);
    } catch (InterruptedException e) {
    	e.printStackTrace();
    }
    this.dispose();
    Et ça marchait très bien quand on appelait directement createAndShowGUI() dans la méthode main().

    Je teste ta méthode...

  15. #15
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    C'est pas convaincant...
    Sans la déclaration du thread, la méthode run() de DisplayLogo ne se lance pas, donc pas de splashscreen.

    Si je le rajoute, ça bloque avec le invokeLater() alors qu'avec le invokeAndWait() ça plante carrément : j'ai pas le droit de l'appeler dans l'EDT...

    En gros, quelle méthode utilisez-vous pour afficher un splashscreen?
    Je pense que mon souci vient de là en fait...

Discussions similaires

  1. Toujours Swing et Thread
    Par Patrice Henrio dans le forum EDT/SwingWorker
    Réponses: 18
    Dernier message: 14/02/2013, 22h13
  2. [Freeze Swing et Threads] Freeze lors d'un appel
    Par Tuxico dans le forum EDT/SwingWorker
    Réponses: 1
    Dernier message: 02/11/2008, 15h53
  3. Problème SWING et Threads
    Par CamilleH dans le forum AWT/Swing
    Réponses: 14
    Dernier message: 12/06/2008, 11h19
  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