我正在尝试创建一个JLabel数组,所有这些都应该在单击时隐藏。当尝试通过需要访问用于声明标签的循环的迭代变量的内部类来设置鼠标侦听器时,会出现问题。代码不言自明:
for(int i=1; i<label.length; i++) {
label[i] = new JLabel("label " + i);
label[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
label[i].setVisible(false); // compilation error here
}
});
cpane.add(label[i]);
}
我认为我可以通过使用this
或super
代替内部方法中label[i]
的调用来解决这个问题,但我无法弄清楚进行。
编译错误是:从内部类中访问局部变量i;需要被宣布为最终的
我确信答案肯定是我没想过的傻事,或者我犯了一些小错误。
任何帮助将不胜感激
答案 0 :(得分:27)
您的本地变量必须是final
才能从内部(和匿名)类访问。
您可以更改以下内容的代码:
for (int i = 1; i < label.length; i++) {
final JLabel currentLabel =new JLabel("label " + i);
currentLabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
currentLabel.setVisible(false); // No more compilation error here
}
});
label[i] = currentLabel;
}
来自JLS:
使用但未在内部类中声明的任何局部变量,形式参数或异常参数必须声明为
final
。任何使用但未在内部类中声明的局部变量必须在内部类的主体之前明确赋值(§16)。
资源:
答案 1 :(得分:4)
如果您在访问i
时遇到问题,请在内部类的范围之外创建另一个变量(例如在label[i].addMouseListener(...)
之前):
for(int i=1; i<label.length; i++) {
label[i] = new JLabel("label " + i);
final int localI = i;
label[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
label[localI].setVisible(false);
}
});
cpane.add(label[i]);
}
答案 2 :(得分:2)
您也可以在程序中使用getSource
。在此之后,您可以在typecasting
的帮助下访问您的组件。它会减少额外的代码行,
你的代码看起来像这样
for (int i = 1; i < label.length; i++) {
currentLabel.addMouseListener(new MouseAdapter(e) {
public void mouseClicked(MouseEvent me) {
JLabel label = (JLabel) me.getSource();
}
});
}
答案 3 :(得分:0)
这是因为label
未指定为final
。
将标签数组声明为:
final JLabel[] label;
而不是:
JLabel[] label;
你的MouseAdapter
不是内心阶级;这是一个匿名类。匿名类只能引用其封闭代码的final
个变量。
答案 4 :(得分:0)
匿名内部类只能访问final
。