Index: /trunk/src/org/openstreetmap/josm/gui/preferences/ExtensibleTabPreferenceSetting.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/ExtensibleTabPreferenceSetting.java	(revision 17314)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/ExtensibleTabPreferenceSetting.java	(revision 17314)
@@ -0,0 +1,36 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.preferences;
+
+import static java.awt.GridBagConstraints.BOTH;
+
+import org.openstreetmap.josm.gui.widgets.HideableTabbedPane;
+import org.openstreetmap.josm.tools.GBC;
+
+/**
+ * Abstract base class for {@link TabPreferenceSetting} implementations extensible solely by inner tabs.
+ *
+ * Support for common functionality, like icon, title and adding a tab ({@link SubPreferenceSetting}).
+ * @since 17314
+ */
+public abstract class ExtensibleTabPreferenceSetting extends DefaultTabPreferenceSetting {
+
+    /**
+     * Constructs a new {@code ExtensibleTabPreferenceSetting}.
+     */
+    protected ExtensibleTabPreferenceSetting() {
+        this(null, null, null);
+    }
+
+    protected ExtensibleTabPreferenceSetting(String iconName, String title, String description) {
+        this(iconName, title, description, false);
+    }
+
+    protected ExtensibleTabPreferenceSetting(String iconName, String title, String description, boolean isExpert) {
+        super(iconName, title, description, isExpert, new HideableTabbedPane());
+    }
+
+    @Override
+    public void addGui(PreferenceTabbedPane gui) {
+        gui.createPreferenceTab(this).add(getTabPane(), GBC.eol().fill(BOTH));
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/display/ColorPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/display/ColorPreference.java	(revision 17313)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/display/ColorPreference.java	(revision 17314)
@@ -2,4 +2,6 @@
 package org.openstreetmap.josm.gui.preferences.display;
 
+import static java.awt.GridBagConstraints.BOTH;
+import static java.awt.GridBagConstraints.HORIZONTAL;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
@@ -48,5 +50,5 @@
 import org.openstreetmap.josm.gui.layer.gpx.GpxDrawHelper;
 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
-import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.ExtensibleTabPreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
@@ -59,6 +61,6 @@
 import org.openstreetmap.josm.tools.ColorHelper;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.I18n;
 import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.tools.I18n;
 
 /**
@@ -68,5 +70,5 @@
  * @see NamedColorProperty
  */
-public class ColorPreference extends DefaultTabPreferenceSetting implements ListSelectionListener, TableModelListener {
+public class ColorPreference extends ExtensibleTabPreferenceSetting implements ListSelectionListener, TableModelListener {
 
     /**
@@ -370,11 +372,11 @@
         JPanel panel = new JPanel(new GridBagLayout());
         panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-        panel.add(colorFilter, GBC.eol().fill(GBC.HORIZONTAL));
+        panel.add(colorFilter, GBC.eol().fill(HORIZONTAL));
         JScrollPane scrollpane = new JScrollPane(colors);
         scrollpane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
-        panel.add(scrollpane, GBC.eol().fill(GBC.BOTH));
+        panel.add(scrollpane, GBC.eol().fill(BOTH));
         JPanel buttonPanel = new JPanel(new GridBagLayout());
-        panel.add(buttonPanel, GBC.eol().insets(5, 0, 5, 5).fill(GBC.HORIZONTAL));
-        buttonPanel.add(Box.createHorizontalGlue(), GBC.std().fill(GBC.HORIZONTAL));
+        panel.add(buttonPanel, GBC.eol().insets(5, 0, 5, 5).fill(HORIZONTAL));
+        buttonPanel.add(Box.createHorizontalGlue(), GBC.std().fill(HORIZONTAL));
         buttonPanel.add(colorEdit, GBC.std().insets(0, 5, 0, 0));
         buttonPanel.add(defaultSet, GBC.std().insets(5, 5, 5, 0));
@@ -382,5 +384,6 @@
         buttonPanel.add(remove, GBC.std().insets(0, 5, 0, 0));
 
-        createPreferenceTabWithScrollPane(gui, panel);
+        getTabPane().addTab(tr("Colors"), panel);
+        super.addGui(gui);
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/display/DisplayPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/display/DisplayPreference.java	(revision 17313)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/display/DisplayPreference.java	(revision 17314)
@@ -5,12 +5,8 @@
 import static org.openstreetmap.josm.tools.I18n.trc;
 
-import javax.swing.JTabbedPane;
-
 import org.openstreetmap.josm.gui.help.HelpUtil;
-import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.ExtensibleTabPreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
-import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
-import org.openstreetmap.josm.tools.GBC;
 
 /**
@@ -18,5 +14,5 @@
  * @since 4969
  */
-public final class DisplayPreference extends DefaultTabPreferenceSetting {
+public final class DisplayPreference extends ExtensibleTabPreferenceSetting {
 
     /**
@@ -32,5 +28,5 @@
     private DisplayPreference() {
         super(/* ICON(preferences/) */ "display", trc("gui", "Display"),
-                tr("Various settings that influence the visual representation of the whole program."), false, new JTabbedPane());
+                tr("Various settings that influence the visual representation of the whole program."), false);
     }
 
@@ -38,9 +34,4 @@
     public boolean ok() {
         return false;
-    }
-
-    @Override
-    public void addGui(PreferenceTabbedPane gui) {
-        gui.createPreferenceTab(this).add(getTabPane(), GBC.eol().fill(GBC.BOTH));
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreference.java	(revision 17313)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreference.java	(revision 17314)
@@ -2,4 +2,6 @@
 package org.openstreetmap.josm.gui.preferences.imagery;
 
+import static java.awt.GridBagConstraints.BOTH;
+import static java.awt.GridBagConstraints.HORIZONTAL;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
@@ -9,5 +11,4 @@
 import java.awt.Font;
 import java.awt.GraphicsEnvironment;
-import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.event.MouseEvent;
@@ -36,5 +37,5 @@
 import org.openstreetmap.josm.gui.download.DownloadDialog;
 import org.openstreetmap.josm.gui.help.HelpUtil;
-import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.ExtensibleTabPreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
@@ -50,5 +51,5 @@
  * @since 3715
  */
-public final class ImageryPreference extends DefaultTabPreferenceSetting {
+public final class ImageryPreference extends ExtensibleTabPreferenceSetting {
 
     private ImageryProvidersPanel imageryProviders;
@@ -72,6 +73,5 @@
     private ImageryPreference() {
         super(/* ICON(preferences/) */ "imagery", tr("Imagery"),
-                tr("Modify list of imagery layers displayed in the Imagery menu"),
-                false, new JTabbedPane());
+                tr("Modify list of imagery layers displayed in the Imagery menu"), false);
     }
 
@@ -85,5 +85,5 @@
         lbl.setLabelFor(section);
         p.add(lbl, GBC.std());
-        p.add(new JSeparator(), GBC.eol().fill(GBC.HORIZONTAL).insets(5, 0, 0, 0));
+        p.add(new JSeparator(), GBC.eol().fill(HORIZONTAL).insets(5, 0, 0, 0));
         p.add(section, gbc.insets(20, 5, 0, 10));
     }
@@ -94,16 +94,13 @@
 
         addSettingsSection(p, tr("Common Settings"), commonSettings);
-        addSettingsSection(p, tr("WMS Settings"), wmsSettings,
-                GBC.eol().fill(GBC.HORIZONTAL));
-        addSettingsSection(p, tr("TMS Settings"), tmsSettings,
-                GBC.eol().fill(GBC.HORIZONTAL));
-
-        p.add(new JPanel(), GBC.eol().fill(GBC.BOTH));
+        addSettingsSection(p, tr("WMS Settings"), wmsSettings, GBC.eol().fill(HORIZONTAL));
+        addSettingsSection(p, tr("TMS Settings"), tmsSettings, GBC.eol().fill(HORIZONTAL));
+
+        p.add(new JPanel(), GBC.eol().fill(BOTH));
         return GuiHelper.setDefaultIncrement(new JScrollPane(p));
     }
 
     @Override
-    public void addGui(final PreferenceTabbedPane gui) {
-        JPanel p = gui.createPreferenceTab(this);
+    public void addGui(PreferenceTabbedPane gui) {
         JTabbedPane pane = getTabPane();
         layerInfo = new ImageryLayerInfo(ImageryLayerInfo.instance);
@@ -114,5 +111,5 @@
         pane.addTab(tr("Cache"), cacheSettingsPanel);
         loadSettings();
-        p.add(pane, GBC.std().fill(GBC.BOTH));
+        super.addGui(gui);
     }
 
@@ -202,5 +199,5 @@
             TableHelper.setFont(list, getClass());
             JScrollPane scroll = new JScrollPane(list);
-            add(scroll, GBC.eol().fill(GridBagConstraints.BOTH));
+            add(scroll, GBC.eol().fill(BOTH));
             scroll.setPreferredSize(new Dimension(200, 200));
 
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/map/MapPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/map/MapPreference.java	(revision 17313)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/map/MapPreference.java	(revision 17314)
@@ -4,17 +4,13 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import javax.swing.JTabbedPane;
-
 import org.openstreetmap.josm.gui.help.HelpUtil;
-import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.ExtensibleTabPreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
-import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
-import org.openstreetmap.josm.tools.GBC;
 
 /**
  * Map preferences, including map paint styles, tagging presets and autosave sub-preferences.
  */
-public final class MapPreference extends DefaultTabPreferenceSetting {
+public final class MapPreference extends ExtensibleTabPreferenceSetting {
 
     /**
@@ -30,5 +26,5 @@
     private MapPreference() {
         super(/* ICON(preferences/) */ "map", tr("Map"),
-                tr("Settings for the map projection and data interpretation."), false, new JTabbedPane());
+                tr("Settings for the map projection and data interpretation."), false);
     }
 
@@ -36,9 +32,4 @@
     public boolean ok() {
         return false;
-    }
-
-    @Override
-    public void addGui(PreferenceTabbedPane gui) {
-        gui.createPreferenceTab(this).add(getTabPane(), GBC.eol().fill(GBC.BOTH));
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreference.java	(revision 17313)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreference.java	(revision 17314)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.gui.preferences.plugin;
 
+import static java.awt.GridBagConstraints.HORIZONTAL;
 import static org.openstreetmap.josm.tools.I18n.tr;
 import static org.openstreetmap.josm.tools.I18n.trc;
@@ -50,9 +51,8 @@
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.help.HelpUtil;
-import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.ExtensibleTabPreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
 import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
-import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane.PreferencePanel;
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.widgets.FilterField;
@@ -71,5 +71,5 @@
  * @since 168
  */
-public final class PluginPreference extends DefaultTabPreferenceSetting {
+public final class PluginPreference extends ExtensibleTabPreferenceSetting {
 
     /**
@@ -94,5 +94,5 @@
 
     private PluginPreference() {
-        super(/* ICON(preferences/) */ "plugin", tr("Plugins"), tr("Configure available plugins."), false, new JTabbedPane());
+        super(/* ICON(preferences/) */ "plugin", tr("Plugins"), tr("Configure available plugins."), false);
     }
 
@@ -247,21 +247,11 @@
     }
 
-    private JTabbedPane buildContentPane() {
+    @Override
+    public void addGui(final PreferenceTabbedPane gui) {
         JTabbedPane pane = getTabPane();
         pnlPluginUpdatePolicy = new PluginUpdatePolicyPanel();
         pane.addTab(tr("Plugins"), buildPluginListPanel());
         pane.addTab(tr("Plugin update policy"), pnlPluginUpdatePolicy);
-        return pane;
-    }
-
-    @Override
-    public void addGui(final PreferenceTabbedPane gui) {
-        GridBagConstraints gc = new GridBagConstraints();
-        gc.weightx = 1.0;
-        gc.weighty = 1.0;
-        gc.anchor = GridBagConstraints.NORTHWEST;
-        gc.fill = GridBagConstraints.BOTH;
-        PreferencePanel plugins = gui.createPreferenceTab(this);
-        plugins.add(buildContentPane(), gc);
+        super.addGui(gui);
         readLocalPluginInformation();
         pluginPreferencesActivated = true;
@@ -585,5 +575,5 @@
                     }
                 }
-            }), GBC.eol().fill(GBC.HORIZONTAL));
+            }), GBC.eol().fill(HORIZONTAL));
             buttons.add(new JButton(new AbstractAction(tr("Edit")) {
                 @Override
@@ -611,5 +601,5 @@
                     }
                 }
-            }), GBC.eol().fill(GBC.HORIZONTAL));
+            }), GBC.eol().fill(HORIZONTAL));
             buttons.add(new JButton(new AbstractAction(tr("Delete")) {
                 @Override
@@ -626,5 +616,5 @@
                     model.removeElement(list.getSelectedValue());
                 }
-            }), GBC.eol().fill(GBC.HORIZONTAL));
+            }), GBC.eol().fill(HORIZONTAL));
             add(buttons, GBC.eol());
         }
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/validator/ValidatorPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/validator/ValidatorPreference.java	(revision 17313)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/validator/ValidatorPreference.java	(revision 17314)
@@ -4,12 +4,8 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import javax.swing.JTabbedPane;
-
 import org.openstreetmap.josm.gui.help.HelpUtil;
-import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.ExtensibleTabPreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
-import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
-import org.openstreetmap.josm.tools.GBC;
 
 /**
@@ -18,5 +14,5 @@
  * @author frsantos
  */
-public final class ValidatorPreference extends DefaultTabPreferenceSetting {
+public final class ValidatorPreference extends ExtensibleTabPreferenceSetting {
 
     /**
@@ -32,11 +28,5 @@
     private ValidatorPreference() {
         super(/* ICON(preferences/) */ "validator", tr("Data validator"),
-                tr("An OSM data validator that checks for common errors made by users and editor programs."),
-                false, new JTabbedPane());
-    }
-
-    @Override
-    public void addGui(PreferenceTabbedPane gui) {
-        gui.createPreferenceTab(this).add(getTabPane(), GBC.eol().fill(GBC.BOTH));
+                tr("An OSM data validator that checks for common errors made by users and editor programs."), false);
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/widgets/HideableTabbedPane.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/widgets/HideableTabbedPane.java	(revision 17314)
+++ /trunk/src/org/openstreetmap/josm/gui/widgets/HideableTabbedPane.java	(revision 17314)
@@ -0,0 +1,80 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.widgets;
+
+import java.awt.Graphics;
+
+import javax.swing.JTabbedPane;
+import javax.swing.plaf.basic.BasicTabbedPaneUI;
+
+/**
+ * A {@link JTabbedPane} extension that completely hides the tab area and border if it contains less than 2 tabs.
+ * @since 17314
+ */
+public class HideableTabbedPane extends JTabbedPane {
+
+    /**
+     * Creates an empty <code>HideableTabbedPane</code> with a default tab placement of <code>JTabbedPane.TOP</code>.
+     * @see #addTab
+     */
+    public HideableTabbedPane() {
+        initUI();
+    }
+
+    /**
+     * Creates an empty <code>HideableTabbedPane</code> with the specified tab placement of either:
+     * <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>, <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>.
+     *
+     * @param tabPlacement the placement for the tabs relative to the content
+     * @see #addTab
+     */
+    public HideableTabbedPane(int tabPlacement) {
+        super(tabPlacement);
+        initUI();
+    }
+
+    /**
+     * Creates an empty <code>TabbedPane</code> with the specified tab placement and tab layout policy. Tab placement may be either:
+     * <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>, <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>.
+     * Tab layout policy may be either: <code>JTabbedPane.WRAP_TAB_LAYOUT</code> or <code>JTabbedPane.SCROLL_TAB_LAYOUT</code>.
+     *
+     * @param tabPlacement the placement for the tabs relative to the content
+     * @param tabLayoutPolicy the policy for laying out tabs when all tabs will not fit on one run
+     * @exception IllegalArgumentException if tab placement or tab layout policy are not one of the above supported values
+     * @see #addTab
+     */
+    public HideableTabbedPane(int tabPlacement, int tabLayoutPolicy) {
+        super(tabPlacement, tabLayoutPolicy);
+        initUI();
+    }
+
+    private void initUI() {
+        // See https://stackoverflow.com/a/8897685/2257172
+        setUI(new BasicTabbedPaneUI() {
+            @Override
+            protected int calculateTabAreaHeight(int tabPlacement, int runCount, int maxTabHeight) {
+                return getTabCount() > 1 ? super.calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight) : 0;
+            }
+
+            @Override
+            protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
+                if (getTabCount() > 1) {
+                    super.paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
+                }
+            }
+
+            @Override
+            protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
+                if (getTabCount() > 1) {
+                    super.paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
+                }
+            }
+
+            @Override
+            protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
+                if (getTabCount() > 1) {
+                    super.paintContentBorder(g, tabPlacement, selectedIndex);
+                }
+            }
+        });
+    }
+}
