我一直在尝试在动作侦听器中更改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
}
});
答案 0 :(得分:2)
您正在尝试引用已单击的按钮。 ActionEvent
包含将作为按钮的事件源。所以你的代码应该是:
//b1.setLocation(location,100);
JButton button = (JButton)e.getSource();
button.setLocation(button.getLocation() + 10, 100);
现在不需要位置变量。
只要有可能,您应该使用事件源来获取Object。不要依赖实例变量。
答案 1 :(得分:0)
使用局部变量是不可能的。而是将您的实现包装在一个类中。 尝试类似:
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;
}
});
答案 2 :(得分:0)
我不确定代码尝试做什么,但一般的想法是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);
}
});
或者您可以创建一个Location包装器类,它具有int位置值的setter和getter。在int的情况下,包装类Integer是不可变的,因此您需要定义自己的。
Monmohan
答案 3 :(得分:0)
如果Location是实例变量而不是Local变量,则可以避免此特定问题
答案 4 :(得分:0)
你可以用两种方式来做,
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;
}
希望这对你有所帮助。