如何使用SwingWorker返回列表

时间:2010-05-03 19:58:16

标签: java swingworker

我有一项任务,我必须创建一个图像库,使用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

@覆盖   protected void done(){     试试{

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



} catch (Exception e) { }

}

我还创建了一个方法,返回名为list的{​​{1}}我需要获取的是来自getImages()的列表,但是当我调用getImages()时,它不能正常工作例如

execute()

一旦到达MySwingWorkerClass swingworker = new MySwingWorkerClass(log,list,filenames); swingworker.execute(); imageList = swingworker.getImage() 它就不会返回任何内容我能够获得列表的唯一方法就是当我使用imageList代替run()时,还有另一种方式获取列表或execute()方法是唯一的方法吗?或者我可能不理解run()班级。

3 个答案:

答案 0 :(得分:1)

我认为你有点误解和SwingWorker。大多数是正确的,但是你不能在getImage()之后立即调用execute() - 执行调用立即返回,并且你的图像正在工作线程上加载。因此,立即调用getImages()无法获取图像。

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

答案 1 :(得分:1)

  

...或者我可能不理解SwingWorker班级。

您应该了解SwingWorker的生命周期。当您调用execute时,您的处理将切换到后台线程,并且当前线程将立即返回。这就是你的getImages没有返回任何内容的原因。来自javadoc

  

<强>工作流

     

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

     

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

     

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

     

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

答案 2 :(得分: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下载或从磁盘加载。 / p>