views:

41

answers:

2
public class MainFrame extends JFrame {
    MainFrame()
    {
        JButton zeroButton = new JButton("0");
        add(zeroButton);

        Handler handler = new Handler();
        zeroButton.addActionListener(handler);
    }

    private class Handler implements ActionListener
    {

        public void actionPerformed(ActionEvent e) {
              if (e.getSource() == **zeroButton**)
                  JOptionPane.showMessageDialog(null, "hello there!");
        }
    }
}

The code has an error which underlines what I marked as bold in the code. here is the error message: "cannot find symbol"

I thought I can access outer class modifiers from the inner class, but it doesn't work!

+2  A: 

zeroButton is not a member of outer class (MainFrame), it's a local variable in MainFrame constructor.

Try something like this

public class MainFrame extends JFrame {
    private final JButton zeroButton;

    MainFrame() {
        zeroButton = new JButton("0");

PS I'm also not sure if you're supposed to compare controls with ==. (never used swing)

Nikita Rybak
Since it is a class level variable, it need not be final. any instance variable will be accessible to anonymous/inner classes
Nivas
(embarassed.) Thank you :)
w4j3d
@Nivas I know that both _private_ and _final_ are optional, I just often apply them 'by default' to all members :)
Nikita Rybak
@Nikita, _I just often apply them 'by default' to all members_: I think you mean memebers that are GUI elements, like JButton, and perhaps not all members by default. I apply `private` to all, but `final` was a bit strange.
Nivas
@Nivas It really depends on domain. I don't work with GUI in Java, so can't tell about it, but if you work in multi-threaded environment it's usually a good idea (unless you see specific reason for a field to be changeable). Helps with thread-safety.
Nikita Rybak
+1  A: 

You are unable to access it because the button is a local variable in another method.

You have two options: 1. Make the button in a instance variable (a class level variable). See Nikita's answer.

  1. Have the handler as an anonymous implementation, in the constructor:

MainFrame() {

MainFrame() {        
        final JButton zeroButton = new JButton("0");  
        add(zeroButton);  
        Handler handler = new Handler();  
        zeroButton.addActionListener(new ActionListener()
        {
           public void actionPerformed(ActionEvent e) { 
              if (e.getSource() == **zeroButton**) 
                  JOptionPane.showMessageDialog(null, "hello there!"); 
        } 

        });  
    }

In this case, the variable should be final because only final local variables are accessible to inner classes.

Nivas