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

Langage Java Discussion :

Comment créer un Action Listener avec une variable de boucle ?


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut Comment créer un Action Listener avec une variable de boucle ?
    bonjour,

    dans une fonction j'ai une boucle qui me permet de créer 3 boutons et leur ActionListener. Je voudrais passer en paramètre à la fonction appelée lors du clic sur le bouton le contenu de la variable de boucle :

    Code java : 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
     
            JButton btn[]= new JButton[3];
    int i;
     
    for (i=0; i<3; i++)
    {
        btn[i]=new JButton("Bouton " + i);
        btn[i].addActionListener(new ActionListener()
        {
     
            @Override
            public void actionPerformed(ActionEvent e)
            {
                System.out.println(i);
            }
        });
    }

    Malheureusement au moment de la compilation j'ai cette erreur au niveau du println() :
    error: local variable i is accessed from within inner class; needs to be declared final
    System.out.println("bouton n°" + i);
    Si je déclare i en final int mon erreur se trouve au niveau du for


    D'où ma question : comment je peux passer le contenu de i ?

  2. #2
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 540
    Par défaut
    Quand tu fais tu es dans une classe interne, et la variable i, n'est plus visible. Il faut alors déclarer ta variable i en variable globale. C'est à dire avec les attributs de la classe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class MaClasse {
    int i;
    ...
     
    public void taMethode() {
    for (i=0...
    A ta place je ne m'y prendrais pas comme ça. Ta classe devrait implémenter ActionListener et dans la méthode actionPerformed, tu boucles sur le tableau, tu intercepte le bouton source et avec un switch case tu gère l'action du bouton en fonction de sa position dans le tableau.

  3. #3
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Citation Envoyé par oneagaindoguys Voir le message
    Quand tu fais tu es dans une classe interne, et la variable i, n'est plus visible. Il faut alors déclarer ta variable i en variable globale. C'est à dire avec les attributs de la classe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class MaClasse {
    int i;
    ...
     
    public void taMethode() {
    for (i=0...
    ça ne fonctionne pas seule la dernière valeur de i est prise en compte...


    Citation Envoyé par oneagaindoguys Voir le message
    A ta place je ne m'y prendrais pas comme ça. Ta classe devrait implémenter ActionListener et dans la méthode actionPerformed, tu boucles sur le tableau, tu intercepte le bouton source et avec un switch case tu gère l'action du bouton en fonction de sa position dans le tableau.
    Dans ce cas quelle propriété du bouton est testée dans le switch case ? Comment je peux les différencier les uns des autres ? En utilisant setName() ?

  4. #4
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 17
    Par défaut
    Bonsoir,
    Tu peux faire comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for (int i=0; i<3; i++)         {
     final int iTmp = i;
     btn[i]=new JButton("Bouton " + i);             
     btn[i].addActionListener(new ActionListener() {
    
       @Override
       public void actionPerformed(ActionEvent e) {
           System.out.println(iTmp);                 
       }             
    });         
    }
    ou encore :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for (int i=0; i<3; i++)         {
     btn[i]=new JButton("Bouton " + i);  
     btn[i].setActionCommand(Integer.toString(i));           
     btn[i].addActionListener(new ActionListener() {
    
       @Override
       public void actionPerformed(ActionEvent e) {
           System.out.println(e.getActionCommand());                 
       }             
    });         
    }
    Mais tout dépend de ce que tu veux faire au final (?)

  5. #5
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 540
    Par défaut
    Citation Envoyé par babycart Voir le message
    Bonsoir,
    Tu peux faire comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for (int i=0; i<3; i++)         {
     final int iTmp = i;
     btn[i]=new JButton("Bouton " + i);             
     btn[i].addActionListener(new ActionListener() {
    
       @Override
       public void actionPerformed(ActionEvent e) {
           System.out.println(iTmp);                 
       }             
    });         
    }
    ou encore :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for (int i=0; i<3; i++)         {
     btn[i]=new JButton("Bouton " + i);  
     btn[i].setActionCommand(Integer.toString(i));           
     btn[i].addActionListener(new ActionListener() {
    
       @Override
       public void actionPerformed(ActionEvent e) {
           System.out.println(e.getActionCommand());                 
       }             
    });         
    }
    Mais tout dépend de ce que tu veux faire au final (?)
    Le mieux, est que la classa implémente ActionListener

  6. #6
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 540
    Par défaut
    Citation Envoyé par Auteur Voir le message
    ça ne fonctionne pas seule la dernière valeur de i est prise en compte...



    Dans ce cas quelle propriété du bouton est testée dans le switch case ? Comment je peux les différencier les uns des autres ? En utilisant setName() ?
    Lorsque tu instancies un bouton la JVM lui attribue une place en mémoire. C'est l'adresse mémoire qui est prise en compte.

    Si tu veux envoies ton code, je vais essayer de l'adapter

  7. #7
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Citation Envoyé par babycart

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for (int i=0; i<3; i++)         {
     final int iTmp = i;
     btn[i]=new JButton("Bouton " + i);             
     btn[i].addActionListener(new ActionListener() {
     
       @Override
       public void actionPerformed(ActionEvent e) {
           System.out.println(iTmp);                 
       }             
    });         
    }
    j'y ai pensé et testé : effectivement cela fonctionne. Mais, j'avoue avoir une certaine réticence à déclarer des variables dans des boucles (sans doute parce que j'ai dans le passé utilisé des langages qui interdisent ce cas de figure).

    Par ailleurs, au niveau de la mémoire comment sont gérées les déclarations dans les boucles ?


    Citation Envoyé par babycart
    ou encore :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for (int i=0; i<3; i++)         {
     btn[i]=new JButton("Bouton " + i);  
     btn[i].setActionCommand(Integer.toString(i));           
     btn[i].addActionListener(new ActionListener() {
     
       @Override
       public void actionPerformed(ActionEvent e) {
           System.out.println(e.getActionCommand());                 
       }             
    });         
    }
    pas mal Je testerai dès que possible Mais une question qu'est-ce que la méthode setActionCommand() ? La javadoc n'est pas très explicite
    public void setActionCommand(String actionCommand)
    Sets the action command for this button.


    Citation Envoyé par oneagaindoguys Voir le message
    Lorsque tu instancies un bouton la JVM lui attribue une place en mémoire. C'est l'adresse mémoire qui est prise en compte.
    je testerai donc cette possibilité avec le méthode equals de getSource().

    Citation Envoyé par oneagaindoguys Voir le message
    Si tu veux envoies ton code, je vais essayer de l'adapter
    non, je préfère le faire moi même à partir des suggestions postées

  8. #8
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 540
    Par défaut
    Citation Envoyé par Auteur Voir le message
    non, je préfère le faire moi même à partir des suggestions postées
    Eh bien si tu veux coder correctement fait ta classe implémenter ActionListener.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public void actionPerformed(ActionEvent e) {
       for (int i=0; i<btn.length; i++) {
          if (e.getSource().equals(btn[i])) {
             switch...
             //ici tu gères l'action en fonction du boutton
       }
    }
    ActionListener est une interface et instancier une interface n'est pas ce qui est de plus cohérent. Imagine tu 30 boutons dans ton tableau, tu instancie 30 ActionListener, c'est lourd.

  9. #9
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Par défaut
    Citation Envoyé par Auteur Voir le message
    j'y ai pensé et testé : effectivement cela fonctionne. Mais, j'avoue avoir une certaine réticence à déclarer des variables dans des boucles (sans doute parce que j'ai dans le passé utilisé des langages qui interdisent ce cas de figure).
    C'est bien comme cela qu'il faut faire rapidement.

    Citation Envoyé par Auteur Voir le message
    Par ailleurs, au niveau de la mémoire comment sont gérées les déclarations dans les boucles ?
    Quand tu crées une classe anonyme, le compilateur génère une vraie classe.
    Si tu utilises des variables locales à l'instanciation de celle-ci alors le compilateur va simplement rajouter des attributs finaux dans la classe générée et les alimenter au niveau de l'instanciation de celle-ci.
    C'est pourquoi les attributs doivent être finaux pour que cela fonctionne.
    Le même principe s'applique si tu fais appels à des attributs et/ou méthode de "this". Le compilateur ajoute un attribut final du type de la classe qui génère la classe anonyme et alimente cet attribut au moment de l'instanciation.
    Le même principe est également appliqué aux inner class non static !

    Citation Envoyé par Auteur Voir le message
    pas mal Je testerai dès que possible Mais une question qu'est-ce que la méthode setActionCommand() ? La javadoc n'est pas très explicite
    Il s'agit d'une simple String permettant d'identifier le comportement du bouton. Par exemple une ActionCommand "delete" pourrait être utilisé pour plusieurs boutons mais un seul listener est nécessaire pour le gérer.

    Dans ce cas il ne faudrait pas instancier un action listener pour chaque élément de la boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ActionListener listener = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        switch (Integer.parseInt(e.getActionCommand()) {
        }
      }
    }
    for (int i=0; i < 10; i++) {
      JButton button = new JButton("Button #" + i);
      button.setActionCommand(""+i);
      button.addActionListener(listener);
      myPanel.add(button);
    }
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

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

    Citation Envoyé par Auteur Voir le message
    Mais, j'avoue avoir une certaine réticence à déclarer des variables dans des boucles (sans doute parce que j'ai dans le passé utilisé des langages qui interdisent ce cas de figure).
    Pourquoi ??????????

    Au contraire même c'est plus propre si la variable n'est utilisé que dans la boucle...

    Citation Envoyé par Auteur Voir le message
    Par ailleurs, au niveau de la mémoire comment sont gérées les déclarations dans les boucles ?
    Il n'y a aucun soucis avec cela...



    a++

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 13/02/2007, 17h40
  2. Créer une fonction avec une variable
    Par Ricou13 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 22/01/2007, 23h51
  3. [VBA] Comment valoriser un champ texte avec une variable ?
    Par Jean_Benoit dans le forum Access
    Réponses: 3
    Dernier message: 25/12/2006, 15h55
  4. Réponses: 2
    Dernier message: 16/11/2006, 13h28
  5. Comment créer un lien hypertexte avec une liaison OLE Excel ?
    Par vieuxsinge dans le forum API, COM et SDKs
    Réponses: 1
    Dernier message: 08/12/2005, 17h16

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