我正在尝试创建一个 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]);
    }

我认为我可以通过使用来克服这个问题 this 或者可能 super 而不是调用 label[i] 在内部方法中,但我一直无法弄清楚。

编译错误是:局部变量 i 从内部类内部访问;需要宣布最终`

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

任何帮助,将不胜感激

有帮助吗?

解决方案

你的局部变量必须是 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) 在内部类的主体之前。


资源 :

其他提示

如果您在访问时遇到问题 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]);
}

你也可以使用 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();
      }
   });
}

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

将标签数组声明为:

final JLabel[] label;

代替:

JLabel[] label;

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top