JfileChooser abrindo Imagem em Thumbnail com performance

[code] package br.com.B.component.filechooser;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileView;

public class BJFileChooser extends JFileChooser {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/** All preview icons will be this width and height */
	private static int ICON_SIZE = 60;

	/** This blank icon will be used while previews are loading */
	private static final Image LOADING_IMAGE = new BufferedImage(ICON_SIZE, ICON_SIZE, BufferedImage.TYPE_INT_ARGB);

	/** Edit this to determine what file types will be previewed. */
	private final Pattern imageFilePattern = Pattern.compile(".+?\\.(png|jpe?g|gif|tiff?)$", Pattern.CASE_INSENSITIVE);

	/** Use a weak hash map to cache images until the next garbage collection (saves memory) */
	private final Map<File, ImageIcon> imageCache = new WeakHashMap<File, ImageIcon>();

	public BJFileChooser() {
		super();
		setFileView(new ThumbnailView());
	}
	
	public void setIconSize(int size) {
		ICON_SIZE = size;
	}

	private class ThumbnailView extends FileView {
		/** This thread pool is where the thumbnail icon loaders run */
		private final ExecutorService executor = Executors.newCachedThreadPool();

		public String getName(File file){
			String name = file.getName();
			if("".equals(name)){
				return "/";
			}
			else{
				String substring = "";
				String extensao = "";
				
				if(name.length() > 25 && (name.contains("jpg") || name.contains("gif") || name.contains("png"))){
					substring = name.substring(0, 25);
				}
				
				if(substring.equals("")){
					return name;
				}else{
					extensao = name.substring(name.lastIndexOf("."), name.length());  
					return substring + extensao;
				}
			}
		}
		
		public Icon getIcon(File file) {
			if (!imageFilePattern.matcher(file.getName()).matches()) {
				return null;
			}

			// Our cache makes browsing back and forth lightning-fast! :D
			synchronized (imageCache) {
				ImageIcon icon = (ImageIcon) imageCache.get(file);

				if (icon == null) {
					// Create a new icon with the default image
					icon = new ImageIcon(LOADING_IMAGE);

					// Add to the cache
					imageCache.put(file, icon);

					// Submit a new task to load the image and update the icon
					executor.submit(new ThumbnailIconLoader(icon, file));
				}

				return icon;
			}
		}
	}

	private class ThumbnailIconLoader implements Runnable {
		private final ImageIcon icon;
		private final File file;

		public ThumbnailIconLoader(ImageIcon i, File f) {
			icon = i;
			file = f;
		}

		public void run() {
				// Load and scale the image down, then replace the icon's old image with the new one.
				ImageIcon newIcon = new ImageIcon(file.getAbsolutePath());
				Image img = newIcon.getImage();

				// calc dimension
				int width = img.getWidth(null);
				int height = img.getHeight(null);

				int newWidth;
				int newHeight;
				double factor;

				if(width > height){
					factor = (double)height/width;
					newWidth = ICON_SIZE;
					newHeight = (int)(ICON_SIZE*factor);
				}
				else{
					factor = (double)width/height;
					newHeight = ICON_SIZE;
					newWidth = (int)(ICON_SIZE*factor);
				}

				img = img.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
				icon.setImage(img);

				// Repaint the dialog so we see the new icon.
				SwingUtilities.invokeLater(new Runnable() {public void run() {repaint();}});

			}
		}
	}

[/code]

Quando abro uma pasta com muitas imagens ocorre Java heap space…
Como posso ter performance com isso?
Como pego somente os Files que estão na tela e exibo Thumbnail ?
Alguma outra ideia ?

Usa um FileDialog nativo

Ex: o do AWT (mas não suporta filtros e é antigo, não é o mais novo que o Windows 7 usa, a aparência dele no Linux é uma aberração também)

Outras opções:

http://code.google.com/p/xfiledialog/
Permite usar o FileDialog + recente do Windows, adiciona só uns 200k na aplicação e é super simples de usar


Esse não sei usar, mas deve suportar os FileDialogs nativos do Windows, Mac e Linux