как вернуть список с помощью SwingWorker - PullRequest
2 голосов
/ 03 мая 2010

У меня есть задание, в котором я должен создать галерею изображений, которая использует SwingWorker для загрузки изображений из файла, после загрузки изображения вы можете перевернуть его и запустить воспроизведение слайд-шоу. У меня проблемы с получением списка загруженных изображений с помощью SwingWorker.

Это то, что происходит в фоновом режиме, просто публикует результаты в TextArea

 // In a thread
@Override
public List<Image> doInBackground() {
List<Image> images = new ArrayList<Image>();
for (File filename : filenames) {
  try {
    //File file = new File(filename);
    System.out.println("Attempting to add: " + filename.getAbsolutePath());
    images.add(ImageIO.read(filename));
    publish("Loaded " + filename);
    System.out.println("Added file" + filename.getAbsolutePath());
  } catch (IOException ioe) {
    publish("Error loading " + filename);
  }
}
return images;

}
}

когда это сделано, я просто вставляю изображения в List<Image>, и это все, что он делает.

// In the EDT

@ Override защищенная пустота выполнена () { попробуй {

  for (Image image : get()) {
    list.add(image);
  }



} catch (Exception e) { }

}

Также я создал метод, который возвращает list с именем getImages(), мне нужно получить список из getImages(), но он не работает, когда я вызываю execute(), например

MySwingWorkerClass swingworker = new MySwingWorkerClass(log,list,filenames);
swingworker.execute();
imageList = swingworker.getImage()

Как только он достигает imageList, он ничего не возвращает. Единственный способ получить список - это когда я использовал run() вместо execute(), есть ли другой способ получить список или метод run() единственный способ ?. или, возможно, я не понимаю класс Swing Worker.

Ответы [ 3 ]

1 голос
/ 04 мая 2010

... или, возможно, я не понимаю класс SwingWorker.

Вы должны знать о жизненном цикле SwingWorker. Когда вы вызываете execute, ваша обработка переключается на фоновый поток, и текущий поток немедленно возвращается. Вот почему ваш getImages ничего не возвращает. Из Javadoc :

Workflow

В жизненном цикле SwingWorker участвуют три потока:

Текущий поток: метод execute () вызывается в этом потоке. Он планирует SwingWorker для выполнения в рабочем потоке и немедленно возвращается. Можно дождаться завершения SwingWorker, используя методы get.

Рабочий поток: метод doInBackground () вызывается в этом потоке. Это где все фоновые действия должны произойти. Чтобы уведомить PropertyChangeListeners об изменениях связанных свойств, используйте методы firePropertyChange и getPropertyChangeSupport (). По умолчанию доступно два связанных свойства: состояние и прогресс.

Поток отправки событий: все действия, связанные с Swing, выполняются в этой теме. SwingWorker вызывает методы process и done () и уведомляет любые PropertyChangeListeners в этом потоке.

1 голос
/ 04 мая 2010

Я думаю, что вы неправильно поняли SwingWorker немного. В большинстве случаев это правильно, но вы не можете вызвать getImage() сразу после execute() - вызов выполнения немедленно возвращается, и ваши изображения загружаются в рабочий поток. Таким образом, немедленный вызов getImages() не имеет изображений для извлечения.

Чтобы исправить это, вы должны выполнить обработку изображений в переопределении done(), например добавление изображений в компонент пользовательского интерфейса, который будет их отображать.

0 голосов
/ 28 июня 2010

Почему вы не используете механизм процесса публикации для отправки промежуточных результатов из фонового рабочего потока в EDT? Похоже, что вы используете SwingWorker#publish(V), чтобы сообщить пользователю о ходе выполнения задачи, и вы можете проверить ход выполнения потока или обновить PropertyChangeListener.

Измените своего работника так, чтобы он отправлял ссылки на Изображения для метода EDT и переопределил SwingWorkerprocess(List<V> chunks), чтобы получать эти Изображения в EDT, и обновите модель компонента для отображения изображений.

public class SwingWorker<Void,Image> {
    @Override
    public Void doInBackground() {
        Image img;
        while(....) {
            img = downloadImage();
            publish(img);
        }    
    }

    @Override
    public void process(List<Image> images) {
        //you are on the EDT now   
    }
}

Вызов SwingWorker # get () метод может блокировать EDT, при этом используя механизм процесса публикации, вы можете обновлять свой пользовательский интерфейс каждый раз, когда одна фотография становится доступной, в то время как другие все еще загружаются из Интернета или загрузка с диска.

...