How to return a list using SwingWorker
I have an assignment where I need to create an image gallery that uses SwingWorker
to load images from a file, as soon as the image is loaded, you can click on the image and start the slideshow. I am having problems getting the list of uploaded images using SwingWorker
.
This is what happens in the background, it just posts the results to the 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's done i just paste the images in List<Image>
and that's all it does.
// In the EDT
@Override protected void done () {try {
for (Image image : get()) {
list.add(image);
}
} catch (Exception e) { }
}
Also I created a method that returns list
called getImages()
what I need to get is a list from getImages()
, but the seam doesn't work when I call execute()
for example
MySwingWorkerClass swingworker = new MySwingWorkerClass(log,list,filenames);
swingworker.execute();
imageList = swingworker.getImage()
Once it reaches imageList
, it returns nothing, the only way to get the list is when I used run()
instead execute()
, is there another way to get the list or the method is the run()
only way ?. or maybe I don't understand the class Swing Worker
.
a source to share
I think that you are wrong and a SwingWorker
little. Most of them are correct, but you cannot call getImage()
immediately after execute()
- the execution call returns immediately and your images are loaded onto the worker thread. So the immediate call getImages()
has no images to retrieve.
To fix this, you have to do image processing in an override done()
eg. by adding images to a UI component that will display them.
a source to share
... or maybe I don't understand the class
SwingWorker
.
You must know the life cycle SwingWorker
. When you call execute, your processing switches to the background thread and the current thread will return immediately. This is why yours getImages
doesn't return anything. From the javadoc :
Workflow
There are three threads involved in the SwingWorker lifecycle:
Current thread: The execute () method is called on this thread. It schedules the SwingWorker to run on the worker thread and returns immediately. You can wait for SwingWorker to finish using get methods.
Worker thread: The doInBackground () method is called on this thread. All background activities take place here. To notify PropertyChangeListeners of associated property changes, use the firePropertyChange and getPropertyChangeSupport () methods. By default, there are two related properties available: status and progress.
Event Dispatch Thread: All Swing-related activities take place in this thread. The SwingWorker calls the process and done () methods and notifies the PropertyChangeListeners.
a source to share
Why aren't you using a posting mechanism to submit intermediate results from a workflow to EDT
? It seems that you are using SwingWorker#publish(V)
to communicate the progress of a task to the user and you can achieve a progress check or update PropertyChangeListener
.
Modify your worker to send Image references to the method EDT
and override SwingWorkerprocess(List<V> chunks)
to get images in EDT
and update the component model to display 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
}
}
Calling the SwingWorker # get () method can block EDT, meanwhile, using the publishing mechanism, you can update your interface every time one photo becomes available and others are still being downloaded from the Internet or downloaded from disk.
a source to share