Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 2604)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 2606)
@@ -644,7 +644,8 @@
 
             if (yLayer.loadThumbs) {
-                Thread tl = new Thread(new ThumbsLoader(yLayer.data));
-                tl.setPriority(Thread.MIN_PRIORITY);
-                tl.start();
+                yLayer.thumbsloader = new ThumbsLoader(yLayer.data);
+                Thread t = new Thread(yLayer.thumbsloader);
+                t.setPriority(Thread.MIN_PRIORITY);
+                t.start();
             }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 2604)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 2606)
@@ -72,4 +72,5 @@
 
     boolean loadThumbs;
+    ThumbsLoader thumbsloader;
 
     /*
@@ -542,6 +543,4 @@
 
                 ImageViewerDialog d = ImageViewerDialog.getInstance();
-//                System.err.println(d.isDialogShowing());
-
 
                 for (int i = data.size() - 1; i >= 0; --i) {
@@ -586,3 +585,10 @@
         });
     }
+    
+    @Override
+    public void destroy() {
+        if (thumbsloader != null) {
+            thumbsloader.stop = true;
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java	(revision 2604)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java	(revision 2606)
@@ -11,42 +11,34 @@
 import java.awt.image.BufferedImage;
 import java.io.File;
+import java.util.ArrayList;
 import java.util.List;
 
+import org.openstreetmap.josm.io.CacheFiles;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer.ImageEntry;
 
 public class ThumbsLoader implements Runnable {
+        volatile boolean stop = false;
         List<ImageEntry> data;
+        MediaTracker tracker;
+        CacheFiles cache;
+        boolean cacheOff = Main.pref.getBoolean("geoimage.noThumbnailCache", false);
+        
         public ThumbsLoader(List<ImageEntry> data) {
-            this.data = data;
+            this.data = new ArrayList<ImageEntry>(data);
+            if (!cacheOff) {
+                cache = new CacheFiles("geoimage-thumbnails", false);
+                cache.setExpire(CacheFiles.EXPIRE_NEVER, false);
+                cache.setMaxSize(120, false);
+            }
         }
 
         public void run() {
             System.err.println("Load Thumbnails");
-            MediaTracker tracker = new MediaTracker(Main.map.mapView);
+            tracker = new MediaTracker(Main.map.mapView);
             for (int i = 0; i < data.size(); i++) {
-                System.err.println("getImg "+i);
-                String path;
-                path = data.get(i).file.getPath();
-                Image img = Toolkit.getDefaultToolkit().createImage(path);
-                tracker.addImage(img, 0);
-                try {
-                    tracker.waitForID(0);
-                } catch (InterruptedException e) {
-                    System.err.println("InterruptedException");
-                    return; //  FIXME
-                }
-                BufferedImage scaledBI = new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
-                Graphics2D g = scaledBI.createGraphics();
-                while (!g.drawImage(img, 0, 0, 16, 16, null))
-                {
-                    try {
-                        Thread.sleep(10);
-                    } catch(InterruptedException ie) {}
-                }
-                g.dispose();
-                tracker.removeImage(img);
-
-                data.get(i).thumbnail = scaledBI;
+                if (stop) return;
+                System.err.print("fetching image "+i);
+                data.get(i).thumbnail = loadThumb(data.get(i));
                 if (Main.map != null && Main.map.mapView != null) {
                     Main.map.mapView.repaint();
@@ -63,10 +55,43 @@
             }).start();
 
-//                boolean error = tracker.isErrorID(1);
-//                if (img != null && (img.getWidth(null) == 0 || img.getHeight(null) == 0)) {
-//                    error = true;
-//                }
-
-
+        }
+        
+        private BufferedImage loadThumb(ImageEntry entry) {
+            final int size = 16;
+            final String cacheIdent = entry.file.toString()+":"+size;
+            
+            if (!cacheOff) {
+                BufferedImage cached = cache.getImg(cacheIdent);
+                if(cached != null) {
+                    System.err.println(" from cache"); 
+                    return cached;
+                }
+            }
+            
+            Image img = Toolkit.getDefaultToolkit().createImage(entry.file.getPath());
+            tracker.addImage(img, 0);
+            try {
+                tracker.waitForID(0);
+            } catch (InterruptedException e) {
+                System.err.println(" InterruptedException");
+                return null;
+            }
+            BufferedImage scaledBI = new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
+            Graphics2D g = scaledBI.createGraphics();
+            while (!g.drawImage(img, 0, 0, 16, 16, null))
+            {
+                try {
+                    Thread.sleep(10);
+                } catch(InterruptedException ie) {} //FIXME: timeout?
+            }
+            g.dispose();
+            tracker.removeImage(img);
+            
+            if (!cacheOff && scaledBI != null && scaledBI.getWidth() > 0) {
+                cache.saveImg(cacheIdent, scaledBI);
+            }
+            
+            System.err.println("");
+            return scaledBI;
         }
 
Index: trunk/src/org/openstreetmap/josm/io/CacheFiles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/CacheFiles.java	(revision 2604)
+++ trunk/src/org/openstreetmap/josm/io/CacheFiles.java	(revision 2606)
@@ -55,5 +55,10 @@
      */
     public CacheFiles(String ident) {
-        String pref = Main.pref.getPluginsDirFile().getPath();
+        this(ident, true);
+    }
+    
+    public CacheFiles(String ident, boolean isPlugin) {
+        String pref = isPlugin ? Main.pref.getPluginsDirFile().getPath() : Main.pref.getPreferencesDir();
+        
         boolean dir_writeable;
         this.ident = ident;
