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

Composants Java Discussion :

update jLabel avec thread


Sujet :

Composants Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 7
    Par défaut update jLabel avec thread
    Bonjour

    voilà un petit moment que je bloque sur comment mettre à jour un Jlabel à partir d'un autre thread

    j'ai une structure à peu près MVC..
    mon Main lance un thread contrôleur qui écrit les data dans le model
    et le Thread graphique (swing) qui lit les data du model

    Comment faire pour que je puisse mettre à jour un jLabel du thread graphique à partir du thread contrôleur ??

    je ne sais pas vers quoi me diriger, des listeners ?

    ou mieux pourrait on associer une variable du model à a ce jLabel et dès qu'elle est modifiée dans le model, le jLabel se met à jour automatiquement ?!

  2. #2
    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
    Le binding est là pour toi.

    Un framework permettant de faire du binding modèle/composant en Swing de façon propre:

    http://www.jgoodies.com/downloads/libraries.html
    Deux articles du créateur du framework expliquant la base du concept de bindings:
    http://www.jgoodies.com/articles/pat...nd-binding.pdf
    http://www.jgoodies.com/articles/binding.pdf

    Une suite de quatre tutos basé sur cette librairie (bien lire jusqu'au quatrième article):
    http://www.javalobby.org/java/forums/t17672
    http://www.javalobby.org/java/forums/t17707
    http://www.javalobby.org/java/forums/t17728
    http://www.javalobby.org/java/forums/t17788.html


    En ce qui concerne la gestion des Threads la question est plus générale.
    L'appli Swing est automatiquement lancée dans son propre Thread,appelé EDT (d'ailleurs il est de bon aloi d'instancier la classe créant la JFrame initiale via un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SwingUtilities.invokeLater(Runnable r)
    et ne surtout pas inclure la création du GUI dans le scope d'un )

    La récupération des données (action longue) doit se faire dans un Thread à part, toutefois l'affectation de ces données au modèle doit se faire dans l'EDT. Pour demander l'exécution de code dans l'EDT il faut passer par la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SwingUtilities.invokeLater(Runnable r)
    , sachant que toute modification d'un composant et de son modèle doit être réalisée dans l'EDT.

    Pour faciliter ce genre de chose il existe une classe utilitaire des plus pratique, à savoir le SwingWorker, voici un tutoriel sur son utilisation: http://rom.developpez.com/java-swingworker/

    Ensuite au niveau organisation, voici comment procéder:

    Avoir un contrôleur/Presenter globale qui va créer les composants, le modèle et gérer les bindings. Ce contrôleur va aussi s'occuper de la récupération des données en lançant un SwingWorker. SwingWorker auquel on aura fourni une référence sur le contrôleur. Ce SwingWorker va s'occuper de récupérer les données dans le doInBackground (qui est exécutée dans un thread à part), puis appeler une méthode du contrôleur pour lui passer les données dans la méthode done (qui est exécutée dans l'EDT). A toi de voir si tu préfères binder un nouveau modèle ou juste modifier le modèle déjà bindé.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 7
    Par défaut
    Merci, je regarde un peu ce framework
    cependant n'ayant qu'un voir au pire 2, 3 champs textes, l'utilisation d'un tel framework ne risque pas d'être surdimensionnée ?

    Citation Envoyé par sinok Voir le message
    L'appli Swing est automatiquement lancée dans son propre Thread,appelé EDT (d'ailleurs il est de bon aloi d'instancier la classe créant la JFrame initiale via un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SwingUtilities.invokeLater(Runnable r)
    et ne surtout pas inclure la création du GUI dans le scope d'un
    ah ben justement je ne maitrise pas trop ce point, ayant testé les deux et voyant que ça ne change rien, j'utilisais Thread.start()...

    Citation Envoyé par sinok Voir le message
    La récupération des données (action longue) doit se faire dans un Thread à part, toutefois l'affectation de ces données au modèle doit se faire dans l'EDT. Pour demander l'exécution de code dans l'EDT il faut passer par la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SwingUtilities.invokeLater(Runnable r)
    , sachant que toute modification d'un composant et de son modèle doit être réalisée dans l'EDT.
    là je crois est la faiblesse de mon code. j'ai dérivé du modèle MVC
    l'affectationde données dans le modele se fait dans le controleur et non dans l'EDT ( la vue). l'EDT ne fait que consulter le modèle.

    ça implique de grave conséquences ?

  4. #4
    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
    oui et non.

    Non dans le sens que vous ne verrez probablement aucune différence

    oui dans le sens que toute l'api de swing n'est pas multi thread, elle est mono thread. Elle ne s'attends donc pas à une modification concurrente de ses valeurs pendant qu'elle affiche.

    Imagine ce que ca donenrais par exemple si, au moment de se dessiner, le JLabel constate qu'il a comme chaine "Bienvenue Ô grand adminsitrateur", qu'il itaère caractère par caractère sur la chaine et que en plein milieu de l'opération ca deviens "Merci au revoir". Tu va finir avec un ArrayOutOfboundException sortis de nulle part dont tu comprendra jamais l'origine. Travailler en dehors de l'EDT pour la manipulation des composant swing, c'est ça, risquer de finir avec des erreurs aléatoire incompréhensibles.

  5. #5
    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
    Basiquement, ton contôleur devrait s'exécuter dans l'EDT et lancer des tâches longues hors EDT.


    Petit exemple sur comment doit se dérouler une interaction Swing/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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
     
    package edt;
     
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.SwingUtilities;
     
    public class MyEdtTest {
     
        private JFrame f;
        private JLabel l;
        private int i;
     
        public MyEdtTest() {
            f = new JFrame();
            l = new JLabel("Avant Thread");
            l.setHorizontalAlignment(JLabel.CENTER);
            f.add(l);
            f.setSize(400,300);
            f.setLocationRelativeTo(null);
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setVisible(true);
     
            Runnable threadTask = new Runnable() {
     
                @Override
                public void run() {
                    for( i = 0; i<15; i++) {
     
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        SwingUtilities.invokeLater(new Runnable() {
     
                            @Override
                            public void run() {
                                l.setText(i/2.0f+" s écoulées");
     
                            }
                        });
                    }
     
                    SwingUtilities.invokeLater(new Runnable() {
     
                        @Override
                        public void run() {
                            l.setText("Thread fini");
     
                        }
                    });
     
                }
            };
     
            new Thread(threadTask).start();
        }
     
        /**
         * @param args
         */
        public static void main(String[] args) {
     
            SwingUtilities.invokeLater(new Runnable() {
     
                @Override
                public void run() {
                    new MyEdtTest();
     
                }
            });
     
        }
     
    }
    On voit bien ici que tous les appels aux méthodes Swing sont se déroulent bien dans l'EDT et que les tâches longues (ici le Thread.sleep remplaçant un appel à un SGBD) se déroulent dans un Thread tiers.

Discussions similaires

  1. [SWING] Exception bizarre avec Thread
    Par Gob4 dans le forum Débuter
    Réponses: 2
    Dernier message: 13/09/2005, 21h55
  2. Update, décalage avec suppression
    Par moulette85 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 04/05/2005, 13h39
  3. [MFC] Cherche Timer avec thread
    Par romeo9423 dans le forum MFC
    Réponses: 17
    Dernier message: 09/03/2005, 10h33
  4. Variable static avec thread
    Par oxor3 dans le forum Threads & Processus
    Réponses: 7
    Dernier message: 27/08/2004, 11h45
  5. Update champ avec le meme champ de la meme table
    Par Baquardie dans le forum Langage SQL
    Réponses: 7
    Dernier message: 04/06/2004, 11h17

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