如何使用 SwingWorker 返回列表

发布于 2024-08-31 04:07:53 字数 1469 浏览 5 评论 0原文

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

// In the EDT

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

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



} catch (Exception e) { }

创建了一个返回名为 getImages()

list 的方法,我需要获取的是 getImages() 中的列表,但是例如,当我调用 execute() 时,它不会工作。

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

一旦到达 imageList,它不会返回任何内容,我能够获取列表的唯一方法是当我使用 run() 而不是 execute() 时,是否有另一种方法来获取列表,或者是 run() 方法必由之路?。或者也许我不理解 Swing Worker 类。

I have an assignment where i have to create an Image Gallery which uses a SwingWorker to load the images froma a file, once the image is load you can flip threw the image and have a slideshow play. I am having trouble getting the list of loaded images using SwingWorker.

This is what happens in the background it just publishes the results to a 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;

}
}

when it is done I just insert the images in a List<Image> and that is all it does.

// In the EDT

@Override
protected void done() {
try {

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



} catch (Exception e) { }

}

Also I created an method that returns the list called getImages() what I need to get is the list from getImages() but doesn't seam to work when I call execute() for example

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

Once it reaches the imageList it doesn't return anything the only way I was able to get the list was when i used the run() instead of the execute() is there another way to get the list or is the run() method the only way?. or perhaps i am not understanding the Swing Worker Class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

病毒体 2024-09-07 04:07:53

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

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

I think you misundersand SwingWorker a little. Most of it is right, but you cannot call getImage() immediately after execute() - the execute call returns immediately, and your images are being loaded on the worker thread. So, the immediate call to getImages() has no images to fetch.

To fix this, you should do your image handling in the done() override, e.g. adding the images to the UI component that will display them.

栖竹 2024-09-07 04:07:53

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

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

工作流程

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

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

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

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

...or perhaps i am not understanding the SwingWorker Class.

You should be aware of the life-cycle of the SwingWorker. When you call execute, your processing will switch to a background thread and the current thread will return immediately. This is why your getImages does not return anything. From the javadoc:

Workflow

There are three threads involved in the life cycle of a SwingWorker :

Current thread: The execute() method is called on this thread. It schedules SwingWorker for the execution on a worker thread and returns immediately. One can wait for the SwingWorker to complete using the get methods.

Worker thread: The doInBackground() method is called on this thread. This is where all background activities should happen. To notify PropertyChangeListeners about bound properties changes use the firePropertyChange and getPropertyChangeSupport() methods. By default there are two bound properties available: state and progress.

Event Dispatch Thread: All Swing related activities occur on this thread. SwingWorker invokes the process and done() methods and notifies any PropertyChangeListeners on this thread.

污味仙女 2024-09-07 04:07:53

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

更改您的工作线程以将 Images 引用发送到 EDT 并重写 SwingWorkerprocess(Listchunks) 方法以在 EDT 上接收该 Images,并且更新组件的模型以显示图片。

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,而其他照片仍在从互联网下载或从磁盘加载。

Why don't you use the publish-process mechanism to send intermediate results from the background worker thread to the EDT? Seems that you are using SwingWorker#publish(V) to tell about the progress of the task to the user and you can achieve checking the thread progress or updating a PropertyChangeListener.

Change your worker to send Images references to the EDT and override SwingWorkerprocess(List<V> chunks) method to receive that Images on EDT, and update a component's model to display the pictures.

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   
    }
}

Calling SwingWorker#get() method can block the EDT, meanwhile using the publish-process mechanism you can update your UI everytime a single photo become available, while the others are still downloading from the Internet or loading from the disk.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文