17

我正在尝试创建一个 JLabels 数组,单击时它们都应该不可见。当试图通过需要访问用于声明标签的循环的迭代变量的内部类来设置鼠标侦听器时,就会出现问题。代码不言自明:

    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]);
    }

我认为我可以通过使用thissuper代替label[i]内部方法中的调用来克服这个问题,但我无法弄清楚。

编译错误是:局部变量 i 是从内部类中访问的;需要声明为final`

我敢肯定,答案一定是我没有想到的非常愚蠢的事情,或者我犯了一些小错误。

任何帮助,将不胜感激

4

5 回答 5

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 节) 。


资源 :

于 2010-10-10T18:35:12.883 回答
4

如果您在访问 时遇到问题i,请在内部类范围之外创建另一个变量(例如 before 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]);
}
于 2010-10-10T18:36:49.913 回答
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();
      }
   });
}
于 2014-03-09T21:34:07.343 回答
0

发生这种情况是因为label未指定为final.

将标签数组声明为:

final JLabel[] label;

代替:

JLabel[] label;

MouseAdapter的不是内部阶级;这是一个匿名类。匿名类只能引用final其封闭代码的变量。

于 2010-10-10T18:34:03.870 回答
0

匿名内部类只能访问封闭方法的变量final

于 2010-10-10T18:35:08.530 回答