2

我有一个任务,我必须创建一个图像库,它使用 aSwingWorker从文件加载图像,一旦加载图像,您可以翻转图像并播放幻灯片。我无法使用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;

}
}

完成后,我只需将图像插入 a 即可List<Image>

// In the EDT

@Override protected void done() { 尝试 {

  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类。

4

3 回答 3

1

我觉得你SwingWorker有点误会了。大部分是正确的,但您不能getImage()立即调用execute()- 执行调用立即返回,并且您的图像正在工作线程上加载。因此,立即调用getImages()没有要获取的图像。

要解决此问题,您应该在done()覆盖中进行图像处理,例如将图像添加到将显示它们的 UI 组件。

于 2010-05-03T20:23:03.000 回答
1

...或者我不理解这个SwingWorker类。

您应该了解SwingWorker. 当您调用execute时,您的处理将切换到后台线程,当前线程将立即返回。这就是为什么你getImages不返回任何东西的原因。从javadoc

工作流程

SwingWorker 的生命周期涉及三个线程:

当前线程:在该线程上调用了 execute() 方法。它安排 SwingWorker 在工作线程上执行并立即返回。可以使用 get 方法等待 SwingWorker 完成。

工作线程:在该线程上调用 doInBackground() 方法。这是所有后台活动都应该发生的地方。要通知 PropertyChangeListener 绑定的属性更改,请使用 firePropertyChange 和 getPropertyChangeSupport() 方法。默认情况下,有两个可用的绑定属性:状态和进度。

事件调度线程:所有与 Swing 相关的活动都发生在该线程上。SwingWorker 调用 process 和 done() 方法并通知此线程上的任何 PropertyChangeListener。

于 2010-05-03T20:29:24.767 回答
0

为什么不使用发布进程机制将中间结果从后台工作线程发送到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,同时使用发布进程机制,您可以在每次有单张照片可用时更新 UI,而其他照片仍在从 Internet 下载或从磁盘加载。

于 2010-06-28T10:01:41.683 回答