如何使用Lambda表达式计算按钮点击次数?

时间:2018-07-08 09:01:05

标签: java swing lambda jbutton

在我的代码的这一部分,我想计算用户按下按钮的次数。问题是,如果我声明该数字以计算该函数外部的点击次数,那么它根本不会执行。这是我的意思:

byte numButtonClicks = 0;

    tellingIntroButton.addActionListener(e -> {
        numButtonClicks ++;
        System.out.println(numButtonClicks);
    });

在内部声明它也不是一个选择,因为它将始终被重置。 感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

请让我知道您得到的确切错误是什么。如果numButtonClicks是局部变量,则无法在lambda函数中对捕获的局部变量进行突变。将它设为一个LongAdder类变量,该变量是原子性的,并为并发而设计。

  LongAdder numButtonClicks= new LongAdder();

              tellingIntroButton.addActionListener(e -> {
                    numButtonClicks.increment();
                    System.out.println(numButtonClicks);
                }); 

答案 1 :(得分:0)

如果您有类似的东西

public class YourComponent extends JFrame { // or whatever it is you're extending

    // ....

    public void init() {
        // ...
        byte numButtonClicks = 0;

        tellingIntroButton.addActionListener(e -> {
            numButtonClicks ++;
            System.out.println(numButtonClicks);
        });
    }

    // ...
}

您会遇到一些问题。

  1. 在匿名内部类(例如您的动作侦听器)中使用的变量必须隐式为final。您在对另一个答案的评论中提到的例外

    Exception in thread "main" java.lang.Error: Unresolved compilation problem: Local variable numButtonClicks defined in an enclosing scope must be final or effectively final
    

告诉您计数器变量不是最终变量

  1. 您正在使用byte字段作为计数器。为什么不使用intlong

  2. 您不能在方法内声明最终的intlong并将其递增。

您可以通过在班级中拥有一个成员来解决此问题,例如

public class YourComponent extends JFrame { // or whatever it is you're extending

    // ....

    private int numButtonClicks = 0;

    public void init() {
        // ...

        tellingIntroButton.addActionListener(e -> {
            YourComponent.this.numButtonClicks++;
            System.out.println(numButtonClicks);
        });
    }

    // ...
}

或者,就像其他答案所暗示的那样,如果并发在这里对您来说是一个问题(如果可以通过不同的线程修改计数),则可以使用诸如LongAdder之类的java8对象。如果您沿着这条路线(LongAdder行驶,则在方法范围内将其声明为 final