JButton ActionListeners在每个循环中都有不同的变量

时间:2018-12-07 15:19:26

标签: java loops jbutton actionlistener

我正在使用JFrame和JButton创建一个简单的计算器。在使用自己的动作监听器制作每个按钮(0至9)之前,现在我已经意识到这是非常低效的,我应该使用循环制作每个按钮并分配ActionListeners。因此,每个ActionListener中唯一需要发生的就是将按钮的编号添加到JTextField中,称为nums。这就是我现在所拥有的。

for(int i = 0; i <=9; i++) {
        count = i;
        btns.get(i).addActionListener(new ActionListener(){ //makes action listeners for each button
            public void actionPerformed(ActionEvent e){ 

                    nums.setText(nums.getText()+ count);//IMPORTANT CODE

            }       
        });
      }

因此,正如您所看到的,我使用了一个名为count的名称极为复杂的变量。在使用重要代码之前,每次迭代中将count设置为i。我必须这样做,因为AL是它自己的类,无法访问i。但是计数是公共的和静态的,因此AL可以使用计数。

我的问题是所有按钮都打印9。这在逻辑上是有意义的,因为正在发生的事情是每个按钮中的AL使用count变量,当循环完成后,count将为9,这意味着每个AL本质上将包含nums.setText(nums.getText()+ 9);。相反,我需要将按钮1设为nums.setText(nums.getText()+ 1); 2才能将2设为ETC。

我尝试调用每个按钮的文本,但是,由于需要在ArrayList的get方法中使用索引,因此需要一个变量,如果使用count,则会发生相同的问题。在for循环终止后,count为9,因此所有按钮都将打印9按钮的文本。

感谢所有帮助,在此先感谢您, -最大

P.S。以防万一您不明白为什么我要获取文本然后添加计数,这是因为要键入数字12,您需要键入1,然后将2连接为1到et12。getText得到1和加数将2连接成12。

2 个答案:

答案 0 :(得分:1)

通常,您将希望避免使用静态字段,因为这样做会失去面向对象编程的所有好处。有一些使用静态字段的特定位置,但这不是其中之一。在您的情况下,不能直接使用循环索引i,因为它不是最终的局部变量,并且非最终的局部变量不能在匿名内部类中使用。因此,存在一个简单的解决方案:

计算最终的局部变量,您应该可以在匿名内部类中使用它:

for(int i = 0; i <= 9; i++) {
    final int finalCount = i;
    btns.get(i).addActionListener(new ActionListener(){ 
        public void actionPerformed(ActionEvent e){ 

            nums.setText(nums.getText() + finalCount);

        }       
    });
}

答案 1 :(得分:0)

假设每个按钮的文本只是您想要附加的数字,那么还有另一种方法可以让您为每个数字按钮共享相同的ActionListener实例。

private ActionListener numberBtnListener = new ActionListener(){ 
    public void actionPerformed(ActionEvent e){ 
        JButton b = (JButton) e.getSource();
        nums.setText(nums.getText() + b.getText());
    }       
}

然后为每个按钮使用相同的侦听器实例:

for(JButton b : btns) {
    b.addActionListener(numberBtnListener);
}

如果由于某些原因您的按钮文本不同,您仍然可以通过在每个按钮上使用client属性来保留要附加的值,来使用相同的技术。例如:

 b.putClientProperty("digit", i);  

然后使用

nums.setText(nums.getText() + b.getClientProperty("digit"));