2

This is a pretty nooby question, but I can't work it out. I have a JButton and a variable. Simply put, the variable's value needs to change when the button is clicked. This isn't working because of the fact that variables in the event listener can only take final variables. Problem is, the variable needs to change, so it can't be final. I've done some reading and tried to make count be a class variable, but then there are problems with static vs not-static. Here is a simple version of what I have:

public static void main(String[] args) {
    int count = 0;

    JFrame frame = new JFrame("Frame");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
     JPanel panel = new JPanel();
            panel.setLayout(null);
            panel.setBackground(Color.WHITE);
            frame.add(panel);
            panel.setSize(frame.getSize());
    JButton button = new JButton("Click Me");
            button.setBounds(50,50,100,50);
            panel.add(button);
    JLabel counter = new JLabel(""+count);
            counter.setBounds(50,100,100,50);
            panel.add(counter);
    frame.setSize(500,500);
    frame.setVisible(true);

    button.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            count++;
            counter.setText(""+count);
        }
     });
}

The exact error I've been getting is:

local variables referenced from an inner class must be final or effectively final.
user2985562
  • 65
  • 2
  • 8
  • First, you asked very interesting question. what I did? I declare a data field without using final keyword and everything worked. I keep reading that If I add final key word , the inner class can change the value cuz it has different copy but when I use it , compiler complains. hope someone answer this very well – Kick Buttowski May 10 '15 at 19:11
  • You will want to get most of that code out of the static main method and into true OOP-compliant classes. Otherwise you're putting the GUI cart ahead of the OOP-concepts horse. – Hovercraft Full Of Eels May 10 '15 at 19:37

2 Answers2

1

This can be done as you have it if you declare the items within your event listener as global static variables like so:

private static int count = 0;
private static JLabel counter;

public static void main(String[] args) {
...
}

Then remove the declarations from your main block i.e:

int count = 0; becomes count = 0;

and:

JLabel counter = new JLabel(""+count);
        counter.setBounds(50,100,100,50);
        panel.add(counter);

becomes:

counter = new JLabel(""+count);
        counter.setBounds(50,100,100,50);
        panel.add(counter);

This will allow the action listener of the button to access the values and change them. Where as declaring them (counter will throw the same issue) final does not allow their values to be actively changed and incremented.

  • **quick fix?** what happened to use of final keyword? where are your reasons? – Kick Buttowski May 10 '15 at 19:12
  • Thank you very much. This is pretty much what I have been reading, but this answer was far clearer than anything else. I suppose this is what I was confused about with moving them to become class variables. It works fine now. – user2985562 May 10 '15 at 19:15
-1
final int count = 0;

look at this post

Why are only final variables accessible in anonymous class?

Community
  • 1
  • 1
Antonio
  • 644
  • 5
  • 17
  • So using @Override, I can override the fact that it is a final variable, which will let me change it? – user2985562 May 10 '15 at 19:01
  • 1
    @Override is not related to variables – Antonio May 10 '15 at 19:05
  • 1
    @Antonio your answer is totally insufficient – Kick Buttowski May 10 '15 at 19:13
  • @KickButtowski you said that my answer was totally insufficient but form me the user learned that a local variable should be final if used in an anonymous class, from you he learned that he should declare "global variable" each variable used in an anonymous class and I guess you can imagine some wrong design in it – Antonio May 10 '15 at 20:34
  • first , I did not vote u down at all, and I just expressed my opinion. Second, be fair, you just through a line of code and a link with any explanation. You can improve your post , so whoever vote u down will revise that. do not get encouraged @Hovercraft Full Of Eels will agree with me too – Kick Buttowski May 10 '15 at 20:38