Java Starter
Java Starter

Reputation: 9

java; How to get the Variable Outside of the Action Listener?

NOTE: My english isn't the best So please don't mind too much Grammar mistakes.

Hey there, java Beginner here, Anyways i was coding my CPS Tester Program, Just as a first mini Program. Anyways, This question may have been asked before but, I need get a variable Outside a ActionListener code:

public static void startB() {
 Font f = new Font(null, Font.BOLD , 0);

    Font size = f.deriveFont(20f);

    JLabel text = new JLabel("");
    text.setPreferredSize(new Dimension(250,250));
    text.setFont(size);

    JButton b = new JButton();
    JFrame cps = new JFrame("CLICK");
    cps.setPreferredSize(new Dimension(400,400));
    cps.setLocationRelativeTo(null);
    cps.setLayout(new FlowLayout());
    b.setText("<html> CLICK ME <br> As much as you can! <html> ");
    cps.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    cps.getContentPane().add(b , BorderLayout.CENTER);
    cps.getContentPane().add(text, BorderLayout.CENTER);
    cps.pack();
    cps.setVisible(true);

    text.setText("<html> Starting in... <br> 3<html>");
    try {
        TimeUnit.SECONDS.sleep((long)1.0);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    text.setText("<html> Starting in... <br> 2<html>");
    try {
        TimeUnit.SECONDS.sleep((long)1.0);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    text.setText("<html> Starting in... <br> 1<html>");
    try {
        TimeUnit.SECONDS.sleep((long)1.0);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    text.setText("<html> CLICK! <html>");
    b.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            double clicks = 0;
            clicks++;
            // How to get Clicks variable out of the actionListener?
        }
    });
    try {
        TimeUnit.SECONDS.sleep((long)10.0);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //I need get the Clicks Variable to here.
}

If you can help me Please respond to the post. Thanks.

Upvotes: 0

Views: 2772

Answers (2)

dpr
dpr

Reputation: 10964

You can only access final variables of your outer class in an anonymous inner class. But as the modifier final suggests the value of such a variable can't be changed anymore once assigned.

To circumvent this you could use an AtomicInteger instead of a plain int or double to store the clicks and declare this final variable outside of your action listener:

final AtomicInteger clicks = new AtomicInteger(0);
b.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        clicks.incrementAndGet();
    }
}
clicks.get(); // will return the desired number of invocations of actionPerformed

This way you can still use an anonymous class for your action listener.

It would be better though - from a code style perspective - to define a named class and provide a getter for the click count as suggested in the other answer.

Upvotes: 1

davidxxx
davidxxx

Reputation: 131316

Here you create a anonymous class of ActionListener :

b.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    double clicks = 0;
    clicks++;
        // How to get Clicks variable out of the actionListener?

    }
  });

And you declared the clicks variable inside it.
You could declare clicks in the outer class but it will not work as the compiler expects that clicks be final. Which is not compatible with your usage of it : you mutate it inside actionPerformed().

An alternative to achieve your need is creating a non anonymous implementation of ActionListener where you will store clicks as a field and provide a getter to retrieve the value of it.

It could be an inner class :

private static class MyActionListener implements ActionListener {

    private double clicks;

    @Override
    public void actionPerformed(ActionEvent e) {
        clicks++;
    }

    public double getClicks() {
        return clicks;
    }

}

And you could use it in this way :

MyActionListener actionListener = new MyActionListener();
myComponent.addActionListener(actionListener);
...
// later retrieve clicks
double clicks = actionListener.getClicks();

Upvotes: 3

Related Questions