Consider using a SwingWorker
in combination with an ExecutorService
...
SwingWorker...
public class ImageLoaderWorker extends SwingWorker<Image, Image> {
private File source;
private JPanel container;
public ImageLoaderWorker(File source, JPanel container) {
this.source = source;
this.container = container;
}
@Override
protected Image doInBackground() throws Exception {
return ImageIO.read(source);
}
@Override
protected void done() {
try {
Image img = get();
JLabel label = new JLabel(new ImageIcon(img));
container.add(label);
container.revalidate();
container.repaint();
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}
}
ExecutorService...
ExecutorService executor = Executors.newFixedThreadPool(4);
File images[] = new File("...").listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
String name = pathname.getName().toLowerCase();
return name.endsWith(".jpg") || name.endsWith(".png");
}
});
for (File img : images) {
executor.submit(new ImageLoaderWorker(img, this));
}
Runnable Example...
This simply scans a directory and loads the images, but the concept is basically the same...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestImageLoader {
public static void main(String[] args) {
new TestImageLoader();
}
public TestImageLoader() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(new TestPane()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel implements Scrollable {
public TestPane() {
setLayout(new GridLayout(0, 4));
ExecutorService executor = Executors.newFixedThreadPool(4);
File images[] = new File("...").listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
String name = pathname.getName().toLowerCase();
return name.endsWith(".jpg") || name.endsWith(".png");
}
});
for (File img : images) {
executor.submit(new ImageLoaderWorker(img, this));
}
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(600, 600);
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return false;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
public class ImageLoaderWorker extends SwingWorker<Image, Image> {
private File source;
private JPanel container;
public ImageLoaderWorker(File source, JPanel container) {
this.source = source;
this.container = container;
}
@Override
protected Image doInBackground() throws Exception {
return ImageIO.read(source);
}
@Override
protected void done() {
try {
Image img = get();
JLabel label = new JLabel(new ImageIcon(img));
container.add(label);
container.revalidate();
container.repaint();
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…