Java 为actionlistener事件创建计数器

Java 为actionlistener事件创建计数器,java,actionlistener,Java,Actionlistener,我的程序中有一个JButton,定义如下(或多或少) 我希望能够计算按钮被点击的次数。问题是,我不能声明一个计数器,然后在调用.doSomething()后将其递增,因为变量必须是final,才能在内部类中引用它 除了使用自己的.increment()方法创建自己的包装器类之外,还有其他方法可以做到这一点吗?根据线程情况,可以将变量移动到封闭类中。但是如果多次调用foo(),这可能会出错,因为这将使用相同的计数器 public class MyClass { // Notice the

我的程序中有一个JButton,定义如下(或多或少)

我希望能够计算按钮被点击的次数。问题是,我不能声明一个计数器,然后在调用.doSomething()后将其递增,因为变量必须是final,才能在内部类中引用它


除了使用自己的.increment()方法创建自己的包装器类之外,还有其他方法可以做到这一点吗?

根据线程情况,可以将变量移动到封闭类中。但是如果多次调用
foo()
,这可能会出错,因为这将使用相同的计数器

public class MyClass {

    // Notice the placement outside the main()    
    private static int counter = 0;

    public static void main(String[] args) {
        JButton startButton = new JButton("Start");
        startButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent ae) {
                startButton.doSomething()
                //do some more stuff

                counter++;

             }
           }
         );    
    }
}

根据线程情况,可以将变量移动到封闭类中。但是如果多次调用
foo()
,这可能会出错,因为这将使用相同的计数器

public class MyClass {

    // Notice the placement outside the main()    
    private static int counter = 0;

    public static void main(String[] args) {
        JButton startButton = new JButton("Start");
        startButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent ae) {
                startButton.doSomething()
                //do some more stuff

                counter++;

             }
           }
         );    
    }
}

您可以将计数器从
ActionListener
外部移动到内部,使其成为侦听器的成员

public class MyTester {
    public static void main(String[] args) {
        final JButton startButton = new JButton("Start");
        startButton.addActionListener(new ActionListener() {           
            int counter; // you make one per listener
            public void actionPerformed(ActionEvent e) {
                startButton.doSomething();
                counter++;
            }
        });
    }
}

您可以将计数器从
ActionListener
外部移动到内部,使其成为侦听器的成员

public class MyTester {
    public static void main(String[] args) {
        final JButton startButton = new JButton("Start");
        startButton.addActionListener(new ActionListener() {           
            int counter; // you make one per listener
            public void actionPerformed(ActionEvent e) {
                startButton.doSomething();
                counter++;
            }
        });
    }
}

正如@akf所建议的,计数器可以是嵌套类的成员,从该嵌套类中可以看到封闭实例的成员。此示例实现了
ActionListener
以扩展
AbstractAction

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/** @see http://stackoverflow.com/questions/4290117 */
public class ClickCount extends JPanel {

    private JButton button = new JButton(new ClickHandler("Click"));
    private JLabel label = new JLabel("0");

    public ClickCount() {
        this.add(button);
        this.add(label);
    }

    private class ClickHandler extends AbstractAction {

        int counter;

        public ClickHandler(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            label.setText(String.valueOf(++counter));
        }
    }

    private void display() {
        JFrame f = new JFrame("ClickCount");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ClickCount().display();
            }
        });
    }
}

正如@akf所建议的,计数器可以是嵌套类的成员,从该嵌套类中可以看到封闭实例的成员。此示例实现了
ActionListener
以扩展
AbstractAction

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/** @see http://stackoverflow.com/questions/4290117 */
public class ClickCount extends JPanel {

    private JButton button = new JButton(new ClickHandler("Click"));
    private JLabel label = new JLabel("0");

    public ClickCount() {
        this.add(button);
        this.add(label);
    }

    private class ClickHandler extends AbstractAction {

        int counter;

        public ClickHandler(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            label.setText(String.valueOf(++counter));
        }
    }

    private void display() {
        JFrame f = new JFrame("ClickCount");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ClickCount().display();
            }
        });
    }
}

刚才澄清了这个问题-这基本上就是我想要做的,但是我仍然遇到了同样的情况,试图改变最后一个变量。我的代码和你的代码之间存在差异。我的
计数器
不在main()函数中,而是在封闭类中。我将更新我的示例。只是澄清了这个问题-这基本上就是我想要做的,但我仍然遇到相同的情况,即尝试变异最终变量。我的代码和您的代码之间存在差异。我的
计数器
不在main()函数中,而是在封闭类中。我将更新我的示例。+1实现
ActionListener
的嵌套类是另一种选择。修订守则;如果不正确,请还原。+1实现
ActionListener
的嵌套类是另一种选择。修订守则;如果不正确,请还原。