Search code examples
javavariablesjbutton

Change variable value through event listener on JButton


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.

Solution

  • 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.