views:

114

answers:

4

Hi,

I'm trying to create simple GUI program in Java and I couldn't find a proper solution to error cannot refer to a non-final variable inside an inner class defined in a different method.

Here's my small code so far;

myPanel = new JPanel();

JButton myButton = new JButton("create buttons");
myButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        int val = Integer.parseInt(textfield.getText());
        for(int i = 0; i < val; i++) {
            JButton button = new JButton("");
            button.setText(String.valueOf(i));
            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    clickButton(i);
                }
            });
            myPanel.add(button);
            myPanel.revalidate();
        }
    }
});

Maybe my approach is completely wrong. What I'm trying to do is; I want to create a set of buttons and say when the user presses a button I want to display a message like "you pressed the button 4", or "you pressed the button 10".

A: 

To avoid this problem, you have to either declare the myPanel as a member variable of the class or use something else that refers to the member of the class.

Bragboy
+3  A: 

i has to be final in order for the inner class to access it. You can work around this by copying it to a final variable.

But I'd recommend refactoring the contents of the for loop into a separate method like this:

for(int i = 0; i < val; i++) {
    myPanel.add(makeButton(i));
    myPanel.revalidate();
}

...

private JButton makeButton(final int index) {
    JButton button = new JButton("");
    button.setText(String.valueOf(index));
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            clickButton(index);
        }
    });

    return button;
}
oksayt
A: 

Anonymous class can only use local variables declared as final so that they are guaranteed not to change.

Sheng Chien
A: 

In the inner class you cannot use i, it's not final. Anyway, you can assign its value to a final temp variable:

        for(int i = 0; i < val; i++) {
            JButton button = new JButton("");
            button.setText(String.valueOf(i));

            final int TEMP = i; // try this

            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    clickButton(TEMP);
                }
            });
            myPanel.add(button);
            myPanel.revalidate();
        }
Alessandro