Link to home
Start Free TrialLog in
Avatar of matthew016
matthew016Flag for Belgium

asked on

problem Inner Class

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*
                                                   
Avatar of zzynx
zzynx
Flag of Belgium image

And what is label?
can you post more of your code?
Because your MouseListener is anonymous, you need to declare any variables of its parent you want to access as final
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);
      }
}
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?
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 :-)
>>
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
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 :-)
You could be right, Tim
/me does a dance

;-)
...although he's explicitely telling us:

//In the Constructor            <<<<<<<<<<<<<<<<<<<
this.modèle = modèle;
yeah...maybe all the other code in in the constructor too?
Mmmmmaybe ;°)
Matthew016, your input is needed!
Avatar of matthew016

ASKER

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 :




> Here here is some more of my code :

where? ;-)
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) {}
      
          });
     }
..............
label in this case is not a local variable. The solution is as i mentioned
Sorry but I dont get it, modèle is not a local variable either ...
Whoops:

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

Sorry :-)
ASKER CERTIFIED SOLUTION
Avatar of TimYates
TimYates
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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) :-)
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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 ?

Hmmm i'll change to d then ...
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) {}
     
          });
     }
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
And then of course:

pColonne[i].addMouseListener(new PlayerListener(i));
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 ...
or not ?
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

}
>> 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);
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);
     }
}
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 ;-)

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)
Sorry replace

    label.setIcon(flèche);

by
   
    theLabel.setIcon(flèche);

in the above
post your code as it is currently,

You've done something wrong :-(
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
Thank you :)
8-)
:-)  Good luck!! :-)

Tim