import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileFilter; import java.util.Arrays; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import javax.imageio.ImageIO; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JScrollPane; import javax.swing.ScrollPaneConstants; import javax.swing.SwingWorker; import org.imgscalr.Scalr; public class ImageThumbList extends JFrame { private final int THUMB_WIDTH; private final int THUMB_HEIGHT; private final int HORIZONTAL_SPACING; private final int VERTICAL_SPACING; private final Color BACKGROUND; private final String IMAGES_DIR_PATH; private final double THUMB_RATIO; private LinkedBlockingQueue<File> queue; private boolean useSwingWorker; private JList iconJList; private JScrollPane iconJListScrollPane; private DefaultListCellRenderer iconJListRenderer; private DefaultListModel iconJListModel; public ImageThumbList() { THUMB_WIDTH = 174; THUMB_HEIGHT = 174; HORIZONTAL_SPACING = 10; VERTICAL_SPACING = 10; IMAGES_DIR_PATH = ImagePath; THUMB_RATIO = (double) THUMB_WIDTH / (double) THUMB_HEIGHT; BACKGROUND = new Color(Integer.parseInt("646464", 16)); useSwingWorker = true; initComponents(); } private void initComponents() { setLayout(new BorderLayout()); iconJListModel = new DefaultListModel(); iconJList = new JList(iconJListModel); iconJListRenderer = (DefaultListCellRenderer) iconJList .getCellRenderer(); iconJListScrollPane = new JScrollPane(iconJList); iconJList.setLayoutOrientation(JList.HORIZONTAL_WRAP); iconJList.setFixedCellHeight(THUMB_HEIGHT + VERTICAL_SPACING); iconJList.setFixedCellWidth(THUMB_WIDTH + HORIZONTAL_SPACING); iconJList.setBackground(BACKGROUND); iconJList.setVisibleRowCount(-1); iconJListRenderer.setHorizontalAlignment(JLabel.CENTER); iconJListRenderer.setVerticalAlignment(JLabel.CENTER); iconJListScrollPane .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); add(iconJListScrollPane, BorderLayout.CENTER); } public void start() { queue = new LinkedBlockingQueue<File>(); queue.addAll(Arrays.asList(new File(IMAGES_DIR_PATH) .listFiles(new FileFilter() { @Override public boolean accept(File dir) { return dir.isFile(); } }))); if (useSwingWorker) { new SimpleThumbnailGenerator().execute(); } else { new Thread(new ExecutorServiceThumbnailGenerator()).start(); } } private class SimpleThumbnailGenerator extends SwingWorker<Void, BufferedImage> { @Override public Void doInBackground() { while (!isCancelled()) { File file = null; try { file = queue.take(); } catch (InterruptedException e) { e.printStackTrace(); } publish(getThumbnail(file)); } return null; } @Override public void process(List<BufferedImage> lista) { for (BufferedImage c : lista) { if (c != null) { iconJListModel.addElement(new ImageIcon(c)); } } } } private class ExecutorServiceThumbnailGenerator implements Runnable { private ExecutorService pool; public ExecutorServiceThumbnailGenerator() { pool = Executors.newFixedThreadPool(Runtime.getRuntime() .availableProcessors()); } @Override public void run() { try { while (true) { pool.execute(new ThumbnailGenerator(queue.take())); } } catch (InterruptedException ie) { ie.printStackTrace(); } finally { pool.shutdown(); } } } private class ThumbnailGenerator extends SwingWorker<Void, BufferedImage> { File file; ThumbnailGenerator(File file) { this.file = file; } @Override public Void doInBackground() { publish(getThumbnail(file)); return null; } @Override public void process(List<BufferedImage> lista) { for (BufferedImage c : lista) { if (c != null) { iconJListModel.addElement(new ImageIcon(c)); } } } } private BufferedImage getThumbnail(File file) { BufferedImage thumbnail = null; if (file != null) { try { thumbnail = ImageIO.read(file); } catch (Exception e) { e.printStackTrace(); } if (thumbnail != null) { int thumbWidth = THUMB_WIDTH; int thumbHeight = THUMB_HEIGHT; // determine thumbnail size from WIDTH and HEIGHT double imageRatio = (double) thumbnail.getWidth(null) / (double) thumbnail.getHeight(null); if (THUMB_RATIO < imageRatio) { thumbHeight = (int) (thumbWidth / imageRatio); } else { thumbWidth = (int) (thumbHeight * imageRatio); } thumbnail = Scalr.resize(thumbnail, thumbWidth, thumbHeight); } } return thumbnail; } public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { ImageThumbList frame = new ImageThumbList(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(800, 445); frame.setPreferredSize(new Dimension(800, 445)); frame.setLocationRelativeTo(null); frame.setVisible(true); frame.start(); } }); } }