Index: /trunk/src/org/openstreetmap/josm/gui/bbox/SizeButton.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/bbox/SizeButton.java	(revision 6538)
+++ /trunk/src/org/openstreetmap/josm/gui/bbox/SizeButton.java	(revision 6539)
@@ -2,8 +2,12 @@
 package org.openstreetmap.josm.gui.bbox;
 
+import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Point;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
 
 import javax.swing.ImageIcon;
+import javax.swing.JComponent;
 
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -12,5 +16,5 @@
  * @author Tim Haussmann
  */
-public class SizeButton{
+public class SizeButton extends JComponent {
 
     private int x = 0;
@@ -20,11 +24,28 @@
     private ImageIcon shrinkImage;
     private boolean isEnlarged = false;
+    private final SlippyMapBBoxChooser slippyMapBBoxChooser;
 
-    public SizeButton(){
+    public SizeButton(SlippyMapBBoxChooser slippyMapBBoxChooser){
+        super();
+        this.slippyMapBBoxChooser = slippyMapBBoxChooser;
         enlargeImage = ImageProvider.get("view-fullscreen.png");
         shrinkImage = ImageProvider.get("view-fullscreen-revert.png");
+        setPreferredSize(new Dimension(enlargeImage.getIconWidth(), enlargeImage.getIconHeight()));
+        addMouseListener(mouseListener);
     }
 
-    public void paint(Graphics g) {
+    private final MouseAdapter mouseListener = new MouseAdapter() {
+        @Override
+        public void mouseReleased(MouseEvent e) {
+            if (e.getButton() == MouseEvent.BUTTON1) {
+                toggle();
+                slippyMapBBoxChooser.resizeSlippyMap();
+            }
+        }
+    };
+
+
+    @Override
+    protected void paintComponent(Graphics g) {
         if(isEnlarged) {
             if(shrinkImage != null)
Index: /trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java	(revision 6538)
+++ /trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java	(revision 6539)
@@ -7,5 +7,4 @@
 import java.awt.Dimension;
 import java.awt.Graphics;
-import java.awt.Graphics2D;
 import java.awt.Image;
 import java.awt.Point;
@@ -21,4 +20,5 @@
 
 import javax.swing.JOptionPane;
+import javax.swing.SpringLayout;
 
 import org.openstreetmap.gui.jmapviewer.Coordinate;
@@ -170,5 +170,5 @@
     private OsmTileLoader uncachedLoader;
 
-    private final SizeButton iSizeButton = new SizeButton();
+    private final SizeButton iSizeButton;
     private final SourceButton iSourceButton;
     private Bounds bbox;
@@ -182,4 +182,6 @@
      */
     public SlippyMapBBoxChooser() {
+        SpringLayout springLayout = new SpringLayout();
+        setLayout(springLayout);
         TMSLayer.setMaxWorkers();
         cachedLoader = TMSLayer.loaderFactory.makeTileLoader(this);
@@ -202,5 +204,11 @@
         List<TileSource> tileSources = getAllTileSources();
 
-        iSourceButton = new SourceButton(tileSources);
+        iSourceButton = new SourceButton(this, tileSources);
+        add(iSourceButton);
+        springLayout.putConstraint(SpringLayout.EAST, iSourceButton, 0, SpringLayout.EAST, this);
+        springLayout.putConstraint(SpringLayout.NORTH, iSourceButton, 30, SpringLayout.NORTH, this);
+
+        iSizeButton = new SizeButton(this);
+        add(iSizeButton);
 
         String mapStyle = PROP_MAPSTYLE.get();
@@ -219,7 +227,7 @@
         }
 
-        new SlippyMapControler(this, this, iSizeButton, iSourceButton);
-    }
-    
+        new SlippyMapControler(this, this);
+    }
+
     private List<TileSource> getAllTileSources() {
         List<TileSource> tileSources = new ArrayList<TileSource>();
@@ -264,7 +272,4 @@
                 g.drawRect(x_min, y_min, w, h);
             }
-
-            iSizeButton.paint(g);
-            iSourceButton.paint((Graphics2D)g);
         } catch (Exception e) {
             e.printStackTrace();
@@ -394,5 +399,5 @@
         repaint();
     }
-    
+
     /**
      * Refreshes the tile sources
Index: /trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapControler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapControler.java	(revision 6538)
+++ /trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapControler.java	(revision 6539)
@@ -51,7 +51,4 @@
     private final SlippyMapBBoxChooser iSlippyMapChooser;
 
-    private SizeButton iSizeButton = null;
-    private SourceButton iSourceButton = null;
-
     private boolean isSelecting;
 
@@ -59,5 +56,5 @@
      * Constructs a new {@code SlippyMapControler}.
      */
-    public SlippyMapControler(SlippyMapBBoxChooser navComp, JPanel contentPane, SizeButton sizeButton, SourceButton sourceButton) {
+    public SlippyMapControler(SlippyMapBBoxChooser navComp, JPanel contentPane) {
         iSlippyMapChooser = navComp;
         iSlippyMapChooser.addMouseListener(this);
@@ -74,7 +71,4 @@
             }
         }
-        iSizeButton = sizeButton;
-        iSourceButton = sourceButton;
-
         isSelecting = false;
 
@@ -124,10 +118,7 @@
     public void mousePressed(MouseEvent e) {
         if (e.getButton() == MouseEvent.BUTTON1) {
-            if (!iSizeButton.hit(e.getPoint())) {
-                iStartSelectionPoint = e.getPoint();
-                iEndSelectionPoint = e.getPoint();
-            }
-        }
-
+            iStartSelectionPoint = e.getPoint();
+            iEndSelectionPoint = e.getPoint();
+        }
     }
 
@@ -160,17 +151,5 @@
 
             } else {
-                int sourceButton = iSourceButton.hit(e.getPoint());
-
-                if (iSizeButton.hit(e.getPoint())) {
-                    iSizeButton.toggle();
-                    iSlippyMapChooser.resizeSlippyMap();
-                } else if (iSlippyMapChooser.handleAttribution(e.getPoint(), true)) {
-                    /* do nothing, handleAttribution() already did the work */
-                } else if (sourceButton == SourceButton.HIDE_OR_SHOW) {
-                    iSourceButton.toggle();
-                    iSlippyMapChooser.repaint();
-                } else if (sourceButton != 0) {
-                    iSlippyMapChooser.toggleMapSource(iSourceButton.hitToTileSource(sourceButton));
-                }
+                iSlippyMapChooser.handleAttribution(e.getPoint(), true);
             }
         }
Index: /trunk/src/org/openstreetmap/josm/gui/bbox/SourceButton.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/bbox/SourceButton.java	(revision 6538)
+++ /trunk/src/org/openstreetmap/josm/gui/bbox/SourceButton.java	(revision 6539)
@@ -3,12 +3,18 @@
 
 import java.awt.Color;
+import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.FontMetrics;
+import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.RenderingHints;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
 import java.util.Collection;
 
 import javax.swing.ImageIcon;
+import javax.swing.JComponent;
 
 import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
@@ -16,30 +22,65 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 
-public class SourceButton {
+public class SourceButton extends JComponent {
 
-    // Filled in paint, used in hit
-    private int barX;
-    private int barY;
-    private int barWidth;
-    private int layerHeight;
+    private final int layerHeight = 20;
+    private final int leftPadding = 5;
+    private final int topPadding = 5;
+    private final int bottomPadding = 5;
+
 
     private TileSource[] sources;
 
-    private ImageIcon enlargeImage;
-    private ImageIcon shrinkImage;
+    private final ImageIcon enlargeImage;
+    private final ImageIcon shrinkImage;
+    private final Dimension hiddenDimension;
+
+    // Calculated after component is added to container
+    private int barWidth;
+    private Dimension shownDimension;
+    private Font font;
 
     private boolean isEnlarged = false;
 
     private int currentMap;
+    private final SlippyMapBBoxChooser slippyMapBBoxChooser;
 
-    public static final int HIDE_OR_SHOW = 1;
-
-    public SourceButton(Collection<TileSource> sources) {
+    public SourceButton(SlippyMapBBoxChooser slippyMapBBoxChooser, Collection<TileSource> sources) {
+        super();
+        this.slippyMapBBoxChooser = slippyMapBBoxChooser;
         setSources(sources);
-        this.currentMap = 2;
         enlargeImage = ImageProvider.get("layer-switcher-maximize.png");
         shrinkImage = ImageProvider.get("layer-switcher-minimize.png");
+
+        hiddenDimension= new Dimension(enlargeImage.getIconWidth(), enlargeImage.getIconHeight());
+        setPreferredSize(hiddenDimension);
+
+        addMouseListener(mouseListener);
     }
-    
+
+    private final MouseListener mouseListener = new MouseAdapter() {
+        @Override
+        public void mouseReleased(MouseEvent e) {
+            if (e.getButton() == MouseEvent.BUTTON1) {
+                Point point = e.getPoint();
+                if (isEnlarged) {
+                    if (barWidth < point.x && point.y < shrinkImage.getIconHeight()) {
+                        toggle();
+                    } else {
+                        int result = (point.y - 5) / layerHeight;
+                        if (result >= 0 && result < SourceButton.this.sources.length) {
+                            SourceButton.this.slippyMapBBoxChooser.toggleMapSource(SourceButton.this.sources[result]);
+                            currentMap = result;
+                            toggle();
+                        }
+                    }
+                } else {
+                    toggle();
+                }
+
+            }
+        }
+    };
+
     /**
      * Set the tile sources.
@@ -50,18 +91,61 @@
         CheckParameterUtil.ensureParameterNotNull(sources, "sources");
         this.sources = sources.toArray(new TileSource[sources.size()]);
+        shownDimension = null;
     }
 
-    public void paint(Graphics2D g) {
-        if (isEnlarged) {
-            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-            int leftPadding = 5;
-            int radioButtonSize = 10;
-            int topPadding = 5;
-            int bottomPadding = 5;
+    @Override
+    protected void paintComponent(Graphics graphics) {
+        Graphics2D g = (Graphics2D) graphics.create();
+        try {
+            calculateShownDimension();
+            g.setFont(font);
+            if (isEnlarged) {
+                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+                int radioButtonSize = 10;
 
+                g.setColor(new Color(0, 0, 139, 179));
+                g.fillRoundRect(0, 0, barWidth + shrinkImage.getIconWidth(), sources.length * layerHeight + topPadding + bottomPadding, 10, 10);
+                for (int i=0; i<sources.length; i++) {
+                    g.setColor(Color.WHITE);
+                    g.fillOval(leftPadding, topPadding + i * layerHeight + 6, radioButtonSize, radioButtonSize);
+                    g.drawString(sources[i].getName(), leftPadding + radioButtonSize + leftPadding, topPadding + i * layerHeight + g.getFontMetrics().getHeight());
+                    if (currentMap == i) {
+                        g.setColor(Color.BLACK);
+                        g.fillOval(leftPadding + 1, topPadding + 7 + i * layerHeight, radioButtonSize - 2, radioButtonSize - 2);
+                    }
+                }
+
+                g.drawImage(shrinkImage.getImage(), barWidth, 0, null);
+            } else {
+                g.drawImage(enlargeImage.getImage(), 0, 0, null);
+            }
+        } finally {
+            g.dispose();
+        }
+    }
+
+    public void toggle() {
+        this.isEnlarged = !this.isEnlarged;
+        calculateShownDimension();
+        setPreferredSize(isEnlarged?shownDimension:hiddenDimension);
+        revalidate();
+    }
+
+
+    public void setCurrentMap(TileSource tileSource) {
+        for (int i=0; i<sources.length; i++) {
+            if (sources[i].equals(tileSource)) {
+                currentMap = i;
+                return;
+            }
+        }
+        currentMap = 0;
+    }
+
+    private void calculateShownDimension() {
+        if (shownDimension == null) {
+            font = getFont().deriveFont(Font.BOLD).deriveFont(15.0f);
             int textWidth = 0;
-
-            g.setFont(g.getFont().deriveFont(Font.BOLD).deriveFont(15.0f));
-            FontMetrics fm = g.getFontMetrics();
+            FontMetrics fm = getFontMetrics(font);
             for (TileSource source: sources) {
                 int width = fm.stringWidth(source.getName());
@@ -70,73 +154,7 @@
                 }
             }
-
             barWidth = textWidth + 50;
-            barX = g.getClipBounds().width  - barWidth - shrinkImage.getIconWidth();
-            barY = 30;
-            layerHeight = 20;
-
-            g.setColor(new Color(0, 0, 139, 179));
-            g.fillRoundRect(barX, barY, barWidth + shrinkImage.getIconWidth(), sources.length * layerHeight + topPadding + bottomPadding, 10, 10);
-            for (int i=0; i<sources.length; i++) {
-                g.setColor(Color.WHITE);
-                g.fillOval(barX + leftPadding, barY + topPadding + i * layerHeight + 6, radioButtonSize, radioButtonSize);
-                g.drawString(sources[i].getName(), barX + leftPadding + radioButtonSize + leftPadding, barY + topPadding + i * layerHeight + g.getFontMetrics().getHeight());
-                if (currentMap == i + 2) {
-                    g.setColor(Color.BLACK);
-                    g.fillOval(barX + leftPadding + 1, barY + topPadding + 7 + i * layerHeight, radioButtonSize - 2, radioButtonSize - 2);
-                }
-            }
-
-            g.drawImage(shrinkImage.getImage(), barX + barWidth, barY, null);
-        } else {
-            barWidth = 0;
-            barX = g.getClipBounds().width  - shrinkImage.getIconWidth();
-            barY = 30;
-            g.drawImage(enlargeImage.getImage(), barX + barWidth, barY, null);
+            shownDimension = new Dimension(barWidth + shrinkImage.getIconWidth(), sources.length * layerHeight + topPadding + bottomPadding);
         }
     }
-
-    public void toggle() {
-        this.isEnlarged = !this.isEnlarged;
-
-    }
-
-    public int hit(Point point) {
-        if (isEnlarged) {
-            if (barX + barWidth < point.x) {
-                if (barY < point.y && point.y < barY + shrinkImage.getIconHeight())
-                    return HIDE_OR_SHOW;
-            } else if (barX < point.x && point.x < barX + barWidth) {
-                int result = (point.y - barY - 5) / layerHeight;
-                if (result >= 0 && result < sources.length) {
-                    currentMap = result + 2;
-                    return currentMap;
-                }
-            }
-        } else {
-            if (barX + barWidth < point.x) {
-                if (barY < point.y && point.y < barY + shrinkImage.getIconHeight())
-                    return HIDE_OR_SHOW;
-            }
-        }
-
-        return 0;
-    }
-
-    public TileSource hitToTileSource(int hit) {
-        if (hit >= 2 && hit < sources.length + 2)
-            return sources[hit - 2];
-        else
-            return null;
-    }
-
-    public void setCurrentMap(TileSource tileSource) {
-        for (int i=0; i<sources.length; i++) {
-            if (sources[i].equals(tileSource)) {
-                currentMap = i + 2;
-                return;
-            }
-        }
-        currentMap = 2;
-    }
 }
