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

内部メソッド内での呼び出しの代わりにthisまたはを使用することでこれを克服できると思いましたが、それを理解することができませんでした。superlabel[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 に答える
0

これは、labelが として指定されていないために発生しfinalます。

ラベルの配列を次のように宣言します。

final JLabel[] label;

それ以外の:

JLabel[] label;

あなたMouseAdapterは内部クラスではありません。それは匿名クラスです。匿名クラスはfinal、それを囲むコードの変数のみを参照できます。

于 2010-10-10T18:34:03.870 に答える
0

匿名の内部クラスは、含まれているメソッドの変数にのみアクセスできますfinal

于 2010-10-10T18:35:08.530 に答える