Index: /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 9269)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 9270)
@@ -157,5 +157,5 @@
                     if (yLayer.data != null) {
                         for (ImageEntry ie : yLayer.data) {
-                            ie.tmp = null;
+                            ie.discardTmp();
                         }
                     }
@@ -826,5 +826,5 @@
             if (yLayer.data != null) {
                 for (ImageEntry ie: yLayer.data) {
-                    ie.tmp = null;
+                    ie.discardTmp();
                 }
             }
@@ -834,5 +834,6 @@
             // Create a temporary copy for each image
             for (ImageEntry ie : dateImgLst) {
-                ie.cleanTmp();
+                ie.createTmp();
+                ie.tmp.setPos(null);
             }
 
Index: /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 9269)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 9270)
@@ -22,11 +22,8 @@
 import java.io.File;
 import java.io.IOException;
-import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Calendar;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.GregorianCalendar;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -34,5 +31,4 @@
 import java.util.List;
 import java.util.Set;
-import java.util.TimeZone;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -50,5 +46,4 @@
 import org.openstreetmap.josm.actions.mapmode.SelectAction;
 import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.gui.ExtendedDialog;
@@ -68,15 +63,6 @@
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.io.JpgImporter;
-import org.openstreetmap.josm.tools.ExifReader;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Utils;
-
-import com.drew.imaging.jpeg.JpegMetadataReader;
-import com.drew.lang.CompoundException;
-import com.drew.metadata.Directory;
-import com.drew.metadata.Metadata;
-import com.drew.metadata.MetadataException;
-import com.drew.metadata.exif.ExifIFD0Directory;
-import com.drew.metadata.exif.GpsDirectory;
 
 /**
@@ -158,16 +144,6 @@
                 progressMonitor.worked(1);
 
-                ImageEntry e = new ImageEntry();
-
-                // Changed to silently cope with no time info in exif. One case
-                // of person having time that couldn't be parsed, but valid GPS info
-
-                try {
-                    e.setExifTime(ExifReader.readTime(f));
-                } catch (ParseException ex) {
-                    e.setExifTime(null);
-                }
-                e.setFile(f);
-                extractExif(e);
+                ImageEntry e = new ImageEntry(f);
+                e.extractExif();
                 data.add(e);
             }
@@ -499,9 +475,9 @@
                         }
                         Point p = mv.getPoint(e.getPos());
-                        if (e.thumbnail != null) {
-                            Dimension d = scaledDimension(e.thumbnail);
+                        if (e.hasThumbnail()) {
+                            Dimension d = scaledDimension(e.getThumbnail());
                             Rectangle target = new Rectangle(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
                             if (clip.intersects(target)) {
-                                tempG.drawImage(e.thumbnail, target.x, target.y, target.width, target.height, null);
+                                tempG.drawImage(e.getThumbnail(), target.x, target.y, target.width, target.height, null);
                             }
                         } else { // thumbnail not loaded yet
@@ -535,6 +511,6 @@
                 int imgWidth = 100;
                 int imgHeight = 100;
-                if (useThumbs && e.thumbnail != null) {
-                    Dimension d = scaledDimension(e.thumbnail);
+                if (useThumbs && e.hasThumbnail()) {
+                    Dimension d = scaledDimension(e.getThumbnail());
                     imgWidth = d.width;
                     imgHeight = d.height;
@@ -574,5 +550,5 @@
                 }
 
-                if (useThumbs && e.thumbnail != null) {
+                if (useThumbs && e.hasThumbnail()) {
                     g.setColor(new Color(128, 0, 0, 122));
                     g.fillRect(p.x - imgWidth / 2, p.y - imgHeight / 2, imgWidth, imgHeight);
@@ -591,124 +567,4 @@
         for (ImageEntry e : data) {
             v.visit(e.getPos());
-        }
-    }
-
-    /**
-     * Extract GPS metadata from image EXIF
-     *
-     * If successful, fills in the LatLon and EastNorth attributes of passed in image
-     * @param e image entry
-     */
-    private static void extractExif(ImageEntry e) {
-
-        Metadata metadata;
-        Directory dirExif;
-        GpsDirectory dirGps;
-
-        try {
-            metadata = JpegMetadataReader.readMetadata(e.getFile());
-            dirExif = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
-            dirGps = metadata.getFirstDirectoryOfType(GpsDirectory.class);
-        } catch (CompoundException | IOException p) {
-            e.setExifCoor(null);
-            e.setPos(null);
-            return;
-        }
-
-        try {
-            if (dirExif != null) {
-                int orientation = dirExif.getInt(ExifIFD0Directory.TAG_ORIENTATION);
-                e.setExifOrientation(orientation);
-            }
-        } catch (MetadataException ex) {
-            Main.debug(ex.getMessage());
-        }
-
-        if (dirGps == null) {
-            e.setExifCoor(null);
-            e.setPos(null);
-            return;
-        }
-
-        try {
-            double speed = dirGps.getDouble(GpsDirectory.TAG_SPEED);
-            String speedRef = dirGps.getString(GpsDirectory.TAG_SPEED_REF);
-            if ("M".equalsIgnoreCase(speedRef)) {
-                // miles per hour
-                speed *= 1.609344;
-            } else if ("N".equalsIgnoreCase(speedRef)) {
-                // knots == nautical miles per hour
-                speed *= 1.852;
-            }
-            // default is K (km/h)
-            e.setSpeed(speed);
-        } catch (Exception ex) {
-            Main.debug(ex.getMessage());
-        }
-
-        try {
-            double ele = dirGps.getDouble(GpsDirectory.TAG_ALTITUDE);
-            int d = dirGps.getInt(GpsDirectory.TAG_ALTITUDE_REF);
-            if (d == 1) {
-                ele *= -1;
-            }
-            e.setElevation(ele);
-        } catch (MetadataException ex) {
-            Main.debug(ex.getMessage());
-        }
-
-        try {
-            LatLon latlon = ExifReader.readLatLon(dirGps);
-            e.setExifCoor(latlon);
-            e.setPos(e.getExifCoor());
-
-        } catch (Exception ex) { // (other exceptions, e.g. #5271)
-            Main.error("Error reading EXIF from file: "+ex);
-            e.setExifCoor(null);
-            e.setPos(null);
-        }
-
-        try {
-            Double direction = ExifReader.readDirection(dirGps);
-            if (direction != null) {
-                e.setExifImgDir(direction.doubleValue());
-            }
-        } catch (Exception ex) { // (CompoundException and other exceptions, e.g. #5271)
-            Main.debug(ex.getMessage());
-        }
-
-        // Time and date. We can have these cases:
-        // 1) GPS_TIME_STAMP not set -> date/time will be null
-        // 2) GPS_DATE_STAMP not set -> use EXIF date or set to default
-        // 3) GPS_TIME_STAMP and GPS_DATE_STAMP are set
-        int[] timeStampComps = dirGps.getIntArray(GpsDirectory.TAG_TIME_STAMP);
-        if (timeStampComps != null) {
-            int gpsHour = timeStampComps[0];
-            int gpsMin = timeStampComps[1];
-            int gpsSec = timeStampComps[2];
-            Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
-
-            // We have the time. Next step is to check if the GPS date stamp is set.
-            // dirGps.getString() always succeeds, but the return value might be null.
-            String dateStampStr = dirGps.getString(GpsDirectory.TAG_DATE_STAMP);
-            if (dateStampStr != null && dateStampStr.matches("^\\d+:\\d+:\\d+$")) {
-                String[] dateStampComps = dateStampStr.split(":");
-                cal.set(Calendar.YEAR, Integer.parseInt(dateStampComps[0]));
-                cal.set(Calendar.MONTH, Integer.parseInt(dateStampComps[1]) - 1);
-                cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateStampComps[2]));
-            } else {
-                // No GPS date stamp in EXIF data. Copy it from EXIF time.
-                // Date is not set if EXIF time is not available.
-                if (e.hasExifTime()) {
-                    // Time not set yet, so we can copy everything, not just date.
-                    cal.setTime(e.getExifTime());
-                }
-            }
-
-            cal.set(Calendar.HOUR_OF_DAY, gpsHour);
-            cal.set(Calendar.MINUTE, gpsMin);
-            cal.set(Calendar.SECOND, gpsSec);
-
-            e.setExifGpsTime(cal.getTime());
         }
     }
@@ -862,6 +718,6 @@
                 Point p = Main.map.mapView.getPoint(img.getPos());
                 Rectangle r;
-                if (useThumbs && img.thumbnail != null) {
-                    Dimension d = scaledDimension(img.thumbnail);
+                if (useThumbs && img.hasThumbnail()) {
+                    Dimension d = scaledDimension(img.getThumbnail());
                     r = new Rectangle(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
                 } else {
@@ -972,6 +828,6 @@
                     Point p = Main.map.mapView.getPoint(e.getPos());
                     Rectangle r;
-                    if (useThumbs && e.thumbnail != null) {
-                        Dimension d = scaledDimension(e.thumbnail);
+                    if (useThumbs && e.hasThumbnail()) {
+                        Dimension d = scaledDimension(e.getThumbnail());
                         r = new Rectangle(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
                     } else {
Index: /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java	(revision 9269)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java	(revision 9270)
@@ -4,8 +4,23 @@
 import java.awt.Image;
 import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.Calendar;
 import java.util.Date;
-
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import com.drew.imaging.jpeg.JpegMetadataReader;
+import com.drew.lang.CompoundException;
+import com.drew.metadata.Directory;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.MetadataException;
+import com.drew.metadata.exif.ExifIFD0Directory;
+import com.drew.metadata.exif.GpsDirectory;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.SystemOfMeasurement;
 import org.openstreetmap.josm.data.coor.CachedLatLon;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.tools.ExifReader;
 
 /**
@@ -26,5 +41,5 @@
     /** Temporary source of GPS time if not correlated with GPX track. */
     private Date exifGpsTime;
-    Image thumbnail;
+    private Image thumbnail;
 
     /**
@@ -44,5 +59,5 @@
      * for the current time offset on the map in real time.
      * On the other hand, when the user aborts this operation, the old values
-     * should be restored. We have a temprary copy, that overrides
+     * should be restored. We have a temporary copy, that overrides
      * the normal values if it is not null. (This may be not the most elegant
      * solution for this, but it works.)
@@ -51,6 +66,20 @@
 
     /**
-     * Returns the cached temporary position value.
-     * @return the cached temporary position value
+     * Constructs a new {@code ImageEntry}.
+     */
+    public ImageEntry() {}
+
+    /**
+     * Constructs a new {@code ImageEntry}.
+     * @param file Path to image file on disk
+     */
+    public ImageEntry(File file) {
+        setFile(file);
+    }
+
+    /**
+     * Returns the position value. The position value from the temporary copy
+     * is returned if that copy exists.
+     * @return the position value
      */
     public CachedLatLon getPos() {
@@ -61,6 +90,7 @@
 
     /**
-     * Returns the cached temporary speed value.
-     * @return the cached temporary speed value
+     * Returns the speed value. The speed value from the temporary copy is
+     * returned if that copy exists.
+     * @return the speed value
      */
     public Double getSpeed() {
@@ -71,6 +101,7 @@
 
     /**
-     * Returns the cached temporary elevation value.
-     * @return the cached temporary elevation value
+     * Returns the elevation value. The elevation value from the temporary
+     * copy is returned if that copy exists.
+     * @return the elevation value
      */
     public Double getElevation() {
@@ -81,6 +112,7 @@
 
     /**
-     * Returns the cached temporary GPS time value.
-     * @return the cached temporary GPS time value
+     * Returns the GPS time value. The GPS time value from the temporary copy
+     * is returned if that copy exists.
+     * @return the GPS time value
      */
     public Date getGpsTime() {
@@ -161,7 +193,13 @@
 
     public Double getExifImgDir() {
+        if (tmp != null)
+            return tmp.exifImgDir;
         return exifImgDir;
     }
 
+    /**
+     * Determines whether a thumbnail is set
+     * @return {@code true} if a thumbnail is set
+     */
     public boolean hasThumbnail() {
         return thumbnail != null;
@@ -169,4 +207,20 @@
 
     /**
+     * Returns the thumbnail.
+     * @return the thumbnail
+     */
+    public Image getThumbnail() {
+        return thumbnail;
+    }
+
+    /**
+     * Sets the thumbnail.
+     * @param thumbnail thumbnail
+     */
+    public void setThumbnail(Image thumbnail) {
+        this.thumbnail = thumbnail;
+    }
+
+    /**
      * Sets the position.
      * @param pos cached position
@@ -181,5 +235,5 @@
      */
     public void setPos(LatLon pos) {
-        setPos(new CachedLatLon(pos));
+        setPos(pos != null ? new CachedLatLon(pos) : null);
     }
 
@@ -241,5 +295,5 @@
     }
 
-    public void setExifImgDir(double exifDir) {
+    public void setExifImgDir(Double exifDir) {
         this.exifImgDir = exifDir;
     }
@@ -269,14 +323,31 @@
 
     /**
-     * Make a fresh copy and save it in the temporary variable.
-     */
-    public void cleanTmp() {
+     * Make a fresh copy and save it in the temporary variable. Use
+     * {@link #applyTmp()} or {@link #discardTmp()} if the temporary variable
+     * is not needed anymore.
+     */
+    public void createTmp() {
         tmp = clone();
-        tmp.setPos(null);
         tmp.tmp = null;
     }
 
     /**
-     * Copy the values from the temporary variable to the main instance.
+     * Get temporary variable that is used for real time parameter
+     * adjustments. The temporary variable is created if it does not exist
+     * yet. Use {@link #applyTmp()} or {@link #discardTmp()} if the temporary
+     * variable is not needed anymore.
+     * @return temporary variable
+     */
+    public ImageEntry getTmp() {
+        if (tmp == null) {
+            createTmp();
+        }
+        return tmp;
+    }
+
+    /**
+     * Copy the values from the temporary variable to the main instance. The
+     * temporary variable is deleted.
+     * @see #discardTmp()
      */
     public void applyTmp() {
@@ -286,6 +357,15 @@
             elevation = tmp.elevation;
             gpsTime = tmp.gpsTime;
+            exifImgDir = tmp.exifImgDir;
             tmp = null;
         }
+    }
+
+    /**
+     * Delete the temporary variable. Temporary modifications are lost.
+     * @see #applyTmp()
+     */
+    public void discardTmp() {
+        tmp = null;
     }
 
@@ -336,3 +416,134 @@
         return isNewGpsData;
     }
+
+    /**
+     * Extract GPS metadata from image EXIF. Has no effect if the image file is not set
+     *
+     * If successful, fills in the LatLon, speed, elevation, image direction, and other attributes
+     */
+    public void extractExif() {
+
+        Metadata metadata;
+        Directory dirExif;
+        GpsDirectory dirGps;
+
+        if (file == null) {
+            return;
+        }
+
+        try {
+            metadata = JpegMetadataReader.readMetadata(file);
+            dirExif = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
+            dirGps = metadata.getFirstDirectoryOfType(GpsDirectory.class);
+        } catch (CompoundException | IOException p) {
+            setExifCoor(null);
+            setPos(null);
+            return;
+        }
+
+        try {
+            if (dirExif != null) {
+                int orientation = dirExif.getInt(ExifIFD0Directory.TAG_ORIENTATION);
+                setExifOrientation(orientation);
+            }
+        } catch (MetadataException ex) {
+            Main.debug(ex.getMessage());
+        }
+
+        if (dirGps == null) {
+            setExifCoor(null);
+            setPos(null);
+            return;
+        }
+
+        try {
+            double speed = dirGps.getDouble(GpsDirectory.TAG_SPEED);
+            String speedRef = dirGps.getString(GpsDirectory.TAG_SPEED_REF);
+            if ("M".equalsIgnoreCase(speedRef)) {
+                // miles per hour
+                speed *= SystemOfMeasurement.IMPERIAL.bValue / 1000;
+            } else if ("N".equalsIgnoreCase(speedRef)) {
+                // knots == nautical miles per hour
+                speed *= SystemOfMeasurement.NAUTICAL_MILE.bValue / 1000;
+            }
+            // default is K (km/h)
+            setSpeed(speed);
+        } catch (Exception ex) {
+            Main.debug(ex.getMessage());
+        }
+
+        try {
+            double ele = dirGps.getDouble(GpsDirectory.TAG_ALTITUDE);
+            int d = dirGps.getInt(GpsDirectory.TAG_ALTITUDE_REF);
+            if (d == 1) {
+                ele *= -1;
+            }
+            setElevation(ele);
+        } catch (MetadataException ex) {
+            Main.debug(ex.getMessage());
+        }
+
+        try {
+            LatLon latlon = ExifReader.readLatLon(dirGps);
+            setExifCoor(latlon);
+            setPos(getExifCoor());
+
+        } catch (Exception ex) { // (other exceptions, e.g. #5271)
+            Main.error("Error reading EXIF from file: " + ex);
+            setExifCoor(null);
+            setPos(null);
+        }
+
+        try {
+            Double direction = ExifReader.readDirection(dirGps);
+            if (direction != null) {
+                setExifImgDir(direction);
+            }
+        } catch (Exception ex) { // (CompoundException and other exceptions, e.g. #5271)
+            Main.debug(ex.getMessage());
+        }
+
+        // Changed to silently cope with no time info in exif. One case
+        // of person having time that couldn't be parsed, but valid GPS info
+        try {
+            setExifTime(ExifReader.readTime(file));
+        } catch (ParseException ex) {
+            setExifTime(null);
+        }
+
+        // Time and date. We can have these cases:
+        // 1) GPS_TIME_STAMP not set -> date/time will be null
+        // 2) GPS_DATE_STAMP not set -> use EXIF date or set to default
+        // 3) GPS_TIME_STAMP and GPS_DATE_STAMP are set
+        int[] timeStampComps = dirGps.getIntArray(GpsDirectory.TAG_TIME_STAMP);
+        if (timeStampComps != null) {
+            int gpsHour = timeStampComps[0];
+            int gpsMin = timeStampComps[1];
+            int gpsSec = timeStampComps[2];
+            Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+
+            // We have the time. Next step is to check if the GPS date stamp is set.
+            // dirGps.getString() always succeeds, but the return value might be null.
+            String dateStampStr = dirGps.getString(GpsDirectory.TAG_DATE_STAMP);
+            if (dateStampStr != null && dateStampStr.matches("^\\d+:\\d+:\\d+$")) {
+                String[] dateStampComps = dateStampStr.split(":");
+                cal.set(Calendar.YEAR, Integer.parseInt(dateStampComps[0]));
+                cal.set(Calendar.MONTH, Integer.parseInt(dateStampComps[1]) - 1);
+                cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateStampComps[2]));
+            } else {
+                // No GPS date stamp in EXIF data. Copy it from EXIF time.
+                // Date is not set if EXIF time is not available.
+                if (hasExifTime()) {
+                    // Time not set yet, so we can copy everything, not just date.
+                    cal.setTime(getExifTime());
+                }
+            }
+
+            cal.set(Calendar.HOUR_OF_DAY, gpsHour);
+            cal.set(Calendar.MINUTE, gpsMin);
+            cal.set(Calendar.SECOND, gpsSec);
+
+            setExifGpsTime(cal.getTime());
+        }
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java	(revision 9269)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java	(revision 9270)
@@ -70,4 +70,5 @@
     private JButton btnPrevious;
     private JButton btnCollapse;
+    private JToggleButton tbCentre;
 
     private ImageViewerDialog() {
@@ -150,5 +151,5 @@
         );
 
-        JToggleButton tbCentre = new JToggleButton(new ImageAction(COMMAND_CENTERVIEW,
+        tbCentre = new JToggleButton(new ImageAction(COMMAND_CENTERVIEW,
                 ImageProvider.get("dialogs", "centreview"), tr("Center view")));
         tbCentre.setPreferredSize(buttonDim);
@@ -225,5 +226,6 @@
                 currentLayer.showLastPhoto();
             } else if (COMMAND_CENTERVIEW.equals(action)) {
-                centerView = ((JToggleButton) e.getSource()).isSelected();
+                final JToggleButton button = (JToggleButton) e.getSource();
+                centerView = button.isEnabled() && button.isSelected();
                 if (centerView && currentEntry != null && currentEntry.getPos() != null) {
                     Main.map.mapView.zoomTo(currentEntry.getPos());
@@ -276,4 +278,17 @@
     }
 
+    /**
+     * Enables (or disables) the "Center view" button.
+     * @param value {@code true} to enable the button, {@code false} otherwise
+     * @return the old enabled value. Can be used to restore the original enable state
+     */
+    public static synchronized boolean setCentreEnabled(boolean value) {
+        final ImageViewerDialog instance = getInstance();
+        final boolean wasEnabled = instance.tbCentre.isEnabled();
+        instance.tbCentre.setEnabled(value);
+        instance.tbCentre.getAction().actionPerformed(new ActionEvent(instance.tbCentre, 0, null));
+        return wasEnabled;
+    }
+
     private transient GeoImageLayer currentLayer;
     private transient ImageEntry currentEntry;
@@ -304,5 +319,5 @@
             StringBuilder osd = new StringBuilder(entry.getFile() != null ? entry.getFile().getName() : "");
             if (entry.getElevation() != null) {
-                osd.append(tr("\nAltitude: {0} m", entry.getElevation().longValue()));
+                osd.append(tr("\nAltitude: {0} m", Math.round(entry.getElevation())));
             }
             if (entry.getSpeed() != null) {
Index: /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java	(revision 9269)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java	(revision 9270)
@@ -33,7 +33,18 @@
     private final boolean cacheOff = Main.pref.getBoolean("geoimage.noThumbnailCache", false);
 
+    /**
+     * Constructs a new thumbnail loader that operates on a geoimage layer.
+     * @param layer geoimage layer
+     */
     public ThumbsLoader(GeoImageLayer layer) {
         this.layer = layer;
         this.data = new ArrayList<>(layer.data);
+        initCache();
+    }
+
+    /**
+     * Initialize the thumbnail cache.
+     */
+    private void initCache() {
         if (!cacheOff) {
             try {
@@ -55,6 +66,6 @@
 
             // Do not load thumbnails that were loaded before.
-            if (entry.thumbnail == null) {
-                entry.thumbnail = loadThumb(entry);
+            if (!entry.hasThumbnail()) {
+                entry.setThumbnail(loadThumb(entry));
 
                 if (Main.isDisplayingMapView()) {
