2009-04-21 8 views
2

J'écris un plugin Eclipse qui ouvre un fichier et affiche toutes les images contenues dans le fichier. Cet affichage d'image fait partie d'une application GUI. Chaque image est rendue en l'associant à un widget SWT Canvas. Lorsque j'ouvre le fichier, j'ai toutes les informations dont j'ai besoin pour déterminer le nombre d'images que je devrai afficher. Je pense qu'il serait logique de créer tous les objets Canvas, l'un après l'autre et de stocker chaque objet Canvas dans un type de tableau comme la structure de données. Chaque fichier que j'ai ouvert avec un nombre différent d'images à afficher. J'ai décidé d'utiliser un ArrayList.Eclipse SWT - Dilemme de programmation Java

Je procède comme suit: Je crée un objet Canvas pour chaque image et stocke tous les objets Canvas dans un ArrayList. Voici le problème: chaque objet Canvas est associé à PaintListener et MouseListener - pour redimensionner et détecter si une image a été «cliquée». Je crée tous les objets de toile dans une « boucle » - qui comprend l'affectation d'un PaintListener et MouseListener à chaque objet de toile, comme suit:

`

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

`

Le problème : La variable 'i' est utilisée pour déterminer quel élément accéder dans les différentes ArrayLists dans les PaintListener et MouseListener. Remarque J'utilise 'i' à des fins d'illustration ici. Je réalise que la variable 'i' définie dans la 'boucle for' ne peut pas être utilisée dans les classes internes des auditeurs. De toute façon ...... Quand les écouteurs reçoivent un événement, n'importe quelle variable que j'utilise pour essayer d'accéder à un élément spécifique d'une ArrayList contient sa valeur actuelle, pas la valeur quand les Auditeurs ont été définis.

Comment puis-je contourner cela en Java? Ce que je dois littéralement est le code dans la définition de chaque auditeur qui dit essentiellement équivaut à:

`

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; 

`

lorsque l'auditeur exécute.

Toutes les idées seraient appréciées.

Merci.

Répondre

5

Vous pouvez simplement ajouter l'objet au constructeur de PaintListener.

Par exemple,

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

Comme Robin, j'ai été battu :) – Olivier

+0

A travaillé comme un charme. Merci. –

0

Tu ne peux pas utiliser une finale temporaire var:

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

Les auditeurs tous les incendies en fonction de la valeur du var au moment de la déclaration, qui sonne comme ce que tu veux.

+0

C'est exactement ce que je veux, mais cela ne semble pas fonctionner quand j'essaye de le coder comme votre exemple. –

+0

Je devrais voir un exemple de ce que vous faites qui fait échouer cette approche. Je ne vois pas vraiment comment cela ferait autre chose que d'afficher la var au moment de l'instanciation. – jsight

1

Utilisez des classes internes au lieu d'une classe interne anonyme et transmettez les objets au constructeur. La variable que vous utilisez dans la classe anon n'est pas stockée dans l'objet, donc elle référencera sa valeur dans la classe externe lorsqu'elle est appelée.

+0

Battu au coup de poing par Kire, avec un exemple de code. – Robin

+0

Je pense que c'est une cravate parce qu'il a illustré par le don et l'exemple et vous avez donné une bonne explication. Ce jist étant que j'avais besoin de stocker la variable dans PaintListener | Objet MouseAdapter. Merci de votre aide. –