2009-04-21 12 views
2

私は、ファイルを開き、ファイルに含まれるすべてのイメージを表示するEclipseプラグインを作成しています。この画像ディスプレイは、GUIアプリケーションの一部です。各イメージは、SWT Canvasウィジェットと関連付けてレンダリングされます。ファイルを開くと、表示する必要がある画像の数を判断するために必要なすべての情報が得られます。すべてのCanvasオブジェクトを1つずつ作成し、各Canvasオブジェクトをデータ構造のような配列に格納するのは意味があります。私が開くすべてのファイルには、表示する画像の数が異なります。私はArrayListを使うことに決めました。Eclipse SWT - Javaプログラミングのジレンマ

私は次のように進んでいます:各画像に対してCanvasオブジェクトを作成し、すべてのCanvasオブジェクトをArrayListに保存します。ここに問題があります:各Canvasオブジェクトには、PaintListenerMouseListenerが関連付けられています。画像がクリックされた場合のサイズ変更と検出に使用されます。 I 'は、forループ' 内のすべてのキャンバスオブジェクトを作成してい - 各キャンバスオブジェクトにPaintListenerMouseListenerを割り当てる含むので、同様に:

`

// 
// 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++) 

`

問題は:変数 'i'は、PaintListenerMouseListenerの異なるArrayListsでアクセスする要素を決定するために使用されます。注意ここでは説明のために「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; 

`

:私は、文字通り、必要なのは、本質的に相当と言い、各リスナーの定義のコードです。

すべてのアイデアをいただければ幸いです。

ありがとうございました。

答えて

5

PaintListenerのコンストラクタにオブジェクトを追加するだけで済みます。聞こえる

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の値に基づいて、すべての火災のイベント、:

例:

class MyPaintListener implements PaintListener 
{ 
Image image; 
MyPaintListener(Image image) 
{ 
    this.image = image; 
} 
void paintControl(...) 
{ 
    do stuff with image. 
} 
} 
+0

ロビンと同じ、私は殴られた:) – Olivier

+0

魅力的なように働いた。ありがとう。 –

0

は、あなただけの一時的な最終VARを使用することはできませんあなたが望むもののように。

+0

これはまさに私が望むものですが、あなたの例のようにコーディングしてみるとうまくいかないようです。 –

+0

私はこのアプローチが失敗する原因となっていることの例を見なければならないでしょう。インスタンス化時にvarを表示する以外の方法は、実際にどのように行うのかは分かりません。 – jsight

1

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

+0

コード例でKireのパンチに殴られました。 – Robin

+0

私はそれを与えると例を示し、あなたは良い説明をしたので、それはネクタイだと思う。このJistはPaintListenerに変数を格納する必要があるということです。 MouseAdapterオブジェクトです。ご協力いただきありがとうございます。 –