Solved

problem Inner Class

Posted on 2004-10-22
188 Views
Last Modified: 2010-03-31
Hello,
I made an inner class for my MouseListener,

private JPanel [] pColonne;
private JPanel panel;
private Puissance4 modèle;

...
//In the Constructor
this.modèle = modèle;
...
panel= new JPanel(new GridLayout (1,7));
for (int i = 0; i < 7; ++i) {
     panel.add(pColonne[i]);
     pColonne[i].add(label);
     pColonne[i].addMouseListener( new MouseListener(){
          public void mouseClicked(MouseEvent e) {
               modèle.jouer(1);
          }
          public void mouseEntered(MouseEvent e) {
               label.setIcon(flèche);
         }
    }
...

I have an error on modèle
says " change modifier of 'modèle' to final "
But why can I acces to 'label' and not to 'modèle' from my inner class ?
Thanks
*sorry of my poor english*
                                                   
0
Question by:matthew016
    40 Comments
     
    LVL 37

    Expert Comment

    by:zzynx
    And what is label?
    0
     
    LVL 35

    Expert Comment

    by:TimYates
    can you post more of your code?
    0
     
    LVL 86

    Expert Comment

    by:CEHJ
    Because your MouseListener is anonymous, you need to declare any variables of its parent you want to access as final
    0
     
    LVL 86

    Expert Comment

    by:CEHJ
    You would be better using a named inner class:


    pColonne[i].addMouseListener(new PlayerListener());

    ............


    class PlayerListener extends MouseAdapter {
          public void mouseClicked(MouseEvent e) {
                modèle.jouer(1);
          }
          
          public void mouseEntered(MouseEvent e) {
                label.setIcon(flèche);
          }
    }
    0
     
    LVL 37

    Expert Comment

    by:zzynx
    The main question was
    >>But why can I acces to 'label' and not to 'modèle' from my inner class ?

    So, mine is: how is label defined?
    0
     
    LVL 35

    Expert Comment

    by:TimYates
    Change:

                   modèle.jouer(1);

    to

                   this.modèle.jouer(1);

    I'm guessing you are passing modèle into the method that the for loop is in, and this is being used rather than the actual class instance that you require :-)
    0
     
    LVL 86

    Expert Comment

    by:CEHJ
    >>
    The main question was
    >>But why can I acces to 'label' and not to 'modèle' from my inner class ?
    >>

    That's unanswerable as the declaration of 'label' is not shown
    0
     
    LVL 35

    Expert Comment

    by:TimYates
    I reckon it's because there's a situation like this:

      public void whatever( Puissance4 modèle )
      {
         this.modèle = modèle;
          ....
         pColonne[i].addMouseListener( new MouseListener(){
              public void mouseClicked(MouseEvent e) {
                   modèle.jouer(1);
              }
              public void mouseEntered(MouseEvent e) {
                   label.setIcon(flèche);
             }
         }
      }

    so,

                   this.modèle.jouer(1);

    should fix it :-)
    0
     
    LVL 37

    Expert Comment

    by:zzynx
    You could be right, Tim
    0
     
    LVL 35

    Expert Comment

    by:TimYates
    /me does a dance

    ;-)
    0
     
    LVL 37

    Expert Comment

    by:zzynx
    ...although he's explicitely telling us:

    //In the Constructor            <<<<<<<<<<<<<<<<<<<
    this.modèle = modèle;
    0
     
    LVL 35

    Expert Comment

    by:TimYates
    yeah...maybe all the other code in in the constructor too?
    0
     
    LVL 37

    Expert Comment

    by:zzynx
    Mmmmmaybe ;°)
    Matthew016, your input is needed!
    0
     
    LVL 9

    Author Comment

    by:matthew016
    Here I am ! I was eating ! you guys are fast ! :p

    CEHJ -> you need to declare any variables of its parent you want to access as final
    not agree because
    i can acces label and I declared label ->
    public class PanelPlateau implements ActionListener{
          private JPanel pNord;
          private JPanel pCentre;
          private JPanel [] pColonne;
          private ImageIcon flèche;
          private ImageIcon spacer;
          private JLabel label;
          private Puissance4 modèle;
    just like modèle ...

    TimYates -> this.modèle. ...
    doesnt work, i get as error "change to 'modèle' "

    Here here is some more of my code :




    0
     
    LVL 35

    Expert Comment

    by:TimYates
    > Here here is some more of my code :

    where? ;-)
    0
     
    LVL 9

    Author Comment

    by:matthew016
    public PanelPlateau(Puissance4 modèle) {
         this.modèle = modèle;
         flèche = new ImageIcon("images/down.gif");
         spacer = new ImageIcon("images/spacer2.gif");
         label = new JLabel(spacer);
                
         pNord = new JPanel(new GridLayout (1,7));
         for (int i = 0; i < 7; ++i) {
              pNord.add(pColonne[i]);
              pColonne[i].add(label);
              pColonne[i].addMouseListener( new MouseListener(){
                   public void mouseClicked(MouseEvent e) {
                        try {
                             this.modèle.jouer(1);
                        } catch (ColonnePleineException ex) {
                        // TODO Auto-generated catch block
                             ex.printStackTrace();
                        }
                   }
                   public void mouseEntered(MouseEvent e) {
                        label.setIcon(flèche);
                   }
                   public void mouseExited(MouseEvent e) {
                        label.setIcon(spacer);                  
                   }
                   public void mousePressed(MouseEvent e) {}
                   public void mouseReleased(MouseEvent e) {}
          
              });
         }
    ..............
    0
     
    LVL 86

    Expert Comment

    by:CEHJ
    label in this case is not a local variable. The solution is as i mentioned
    0
     
    LVL 9

    Author Comment

    by:matthew016
    Sorry but I dont get it, modèle is not a local variable either ...
    0
     
    LVL 35

    Expert Comment

    by:TimYates
    Whoops:

                         PanelPlateau.this.modèle.jouer(1);

    Sorry :-)
    0
     
    LVL 35

    Accepted Solution

    by:
    You pass a variable called "modèle" in the constructor...  The anonymous inner class is trying to use this variable, NOT the modèle variable in the class (this.modèle)...

    either

    a)  Change the constructor to:

     public PanelPlateau(Puissance4 m) {
         this.modèle = m;
     
    b)  Change the constructor to:

     public PanelPlateau(final Puissance4 modèle) {
         this.modèle = modèle;
     
    c)  Change the inner class to:

                   public void mouseClicked(MouseEvent e) {
                        try {
                             PanelPlateau.this.modèle.jouer(1);
     
    d)  Write a proper MouseListener class (like CEHJ said)
    0
     
    LVL 35

    Expert Comment

    by:TimYates
    NB:  Those were in no particular order...  I'd probably do (b)  because it's the easiest...  But I have been know to do (a), (b), or (d) :-)
    0
     
    LVL 86

    Assisted Solution

    by:CEHJ
    Using d) will also give you the advantage of making your generated code cleaner and therefore easier to package
    0
     
    LVL 9

    Author Comment

    by:matthew016
    Thanks, can u tell me how i can acces the integer 'i' in the for ?
    (i used method c :-))
    Because PanelPlateau.this.modèle.jouer(1);
    should be PanelPlateau.this.modèle.jouer(i);
    Hum I didnt ask that question at start sorry, but do you know how ?

    0
     
    LVL 9

    Author Comment

    by:matthew016
    Hmmm i'll change to d then ...
    0
     
    LVL 35

    Expert Comment

    by:TimYates
    I *think* you should be able to do:

            for (int i = 0; i < 7; ++i) {
              final int cnt = i ;
              pNord.add(pColonne[i]);
              pColonne[i].add(label);
              pColonne[i].addMouseListener( new MouseListener(){
                   public void mouseClicked(MouseEvent e) {
                        try {
                              PanelPlateau.this.modèle.jouer( cnt );
                        } catch (ColonnePleineException ex) {
                        // TODO Auto-generated catch block
                             ex.printStackTrace();
                        }
                   }
                   public void mouseEntered(MouseEvent e) {
                        label.setIcon(flèche);
                   }
                   public void mouseExited(MouseEvent e) {
                        label.setIcon(spacer);              
                   }
                   public void mousePressed(MouseEvent e) {}
                   public void mouseReleased(MouseEvent e) {}
         
              });
         }
    0
     
    LVL 37

    Assisted Solution

    by:zzynx
    class PlayerListener extends MouseAdapter {

          private int toPlay = 0;

         public PlayerListener(int i) {
            toPlay = i;
         }

         public void mouseClicked(MouseEvent e) {
              modèle.jouer(toPlay);
         }
         
         public void mouseEntered(MouseEvent e) {
              label.setIcon(flèche);
         }
    }
    0
     
    LVL 37

    Expert Comment

    by:zzynx
    And then of course:

    pColonne[i].addMouseListener(new PlayerListener(i));
    0
     
    LVL 9

    Author Comment

    by:matthew016
    Thanks Very Good !!
    But i'll need to put modèle and also flèche AND label in the PlayerListener Constructor because i make a seperate class ...
    0
     
    LVL 9

    Author Comment

    by:matthew016
    or not ?
    0
     
    LVL 35

    Expert Comment

    by:TimYates
    Yup.  Or you can put this class inside your PanelPlateau class...  then you don't have to ;-)

    public class PanelPlateau extends whatever
    {
        class PlayerListener extends MouseAdapter
        {
            private int toPlay = 0;

           public PlayerListener(int i) {
              toPlay = i;
           }

           public void mouseClicked(MouseEvent e) {
                modèle.jouer(toPlay);
           }
         
           public void mouseEntered(MouseEvent e) {
                label.setIcon(flèche);
           }
        }

    ... rest of PanelPlateau class

    }
    0
     
    LVL 37

    Expert Comment

    by:zzynx
    >> But i'll need to put modèle and also flèche AND label in the PlayerListener Constructor because i make a seperate class ...
    You can pass it afterwards too:

    PlayerListener pl = new PlayerListener(i);
    pl.setWhatever(whateveryoulike);
    pl.setWhatever2(whateveryoulike2);
    ...
    pColonne[i].addMouseListener(pl);
    0
     
    LVL 37

    Expert Comment

    by:zzynx
    Of course then you have to add the needed functions to your PlayerListener class

    e.g. I added setLabel():

    class PlayerListener extends MouseAdapter {

          private int toPlay = 0;
          private JLabel theLabel;

         public PlayerListener(int i) {
            toPlay = i;
         }

         public void setLabel(JLabel lbl) {
           theLabel = lbl;
         }

         public void mouseClicked(MouseEvent e) {
              modèle.jouer(toPlay);
         }
         
         public void mouseEntered(MouseEvent e) {
              label.setIcon(flèche);
         }
    }
    0
     
    LVL 86

    Expert Comment

    by:CEHJ
    You don't necessarily have to go from an anonymous inner class to a stand-alone inner class with its own instance variables. Ask yourself how truly independent of its parent it should be. Certainly it wasn't going to be in the first place ;-)

    0
     
    LVL 9

    Author Comment

    by:matthew016
    Well, I tried it with a named inner class ...
    but I still have to put
    PanelPlateau.this.modèle.jouer(1) ...

    I get an error on modèle.jouer(1)
    and also on this.modèle.jouer(1)
    0
     
    LVL 37

    Expert Comment

    by:zzynx
    Sorry replace

        label.setIcon(flèche);

    by
       
        theLabel.setIcon(flèche);

    in the above
    0
     
    LVL 35

    Expert Comment

    by:TimYates
    post your code as it is currently,

    You've done something wrong :-(
    0
     
    LVL 9

    Author Comment

    by:matthew016
    Exactly, I answered to fast, forgot the try catch ....
    Now it works,
    thanks to you three

    *splitting points*
    not much sorry those are my last one!

    Goodbye
    0
     
    LVL 37

    Expert Comment

    by:zzynx
    Thank you :)
    0
     
    LVL 86

    Expert Comment

    by:CEHJ
    8-)
    0
     
    LVL 35

    Expert Comment

    by:TimYates
    :-)  Good luck!! :-)

    Tim
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Product Review - Android Remix

    Come along for the ride with our Senior Product Manager, Brian Matis, as he reviews the Android Remix.

    Suggested Solutions

    INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
    Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
    Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
    The viewer will learn how to implement Singleton Design Pattern in Java.

    845 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    6 Experts available now in Live!

    Get 1:1 Help Now