Results 1 to 15 of 15
  1. #1
    kbro3 is offline Member
    Join Date
    Feb 2011
    Posts
    24
    Rep Power
    0

    Default ActionListener issue.

    Hi all,

    Having some issues with ActionListener in Swing, I have added an actionListener to a button, and it works as expected, but if I try to change any variables, I get a "local variable is accessed from within inner class, needs to be declared Final".

    Any ideas? If I want my button to, for instance, decrement an int variable, everytime it's pressed, the int can't possibly be declared as final.

    Here's a snippet of my code:

    Java Code:
    int currentHealth = 100;
    
            JPanel mainPanel = new JPanel();
    
            final JLabel label1 = new JLabel(Integer.toString(currentHealth));
    
    
            JButton okButton = new JButton("OK");
            JButton cancelButton = new JButton("CANCEL");
            JButton exitButton = new JButton("Exit");
    
    
    
            JFrame mainFrame = new JFrame("Application");
            mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    
    
            //OK Button event
            ActionListener al = new ActionListener() {
                public void actionPerformed(ActionEvent ae){
    
                    currentHealth = CurrentHealth--; //ERROR HERE
                    
                    System.out.println("Button Pressed");
    
    
                }
    
            };
    Thanks!

  2. #2
    al_Marshy_1981 is offline Senior Member
    Join Date
    Feb 2010
    Location
    Waterford, Ireland
    Posts
    748
    Rep Power
    5

    Default

    I cant replicate this error, can you post compilable code that shows it?

  3. #3
    Junky's Avatar
    Junky is offline Grand Poobah
    Join Date
    Jan 2011
    Location
    Dystopia
    Posts
    3,784
    Rep Power
    7

    Default

    From the JLS:
    Any local variable, formal method parameter or exception handler parameter used but not declared in an inner class must be declared final.

    It doesn't explain why. It may in another section.

  4. #4
    al_Marshy_1981 is offline Senior Member
    Join Date
    Feb 2010
    Location
    Waterford, Ireland
    Posts
    748
    Rep Power
    5

    Default

    Quote Originally Posted by Junky View Post
    From the JLS:
    Any local variable, formal method parameter or exception handler parameter used but not declared in an inner class must be declared final.

    It doesn't explain why. It may in another section.
    The inner class holds only a copy of the local variable so if the variable changes in the local class the inner class variable might be out of synch (bad things). I cannot replicate it though for some reason :confused:

  5. #5
    kbro3 is offline Member
    Join Date
    Feb 2011
    Posts
    24
    Rep Power
    0

    Default

    The entire code:

    Java Code:
    import javax.swing.*;
    import java.awt.event.*;
    import java.awt.*;
    
    /**
     *
     * @author kirill
     */
    public class Main {
    
    
    
       
    
        public static void main(String[] args)
        {
    
            int currentHealth = 100;
    
            JPanel mainPanel = new JPanel();
    
            final JLabel label1 = new JLabel(Integer.toString(currentHealth));
    
    
            JButton okButton = new JButton("OK");
            JButton cancelButton = new JButton("CANCEL");
            JButton exitButton = new JButton("Exit");
    
    
    
            JFrame mainFrame = new JFrame("Application");
            mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    
    
            //OK Button event
            ActionListener al = new ActionListener() {
                public void actionPerformed(ActionEvent ae){
    
                    currentHealth = CurrentHealth--; //Won't allow this
                    
                    System.out.println("Button Pressed");
    
    
                }
    
            };
    
    
            //Cancel Button event
            ActionListener ac = new ActionListener(){
                public void actionPerformed(ActionEvent ae){
    
    
                }
    
    
    
            };
    
    
            //Register actionlistener with ok button
            okButton.addActionListener(al);
            cancelButton.addActionListener(ac);
    
    
            mainPanel.add(okButton, BorderLayout.CENTER);
            mainPanel.add(label1, BorderLayout.NORTH);
            mainFrame.add(mainPanel);
    
            mainFrame.pack();
            mainFrame.setVisible(true);
            
            
            
    
    
            
            
    
    
            
        }
    
        
    }
    Basically, I can only reference final variables from within the ActionListener. But if I want to modify them in the listener, obviously they can't be final, so that's the dilemma here..

    Thanks.

  6. #6
    Junky's Avatar
    Junky is offline Grand Poobah
    Join Date
    Jan 2011
    Location
    Dystopia
    Posts
    3,784
    Rep Power
    7

    Default

    Quote Originally Posted by al_Marshy_1981 View Post
    the inner class might be out of synch
    Yeah that was what I was thinking but wasn't 100% sure.

  7. #7
    kbro3 is offline Member
    Join Date
    Feb 2011
    Posts
    24
    Rep Power
    0

    Default

    Quote Originally Posted by Junky View Post
    Yeah that was what I was thinking but wasn't 100% sure.
    Elaborate please?

    Thanks.

  8. #8
    Junky's Avatar
    Junky is offline Grand Poobah
    Join Date
    Jan 2011
    Location
    Dystopia
    Posts
    3,784
    Rep Power
    7

    Default

    So don't make the variable you are trying to change local.

    Yikes!

    Don't stuff all your code in the main method. Java is OO and has classes for a reason.

  9. #9
    kbro3 is offline Member
    Join Date
    Feb 2011
    Posts
    24
    Rep Power
    0

    Default

    Quote Originally Posted by Junky View Post
    So don't make the variable you are trying to change local.

    Yikes!

    Don't stuff all your code in the main method. Java is OO and has classes for a reason.

    Haha, yeah I know it's not exactly elegant, but I'm just testing ActionListeners out, hence why didn't spend time on proper OO.

    Thanks.

  10. #10
    Junky's Avatar
    Junky is offline Grand Poobah
    Join Date
    Jan 2011
    Location
    Dystopia
    Posts
    3,784
    Rep Power
    7

    Default

    Well it won't take much to change. Move all the code you have so far into a constructor. Except the local variable you are trying to modify. Make it an instance variable instead. Then change your main method to:
    Java Code:
    new Main();

  11. #11
    kbro3 is offline Member
    Join Date
    Feb 2011
    Posts
    24
    Rep Power
    0

    Default

    Quote Originally Posted by Junky View Post
    Well it won't take much to change. Move all the code you have so far into a constructor. Except the local variable you are trying to modify. Make it an instance variable instead. Then change your main method to:
    Java Code:
    new Main();
    So as a class, I can modify instance variables with ActionListener? That means i'll have to instantiate the class and then modify the instance variable through a setter which in turn gets called by ActionListener?

    Sorry if I'm going over very basic concepts.

    Thanks.

  12. #12
    Junky's Avatar
    Junky is offline Grand Poobah
    Join Date
    Jan 2011
    Location
    Dystopia
    Posts
    3,784
    Rep Power
    7

    Default

    Quote Originally Posted by kbro3 View Post
    So as a class, I can modify instance variables with an inner class?
    Just to be clear.
    That means i'll have to instantiate the class
    Yes that is what the main method is doing.
    and then modify the instance variable through a setter which in turn gets called by ActionListener?
    If the variable is an instance variable the inner class has direct access to it. No need for a setter method.

    By the way
    Java Code:
    currentHealth = currentHealth--;
    this does not work. Try the following:
    Java Code:
    int a = 1;
    a = a++;
    System.out.println(a);
    int b = 1;
    b = ++b;
    System.out.println(b);
    Same goes for decrementing.
    Last edited by Junky; 02-24-2011 at 05:54 AM.

  13. #13
    kbro3 is offline Member
    Join Date
    Feb 2011
    Posts
    24
    Rep Power
    0

    Default

    Quote Originally Posted by Junky View Post
    Just to be clear.

    Yes that is what the main method is doing.

    If the variable is an instance variable the inner class has direct access to it. No need for a setter method.

    By the way
    Java Code:
    currentHealth = currentHealth--;
    this does not work. Try the following:
    Java Code:
    int a = 1;
    a = a++;
    System.out.println(a);
    int b = 1;
    b = ++b;
    System.out.println(b);
    Same goes for decrementing.
    Cheers for the reply. I'll have a dig around with it some more, no doubt I'll be back asking more questions.

    Btw, thanks for the increment/decrement thing too, I don't usually bother with shorthand, now I remember why :)

    Thanks.

  14. #14
    Junky's Avatar
    Junky is offline Grand Poobah
    Join Date
    Jan 2011
    Location
    Dystopia
    Posts
    3,784
    Rep Power
    7

    Default

    Just to clarify increment/decrement. When you want to use them don't assign them back to the variable. simply do:
    Java Code:
    int a = 10;
    a--;
    --a;
    int b = 10;
    b++;
    ++b;

  15. #15
    kbro3 is offline Member
    Join Date
    Feb 2011
    Posts
    24
    Rep Power
    0

    Default

    Quote Originally Posted by Junky View Post
    Just to clarify increment/decrement. When you want to use them don't assign them back to the variable. simply do:
    Java Code:
    int a = 10;
    a--;
    --a;
    int b = 10;
    b++;
    ++b;
    Ah right, I didn't catch that earlier, thanks for the clarification. :)

Similar Threads

  1. ActionListener w/ Dialog
    By BariMutation in forum New To Java
    Replies: 1
    Last Post: 12-03-2010, 04:50 PM
  2. ActionListener+KeyListener
    By mandelbrot in forum AWT / Swing
    Replies: 5
    Last Post: 09-10-2010, 12:25 AM
  3. NullPointerException by ActionListener
    By YouGina in forum AWT / Swing
    Replies: 8
    Last Post: 07-10-2009, 11:08 AM
  4. Demonstrating the ActionListener
    By Java Tip in forum java.awt
    Replies: 0
    Last Post: 04-23-2008, 08:20 PM
  5. How to use KeyListener and ActionListener
    By Java Tip in forum javax.swing
    Replies: 0
    Last Post: 04-23-2008, 08:19 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •