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 :

JCombobox + ItemListener


Sujet :

Composants Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de kimausoleil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2004
    Messages : 126
    Par défaut JCombobox + ItemListener
    Bonjour,

    j'ai une combobox et des actions qui s'effectuent lorsque l'on sélectionne un "item".

    Or quand je remplis ma combobox, itemStateChanged est appelée à chaque élément ajouté et ça plante l'affichage !

    Donc je charge ma combobox par un thread (car mes valeurs sont dans une base de données) :
    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
     
        /**
         * Classe Thread
         * Chargement des paramétrages Saisons
         */
        private class LoadSaisonsThread extends Thread {
     
            @Override
            public void run() {
     
                final SaisonsListe<Saison> saisons = new SaisonsListe<Saison>(fiche.getAdresse());
                saisons.load();
     
            //  on renvoie le rafraichissement à l'EDT
                SwingUtilities.invokeLater(
                        new Runnable() {
     
                            @Override
                            public void run() {
     
                                for (Saison saison : saisons)
                                    cboSaisons.addItem(saison);
     
                                cboSaisons.setSelectedItem(null);
     
                                int count = 0;
                                if ( (count=cboSaisons.getItemCount())>0 )
                                    cboSaisons.setSelectedIndex(count-1);
     
                            }
     
                    });
            }
     
        }

    Et quand on choisit manuellement la saison, ça exécute un chargement spécifique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        @Override
        public void itemStateChanged(ItemEvent e) {
     
            if ( e.getStateChange()==ItemEvent.SELECTED  ) {
     
            //  chargement d'une saison
                if ( cboSaisons.getSelectedIndex()>=0 )
                    grille.load((Saison) cboSaisons.getSelectedItem());
     
            }
        }

    Donc chaque fois que j'ajoute un élément
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cboSaisons.addItem(saison);
    ma fonction itemStateChanged est appelée !

    Comment y remédier proprement ?

  2. #2
    Membre confirmé Avatar de kimausoleil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2004
    Messages : 126
    Par défaut bourrin mais pas très "beau"...
    Pour empêcher le chargement, j'ai alors utilisé une variable de type boolean :

    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
        /**
         * Classe Thread
         * Chargement des paramétrages Saisons
         */
        private class LoadSaisonsThread extends Thread {
    
            @Override
            public void run() {
    
                final SaisonsListe<Saison> saisons = new SaisonsListe<Saison>(fiche.getAdresse());
                saisons.load();
    
            //  on renvoie le rafraichissement à l'EDT
                SwingUtilities.invokeLater(
                        new Runnable() {
    
                            @Override
                            public void run() {
    
                                enChargement = true;
                                for (Saison saison : saisons)
                                    cboSaisons.addItem(saison);
    
                                cboSaisons.setSelectedItem(null);
                                
                                enChargement = false;
                                int count = 0;
                                if ( (count=cboSaisons.getItemCount())>0 )
                                    cboSaisons.setSelectedIndex(count-1);
                                
                            }
    
                    });
            }
    
        }
    Donc pour charger ma combobox, j'initialise ma variable à true, et quand j'ai terminé l'ajout de mes éléments, je passe à false.

    Ainsi, dans ma gestion de l'evènement, si en cours de chargement de la combo, je ne fais pas mon traitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        @Override
        public void itemStateChanged(ItemEvent e) {
    
            if ( e.getStateChange()==ItemEvent.SELECTED  ) {
    
            //  chargement d'une saison
                if ( !enChargement && cboSaisons.getSelectedIndex()>=0 )
                    grille.load((Saison) cboSaisons.getSelectedItem());
                
            }
        }

    Ca marche très bien, mais peut-on faire quelque chose de plus "propre" ?



    Merci pour vos suggestions

  3. #3
    Membre émérite
    Inscrit en
    Mars 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2006
    Messages : 848
    Par défaut
    Ce qui m'étonne, c'est que ce bout de 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
            final JComboBox mCombo = new JComboBox();
            mCombo.addItem("Toto");
            mCombo.addItemListener(new ItemListener()
            {
                public void itemStateChanged(ItemEvent e)
                {
                    System.out.print(e.getItem());
                    if(e.getStateChange() == ItemEvent.SELECTED) {
                        System.out.println(" Selected");
                    } else {
                        System.out.println(" Deselected");
                    }
                }
            });
     
            mCombo.addItem("Toto2"); // Aucun évènement
            mCombo.addItem("Toto3"); // Aucun évènement
            mCombo.setSelectedIndex(2); // Deselect puis Select
            mCombo.addItem("Toto4"); // Aucun évènement
    Montre que l'ajout d'élément ne provoque pas d'évènement.
    Essaie de le comparer à ton code pour voir la différence.

  4. #4
    Membre confirmé Avatar de kimausoleil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2004
    Messages : 126
    Par défaut
    Tout d'abord... merci pour ta réponse !

    Ensuite, en regardant ton code de plus près, je m'aperçois que tu ajoutes ton listener une fois après avoir ajouté un élt dans ta combo :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    mCombo.addItem("Toto");
    mCombo.addItemListener(
    Donc si je reprends ton exemple tel que :
    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
     
            final JComboBox mCombo = new JComboBox();
     
            mCombo.addItemListener(new ItemListener()
            {
                public void itemStateChanged(ItemEvent e)
                {
                    System.out.print(e.getItem());
                    if(e.getStateChange() == ItemEvent.SELECTED) {
                        System.out.println(" Selected");
                    } else {
                        System.out.println(" Deselected");
                    }
                }
            });
     
            mCombo.addItem("Toto");   //Select !
            mCombo.addItem("Toto2"); // Aucun évènement
            mCombo.addItem("Toto3"); // Aucun évènement
            mCombo.setSelectedIndex(2); // Deselect puis Select
            mCombo.addItem("Toto4"); // Aucun évènement

    Ainsi j'ai pu modifier mon code en initialisant ma combo :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            cboSaisons = new JComboBox();
            cboSaisons.addItem("");                  //un élt vide (qui sert à rien)
            cboSaisons.addItemListener(this);    //je rajoute après mon listener
    Puis dans mon thread :
    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
     
        /**
         * Classe Thread
         * Chargement des paramétrages Saisons
         */
        private class LoadSaisonsThread extends Thread {
     
            @Override
            public void run() {
     
                final SaisonsListe<Saison> saisons = new SaisonsListe<Saison>(fiche.getAdresse());
                saisons.load();
     
            //  on renvoie le rafraichissement à l'EDT
                SwingUtilities.invokeLater(
                        new Runnable() {
     
                            @Override
                            public void run() {
     
                                for (Saison saison : saisons)
                                    cboSaisons.addItem(saison);     //plus d'evt à l'ajout !
     
                                int count = 0;
                                if ( (count=cboSaisons.getItemCount())>0 )
                                    cboSaisons.setSelectedIndex(count-1);     //je sélectionne enfin celui que je veux afficher qui génère un evt
     
                                cboSaisons.removeItemAt(0);      //je supprime l'elt vide préalablement ajouté à l'initialisation
     
                            }
     
                    });
            }
     
        }

    Et l'evt normal, déclenché comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        @Override
        public void itemStateChanged(ItemEvent e) {
     
            if ( e.getStateChange()==ItemEvent.SELECTED  )
                    grille.load((Saison) e.getItem());
     
        }
    En résumé :
    1. j'ajoute un elt "vide" que je supprimerai plus tard
    2. j'ajoute le listener
    3. je charge ma combo comme avant, et comme il y a déjà un élt, il ne sélectionne pas et ne déclenche pas d'evt
    4. je sélectionne l'élt que je veux bien afficher qui déclencle l'evt associé (normal !)
    5. et je supprime le 1er élt vide




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

Discussions similaires

  1. [JComboBox] actionListener ou itemListener ?
    Par Sh4dow49 dans le forum Composants
    Réponses: 5
    Dernier message: 21/04/2008, 18h41
  2. Réponses: 7
    Dernier message: 17/04/2007, 13h51
  3. [jcombobox]l'élément affiché lié à un autre objet
    Par szdavid dans le forum Composants
    Réponses: 3
    Dernier message: 11/05/2004, 10h17
  4. [swing][JComboBox]Problème de taille
    Par n!co dans le forum Composants
    Réponses: 8
    Dernier message: 06/03/2004, 10h53
  5. Couleur d'une JComboBox disabled
    Par ced dans le forum Composants
    Réponses: 6
    Dernier message: 06/01/2004, 15h33

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