Eclipse SWT - Дилемма программирования Java - PullRequest
2 голосов
/ 21 апреля 2009

Я пишу плагин Eclipse, который открывает файл и отображает все изображения, содержащиеся в этом файле. Это изображение является частью приложения с графическим интерфейсом. Каждое изображение отображается путем связывания его с виджетом SWT Canvas. Когда я открываю файл, у меня есть вся информация, необходимая для определения количества изображений, которые мне нужно отобразить. Я подумал, что имеет смысл создавать все объекты Canvas, один за другим, и сохранять каждый объект Canvas в неком типе массива, подобном структуре данных. Каждый файл, с которым я открываю, имеет различное количество изображений для отображения. Я решил использовать ArrayList.

Я действую следующим образом: я создаю объект Canvas для каждого изображения и сохраняю все объекты Canvas в ArrayList. Вот проблема: Каждый объект Canvas имеет PaintListener и MouseListener, связанные с ним - для изменения размера и обнаружения, если изображение было «нажато». Я создаю все объекты Canvas в цикле for, который включает присвоение PaintListener и MouseListener каждому объекту Canvas, например:

`

//
// 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' используется для определения того, к какому элементу обращаться в различных списках ArrayList в PaintListener и MouseListener. Обратите внимание, что я использую «я» для иллюстративных целей здесь. Я понимаю, что переменная 'i', определенная в цикле for, не может использоваться во внутренних классах слушателей. В любом случае ...... Когда слушатели получают событие, любая переменная, которую я использую, чтобы попытаться получить доступ к определенному элементу 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;

`

при выполнении слушателя.

Любые идеи приветствуются.

Спасибо.

Ответы [ 3 ]

5 голосов
/ 21 апреля 2009

Вы можете просто добавить объект в конструктор PaintListener.

* 1003 например *

class MyPaintListener implements PaintListener
{
 Image image;
 MyPaintListener(Image image)
 { 
    this.image = image;
 }
 void paintControl(...)
 {  
     do stuff with image.
 }
}
1 голос
/ 21 апреля 2009

Используйте внутренние классы вместо анонимного внутреннего класса и передайте объекты в конструктор. Переменная, которую вы используете в классе anon, не сохраняется в объекте, поэтому при вызове она будет ссылаться на свое значение во внешнем классе.

0 голосов
/ 21 апреля 2009

Разве вы не можете просто использовать временную окончательную переменную:

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 на момент объявления, которое звучит как то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...