2

ファイルを開き、ファイルに含まれるすべての画像を表示する Eclipse プラグインを作成しています。この画像表示は、GUI アプリケーションの一部です。各画像は、SWT Canvas ウィジェットに関連付けることによってレンダリングされます。ファイルを開くと、表示する必要がある画像の数を決定するために必要なすべての情報が得られます。すべての Canvas オブジェクトを次々に作成し、各 Canvas オブジェクトをデータ構造のような何らかのタイプの配列に格納することは理にかなっていると思います。開いたファイルごとに、表示する画像の数が異なります。を使用することにしましたArrayList

手順は次のとおりです。画像ごとに Canvas オブジェクトを作成し、すべての Canvas オブジェクトを に保存しますArrayList。問題は次のとおりです。各 Canvas オブジェクトには、PaintListenerそれにMouseListener関連付けられた と があります。これは、サイズ変更と、画像が「クリック」されたかどうかを検出するためのものです。「for ループ」ですべての Canvas オブジェクトを作成しています。これには、次のように、各 Canvas オブジェクトにPaintListenerandを割り当てることが含まれます。MouseListener

`

//
// Assume the following ArrayLists have been defined:
// myCanvases, myImages, and myFrames
//

for (int i = 0; i < numberOfImages; i++) {

    canvas = new Canvas(getMyComposite(), SWT.BORDER | 
        SWT.NO_MERGE_PAINTS | SWT.NONE );

    canvas.setLayoutData(getMyGridData());

.
    .
    .

    canvas.addPaintListener(new PaintListener() {
    public void paintControl(final PaintEvent event) {
        if (myImages.get(i) != null) {
                myImages.get(i).dispose();
                event.gc.drawImage(mySceneImages.get(element), 0, 0);
    }
    }
});

    currentCanvas.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseUp(MouseEvent event) {
        getVideo().setCurrentFrame(myFrames.get(i).getFrameNumber());
                }
    });

    canvas.setVisible(true);

        myCanvases.add(i, canvas);


} // End for (int i = 0; i < numberOfScenes; i++)

`

問題PaintListener: 変数 'i' を使用して、およびの異なる ArrayList でアクセスする要素を決定しますMouseListener。ここでは説明のために「i」を使用していることに注意してください。「for ループ」で定義された変数「i」は、リスナーの内部クラスでは使用できないことに気付きました。とにかく...... リスナーがイベントを受け取ると、ArrayList の特定の要素にアクセスしようとするために使用する変数には、リスナーが定義されたときの値ではなく、現在の値が含まれます。

Javaでこれを回避するにはどうすればよいですか? 私が文字通り必要としているのは、本質的に次のように言う各リスナーの定義内のコードです。

`

myCanvases.get(7); // or whatever the for loop iteration is for that specific object);

// Not

myCanvases.get(i); // - which will contain the present value of i;

`

リスナーが実行されるとき。

どんなアイデアでも大歓迎です。

ありがとう。

4

3 に答える 3

5

PaintListenerのコンストラクターにオブジェクトを追加するだけです。

例えば

class MyPaintListener implements PaintListener
{
 Image image;
 MyPaintListener(Image image)
 { 
    this.image = image;
 }
 void paintControl(...)
 {  
     do stuff with image.
 }
}
于 2009-04-21T18:22:05.940 に答える
1

匿名内部クラスの代わりに内部クラスを使用し、オブジェクトをコンストラクターに渡します。anon クラスで使用している変数はオブジェクトに格納されていないため、呼び出されたときに外部クラスの値を参照します。

于 2009-04-21T18:28:53.663 に答える
0

一時的な最終変数を使用することはできません:

final JFrame f = new JFrame();
f.setLayout(new FlowLayout());
for (int i = 0; i < 10; i++) {
  final int curIdx = i;
  JButton btn = new JButton("Btn: " + i);
  btn.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
      JOptionPane.showMessageDialog(f, "Item: " + curIdx);
    }
  });
  f.add(btn);
}
f.pack();
f.setVisible(true);

リスナーはすべて、宣言時のvarの値に基づいてイベントを起動します。これは、希望どおりに聞こえます。

于 2009-04-21T18:26:51.420 に答える