diff -rupN JMapViewer/src/org/openstreetmap/gui/jmapviewer/DefaultMapController.java JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/DefaultMapController.java
--- JMapViewer/src/org/openstreetmap/gui/jmapviewer/DefaultMapController.java	2017-05-14 17:28:05.000000000 +0100
+++ JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/DefaultMapController.java	2017-05-14 17:12:14.000000000 +0100
@@ -26,12 +26,12 @@ MouseWheelListener {
 
     private Point lastDragPoint;
 
-    private boolean isMoving;
+    private boolean isMoving = false;
 
     private boolean movementEnabled = true;
 
-    private int movementMouseButton = MouseEvent.BUTTON3;
-    private int movementMouseButtonMask = MouseEvent.BUTTON3_DOWN_MASK;
+    private int movementMouseButton = MouseEvent.BUTTON1;
+    private int movementMouseButtonMask = MouseEvent.BUTTON1_DOWN_MASK;
 
     private boolean wheelZoomEnabled = true;
     private boolean doubleClickZoomEnabled = true;
@@ -49,7 +49,7 @@ MouseWheelListener {
         if (!movementEnabled || !isMoving)
             return;
         // Is only the selected mouse button pressed?
-        if ((e.getModifiersEx() & MOUSE_BUTTONS_MASK) == movementMouseButtonMask
+        if ((e.getModifiersEx() & MOUSE_BUTTONS_MASK) == movementMouseButtonMask 
                 || (isPlatformOsx() && e.getModifiersEx() == MAC_MOUSE_BUTTON3_MASK)) {
             Point p = e.getPoint();
             if (lastDragPoint != null) {
diff -rupN JMapViewer/src/org/openstreetmap/gui/jmapviewer/Demo.java JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/Demo.java
--- JMapViewer/src/org/openstreetmap/gui/jmapviewer/Demo.java	2017-05-14 17:28:05.000000000 +0100
+++ JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/Demo.java	2017-05-14 17:22:05.000000000 +0100
@@ -75,7 +75,7 @@ public class Demo extends JFrame impleme
         add(helpPanel, BorderLayout.SOUTH);
         panel.add(panelTop, BorderLayout.NORTH);
         panel.add(panelBottom, BorderLayout.SOUTH);
-        JLabel helpLabel = new JLabel("Use right mouse button to move,\n "
+        JLabel helpLabel = new JLabel("Use left mouse button to move,\n "
                 + "left double click or mouse wheel to zoom.");
         helpPanel.add(helpLabel);
         JButton button = new JButton("setDisplayToFitMapMarkers");
@@ -88,7 +88,7 @@ public class Demo extends JFrame impleme
         JComboBox<TileSource> tileSourceSelector = new JComboBox<>(new TileSource[] {
                 new OsmTileSource.Mapnik(),
                 new OsmTileSource.CycleMap(),
-                new BingAerialTileSource(),
+                new BingAerialTileSource()
         });
         tileSourceSelector.addItemListener(new ItemListener() {
             @Override
diff -rupN JMapViewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java
--- JMapViewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java	2017-05-14 17:28:05.000000000 +0100
+++ JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java	2017-05-14 17:12:14.000000000 +0100
@@ -44,6 +44,8 @@ import org.openstreetmap.gui.jmapviewer.
  */
 public class JMapViewer extends JPanel implements TileLoaderListener {
 
+    private static final long serialVersionUID = 1L;
+
     /** whether debug mode is enabled or not */
     public static boolean debug;
 
@@ -502,7 +504,7 @@ public class JMapViewer extends JPanel i
             return (int) marker.getRadius();
         else if (p != null) {
             Integer radius = getLatOffset(marker.getLat(), marker.getLon(), marker.getRadius(), false);
-            radius = radius == null ? null : p.y - radius.intValue();
+            radius = radius == null ? null : p.y - radius;
             return radius;
         } else
             return null;
diff -rupN JMapViewer/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java
--- JMapViewer/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java	2017-05-14 17:28:05.000000000 +0100
+++ JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java	2017-05-14 17:12:14.000000000 +0100
@@ -9,8 +9,7 @@ import java.net.URLConnection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.*;
 
 import org.openstreetmap.gui.jmapviewer.interfaces.TileJob;
 import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
@@ -22,7 +21,8 @@ import org.openstreetmap.gui.jmapviewer.
  * @author Jan Peter Stotz
  */
 public class OsmTileLoader implements TileLoader {
-    private static final ThreadPoolExecutor jobDispatcher = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
+    
+    private static final ThreadPoolExecutor jobDispatcher = new ThreadPoolExecutor(8, 24, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(2_000));
 
     private final class OsmTileJob implements TileJob {
         private final Tile tile;
@@ -178,7 +178,9 @@ public class OsmTileLoader implements Ti
 
     @Override
     public void cancelOutstandingTasks() {
-        jobDispatcher.getQueue().clear();
+        for (Runnable item : jobDispatcher.getQueue()) {
+            jobDispatcher.remove(item);
+        }
     }
 
     /**
Binary files JMapViewer/src/org/openstreetmap/gui/jmapviewer/images/bing_maps.png and JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/images/bing_maps.png differ
Binary files JMapViewer/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_gray_large.png and JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_gray_large.png differ
Binary files JMapViewer/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_gray_medium_1.png and JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_gray_medium_1.png differ
Binary files JMapViewer/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_gray_medium_2.png and JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_gray_medium_2.png differ
Binary files JMapViewer/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_gray_small.png and JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_gray_small.png differ
Binary files JMapViewer/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_white_large.png and JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_white_large.png differ
Binary files JMapViewer/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_white_medium_1.png and JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_white_medium_1.png differ
Binary files JMapViewer/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_white_medium_2.png and JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_white_medium_2.png differ
Binary files JMapViewer/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_white_small.png and JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/images/bing_maps_logo_white_small.png differ
diff -rupN JMapViewer/src/org/openstreetmap/gui/jmapviewer/interfaces/TileLoaderListener.java JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/interfaces/TileLoaderListener.java
--- JMapViewer/src/org/openstreetmap/gui/jmapviewer/interfaces/TileLoaderListener.java	2017-05-14 17:28:05.000000000 +0100
+++ JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/interfaces/TileLoaderListener.java	2017-05-14 17:12:14.000000000 +0100
@@ -6,7 +6,7 @@ import org.openstreetmap.gui.jmapviewer.
 /**
  * This listener listens to successful tile loads.
  */
-@FunctionalInterface
+//@FunctionalInterface
 public interface TileLoaderListener {
 
     /**
diff -rupN JMapViewer/src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java
--- JMapViewer/src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java	2017-05-14 17:28:05.000000000 +0100
+++ JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java	2017-05-14 17:12:14.000000000 +0100
@@ -14,7 +14,6 @@ import java.util.concurrent.ExecutionExc
 import java.util.concurrent.Future;
 import java.util.concurrent.FutureTask;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 import java.util.regex.Pattern;
 
 import javax.imageio.ImageIO;
@@ -57,7 +56,7 @@ public class BingAerialTileSource extend
      * Constructs a new {@code BingAerialTileSource}.
      */
     public BingAerialTileSource() {
-        super(new TileSourceInfo("Bing", null, null));
+        super(new TileSourceInfo("Bing Aerial Maps", null, null));
     }
 
     /**
@@ -192,7 +191,7 @@ public class BingAerialTileSource extend
     @Override
     public Image getAttributionImage() {
         try {
-            final InputStream imageResource = JMapViewer.class.getResourceAsStream("images/bing_maps.png");
+            final InputStream imageResource = JMapViewer.class.getResourceAsStream("images/bing_maps_logo_white_small.png");
             if (imageResource != null) {
                 return ImageIO.read(imageResource);
             } else {
@@ -239,7 +238,6 @@ public class BingAerialTileSource extend
                     try {
                         InputSource xml = new InputSource(getAttributionUrl().openStream());
                         List<Attribution> r = parseAttributionText(xml);
-                        System.out.println("Successfully loaded Bing attribution data.");
                         return r;
                     } catch (IOException ex) {
                         System.err.println("Could not connect to Bing API. Will retry in " + waitTimeSec + " seconds.");
@@ -263,9 +261,7 @@ public class BingAerialTileSource extend
             }
         }
         try {
-            return attributions.get(0, TimeUnit.MILLISECONDS);
-        } catch (TimeoutException ex) {
-            System.err.println("Bing: attribution data is not yet loaded.");
+            return attributions.get();
         } catch (ExecutionException ex) {
             throw new RuntimeException(ex.getCause());
         } catch (InterruptedException ign) {
diff -rupN JMapViewer/src/org/openstreetmap/gui/jmapviewer/tilesources/OsmTileSource.java JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/tilesources/OsmTileSource.java
--- JMapViewer/src/org/openstreetmap/gui/jmapviewer/tilesources/OsmTileSource.java	2017-05-14 17:28:05.000000000 +0100
+++ JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/tilesources/OsmTileSource.java	2017-05-14 17:17:37.000000000 +0100
@@ -1,6 +1,9 @@
 // License: GPL. For details, see Readme.txt file.
 package org.openstreetmap.gui.jmapviewer.tilesources;
 
+import java.io.IOException;
+import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
+
 /**
  * OSM Tile source.
  */
@@ -11,7 +14,7 @@ public class OsmTileSource {
      */
     public static class Mapnik extends AbstractOsmTileSource {
 
-        private static final String PATTERN = "https://%s.tile.openstreetmap.org";
+        private static final String PATTERN = "http://%s.tile.openstreetmap.org";
 
         private static final String[] SERVER = {"a", "b", "c"};
 
@@ -37,9 +40,11 @@ public class OsmTileSource {
      */
     public static class CycleMap extends AbstractOsmTileSource {
 
-        private static final String PATTERN = "http://%s.tile.opencyclemap.org/cycle";
+        private static final String API_KEY = "API_KEY";
 
-        private static final String[] SERVER = {"a", "b", "c"};
+        private static final String PATTERN = "http://%s.tile.thunderforest.com/cycle";
+
+        private static final String[] SERVER = { "a", "b", "c" };
 
         private int serverNum;
 
@@ -47,7 +52,7 @@ public class OsmTileSource {
          * Constructs a new {@code CycleMap} tile source.
          */
         public CycleMap() {
-            super("Cyclemap", PATTERN, "opencyclemap");
+            super("OSM Cycle Map", PATTERN, "opencyclemap");
         }
 
         @Override
@@ -61,5 +66,21 @@ public class OsmTileSource {
         public int getMaxZoom() {
             return 18;
         }
+
+        @Override
+        public String getTileUrl(int zoom, int tilex, int tiley) throws IOException {
+            return this.getBaseUrl() + getTilePath(zoom, tilex, tiley); // + "?apikey=" + API_KEY;
+        }
+
+        @Override
+        public String getAttributionText(int zoom, ICoordinate topLeft, ICoordinate botRight) {
+            return "Maps © Thunderforest, Data © OpenStreetMap contributors";
+        }
+
+        @Override
+        public String getAttributionLinkURL() {
+            return "http://www.thunderforest.com/";
+        }
     }
+
 }
diff -rupN JMapViewer/src/org/openstreetmap/gui/jmapviewer/tilesources/ScanexTileSource.java JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/tilesources/ScanexTileSource.java
--- JMapViewer/src/org/openstreetmap/gui/jmapviewer/tilesources/ScanexTileSource.java	2017-05-14 17:28:05.000000000 +0100
+++ JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/tilesources/ScanexTileSource.java	2017-05-14 17:12:14.000000000 +0100
@@ -116,8 +116,8 @@ public class ScanexTileSource extends TM
     @Override
     public Point latLonToXY(double lat, double lon, int zoom) {
         return new Point(
-                (int) osmMercator.lonToX(lon, zoom),
-                (int) latToTileY(lat, zoom)
+                (int) Math.round(osmMercator.lonToX(lon, zoom)),
+                (int) Math.round(latToTileY(lat, zoom))
                 );
     }
 
diff -rupN JMapViewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TMSTileSource.java JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/tilesources/TMSTileSource.java
--- JMapViewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TMSTileSource.java	2017-05-14 17:28:05.000000000 +0100
+++ JMapViewer.patched/src/org/openstreetmap/gui/jmapviewer/tilesources/TMSTileSource.java	2017-05-14 17:12:14.000000000 +0100
@@ -50,33 +50,32 @@ public class TMSTileSource extends Abstr
     @Override
     public Point latLonToXY(double lat, double lon, int zoom) {
         return new Point(
-                (int) osmMercator.lonToX(lon, zoom),
-                (int) osmMercator.latToY(lat, zoom)
-                );
+            (int) Math.round(osmMercator.lonToX(lon, zoom)),
+            (int) Math.round(osmMercator.latToY(lat, zoom)));
     }
 
     @Override
     public ICoordinate xyToLatLon(int x, int y, int zoom) {
         return new Coordinate(
-                osmMercator.yToLat(y, zoom),
-                osmMercator.xToLon(x, zoom)
-                );
+            osmMercator.yToLat(y, zoom),
+            osmMercator.xToLon(x, zoom)
+        );
     }
 
     @Override
     public TileXY latLonToTileXY(double lat, double lon, int zoom) {
         return new TileXY(
-                osmMercator.lonToX(lon, zoom) / getTileSize(),
-                osmMercator.latToY(lat, zoom) / getTileSize()
-                );
+            osmMercator.lonToX(lon, zoom) / getTileSize(),
+            osmMercator.latToY(lat, zoom) / getTileSize()
+        );
     }
 
     @Override
     public ICoordinate tileXYToLatLon(int x, int y, int zoom) {
         return new Coordinate(
-                osmMercator.yToLat(y * getTileSize(), zoom),
-                osmMercator.xToLon(x * getTileSize(), zoom)
-                );
+            osmMercator.yToLat(y * getTileSize(), zoom),
+            osmMercator.xToLon(x * getTileSize(), zoom)
+        );
     }
 
     @Override
