views:

45

answers:

1

Hello,

I am trying to make a GUI in Java, using something along these lines:

public class GUIApp
{
    DrawingPanel dp;
    buttonPanel bp;
    ova = Oval;
 public GUIApp()
    {
        JFrame win = new JFrame("Drawing App");
        dp = new DrawingPanel();
        bp = new buttonPanel(this);

    //Settings for panels and frame

        ova = new Oval(100,100,100,100);

      }
      public void setOval(int c){
        //Change color of oval
      }
  }

Then in my buttonPanel class I have this:

public class ButtonPanel extends JPanel
{

    private JButton btnRed, btnGreen, btnBlue;

    public ButtonPanel(GUIApp d)
    {

        ButtonListener listener = new ButtonListener();
        btnRed = new JButton("Red");
        btnGreen = new JButton("Green");
        btnBlue = new JButton("Blue");

        btnRed.addActionListener(listener);
        btnGreen.addActionListener(listener);
        btnBlue.addActionListener(listener);

        setBackground(Color.lightGray);
        GridLayout grid = new GridLayout(3,1);
        add(btnRed,grid);
        add(btnGreen,grid);
        add(btnBlue,grid);
    }

    private class ButtonListener implements ActionListener{

        public void clickButton(ActionEvent event) {
            Object location = event.getSource();
            if (location == btnRed){
                d.setOval(1);
            }
            else if(location == btnGreen){
                d.setOval(2);
            }
            else if(location == btnBlue){
                d.setOval(3);
        }
        }

}
}

But netbeans gives an error for the inner ButtonListener class, and I don't know why. I also don't know how to correctly call the setOval from within that class to the GUIApp class. What am I doing wrong?

+3  A: 

The problem is that when you implement ActionListener you must define the method actionPerformed(ActionEvent e); you haven't done that in your ButtonListener class. You can't name the method anything that you want (as you've done with clickButton), so you should just rename your clickButton method to actionPerformed (and go ahead and add an @Override annotation too).

Now in order to call d.setOval from within your inner class, d must be in scope when the actionPerformed method is called. There are a couple ways to achieve this: you could make d a member variable of your class, or you could define your ButtonListener as an anonymous class.

For example, if you saved d as a member variable then your code would look like this:

public class ButtonPanel {
 private GUIApp d;

 public ButtonPanel(GUIApp d) {
  this.d = d;
  // The rest of your code here...
 }
}

Or, you could use an anonymous class like this:

public ButtonPanel(GUIApp d) {
 ActionListener listener = new ActionListener(){
  @Override
  public void actionPerformed(ActionEvent event) {
   Object location = event.getSource();
   if (btnRed.equals(location)) {
    d.setOval(1);
   } else if (btnGreen.equals(location)) {
    d.setOval(2);
   } else if (btnBlue.equals(location)) {
    d.setOval(3);
   }
  }
 };
 // The rest of your constructor code here ...
}

Note: Notice how I also changed the use of == to equals() for object equality.

Shakedown
Also, 'd' doesn't seem to be declared in the listener class
Guillaume
Thanks for that, but how do I call `d.setOval(c)` from within the inner class?
Jonno_FTW
`event.getSource()` returns the specific instance of a (in this case) JButton used in the code, so `btnRed == location` would work correctly.
Bart Kiers
@Bart K. Yes, you're right it would work correctly in this case, but in the general case `equals` is usually preferred.
Shakedown