【问题标题】:how to return a list using SwingWorker如何使用 SwingWorker 返回列表
【发布时间】:2010-06-28 22:58:29
【问题描述】:

我有一个任务,我必须创建一个图像库,它使用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&lt;Image&gt; 即可。

// In the EDT

@覆盖 受保护的无效完成(){ 试试 {

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

【问题讨论】:

    标签: java swingworker


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      工作流程

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

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

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

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

      【讨论】:

        【解决方案3】:

        为什么不使用发布进程机制将后台工作线程的中间结果发送到EDT?看来您正在使用SwingWorker#publish(V) 向用户告知任务的进度,您可以实现检查线程进度或更新PropertyChangeListener

        更改您的工作人员以将图像引用发送到EDT 并覆盖SwingWorkerprocess(List&lt;V&gt; 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,而其他照片仍在从互联网下载或从磁盘加载。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-05
          • 2015-11-11
          • 2021-04-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多