繁体   English   中英

需要声明为最终值的局部变量的更改值

[英]Change value of a local variable that needs to be declared final

我一直在尝试更改JButton在动作侦听器中的位置。 但是,当我编译我的代码时, Local variable is accessed from within inner class: needs to be declared final错误被显示。 因此,我将位置变量声明为final。 问题是我需要更改位置变量的值,而这只能是最终变量。 我该如何解决?

码:

final int location =100;

JFrame f = new JFrame();
final JButton b1 = new JButton("character");

f.setVisible(true);
f.setSize(500,500);
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.setLayout( new FlowLayout());

f.add(b1);

b1.addActionListener(new ActionListener() {     
  public void actionPerformed(ActionEvent e) {
     b1.setLocation(location,100);
     location += 10; // cannot assign a value to final variable location
  }
});

您正在尝试引用单击的按钮。 ActionEvent包含将作为按钮的事件源。 因此,您的代码应为:

//b1.setLocation(location,100);
JButton button = (JButton)e.getSource();
button.setLocation(button.getLocation() + 10, 100);

现在,不需要位置变量。

只要有可能,就应该使用事件的源来获取对象。 不要依赖实例变量。

局部变量是不可能的。
而是将实现包装在一个类中。 尝试类似:

  class Test {
         //instance variable
            private int location = 100;

            void init() {

                JFrame f = new JFrame();
                final JButton b1 = new JButton("character");
                f.setVisible(true);
                f.setSize(500, 500);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLocationRelativeTo(null);
                f.setLayout(new FlowLayout());

                f.add(b1);

                b1.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        b1.setLocation(location, 100);
                        Test.this.location += 10;
                    }
                });
            }
        }

甚至低于以下的值也可以正常工作(以防您在其他任何地方都不需要位置):

b1.addActionListener(new ActionListener() {

        private int location = 100;

        @Override
        public void actionPerformed(ActionEvent e) {
            b1.setLocation(location, 100);
            location += 10;
        }
    });

我不确定代码要做什么,但总体思路是Final原语变量是不可变的。 但是,如果是对象引用,则不能更改其引用,但可以更改对象的实例变量。 例如,如果您要使用地图存储位置,则如下所示

final Map<String,Integer> locM=new HashMap<String,Integer>();
locM.put("location",100);
then you can do the change to map values

b1.addActionListener(new ActionListener() {     
public void actionPerformed(ActionEvent e) {
..............
 locM.put("location",locM.get("location")+10);
   }
 });

或者,您可以创建一个位置包装器类,该类具有用于int位置值的setter和getter。 如果是int,则包装器类Integer是不可变的,因此您需要定义自己的包装类。

蒙莫汉

如果Location是实例变量而不是Local变量,则可以避免此特定问题

您可以通过两种方式做到这一点,

1)在您的父类中实现ActionListener,然后在

ParentClass implements ActionListener 
{
int location =100;
 //...Codes codes..
 public void actionPerformed(ActionEvent e) {
 //perform null check 
  if (b1==(JButton)e.getSource()){
   b1.setLocation(location,100);
    location += 10;

    }
  }
}

2)从内部类调用静态变量,(请记住:这是一种不好的编程方法)

 //static class to store variables
  Class StaticVariables{
  static int location=100;
 }



class ParentClass{

    //..Codes Codes..

    b1.addActionListener(new ActionListener() {
    //Calling Static class varible
    int localLocationVariable=StaticVariables.location;
    b1.setLocation(localLocationVariable,100);
    localLocationVariable+= 10;
    StaticVariables.location=localLocationVariable;
    }

希望这对您有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM