Index: src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 9599)
+++ src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(working copy)
@@ -24,6 +24,7 @@
 
 import javax.swing.AbstractAction;
 import javax.swing.AbstractListModel;
+import javax.swing.Action;
 import javax.swing.DefaultListSelectionModel;
 import javax.swing.JComponent;
 import javax.swing.JList;
@@ -48,6 +49,7 @@
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveComparator;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
@@ -155,6 +157,13 @@
         );
 
         buildContentPanel();
+        setTitleActions(new Action[] {
+                null,
+                new SelectAction(SelectAction.RELATIONS),
+                new SelectAction(SelectAction.WAYS),
+                new SelectAction(SelectAction.NODES),
+        });
+
         model.addListDataListener(new TitleUpdater());
         model.addListDataListener(actZoomToJOSMSelection);
 
@@ -168,7 +177,6 @@
                 popupMenuHandler.setPrimitives(model.getSelected());
             }
         });
-
         lstPrimitives.addMouseListener(new MouseEventHandler());
 
         InputMapUtils.addEnterAction(lstPrimitives, actZoomToListSelection);
@@ -273,7 +281,15 @@
      */
     class TitleUpdater implements ListDataListener {
         protected void updateTitle() {
-            setTitle(model.getJOSMSelectionSummary());
+            String[] s = model.getJOSMSelectionSummary().split("/");
+            String[] t = s[0].split(" ", 2);
+            setTitle(t[0]);
+            if (t.length > 1) {
+                s[0] = " " + t[1];
+                s[1] = "/" + s[1];
+                s[2] = "/" + s[2];
+                setTitleSuffixes(s);
+            }
         }
 
         @Override
@@ -327,21 +343,50 @@
      * of this dialog
      */
     class SelectAction extends AbstractSelectAction implements ListSelectionListener {
+        static final String NODES = "Select {0} nodes";
+        static final String WAYS = "Select {0} ways";
+        static final String RELATIONS = "Select {0} relations";
+
         /**
          * Constructs a new {@code SelectAction}.
          */
         SelectAction() {
+            this("");
+        }
+
+        SelectAction(String cmd) {
+            this.putValue(ACTION_COMMAND_KEY, cmd);
             updateEnabledState();
         }
 
         @Override
         public void actionPerformed(ActionEvent e) {
-            Collection<OsmPrimitive> sel = model.getSelected();
-            if (sel.isEmpty()) return;
             OsmDataLayer editLayer = Main.main.getEditLayer();
             if (editLayer == null) return;
-            editLayer.data.setSelected(sel);
-            model.selectionModel.setSelectionInterval(0, sel.size()-1);
+
+            Collection<? extends PrimitiveId> sel;
+            boolean clearsel = true;
+
+            switch ((String) this.getValue(ACTION_COMMAND_KEY)) {
+            case NODES:
+                sel = editLayer.data.getSelectedNodes();
+                break;
+            case WAYS:
+                sel = editLayer.data.getSelectedWays();
+                break;
+            case RELATIONS:
+                sel = editLayer.data.getSelectedRelations();
+                break;
+            default:
+                sel = model.getSelected();
+                clearsel = !clearsel;
+                break;
+            }
+
+            if (!sel.isEmpty()) {
+                editLayer.data.setSelected(sel);
+                model.selectionModel.setSelectionInterval(0, clearsel ? 0 : sel.size()-1);
+            }
         }
 
         protected void updateEnabledState() {
Index: src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 9599)
+++ src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(working copy)
@@ -9,8 +9,6 @@
 import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.FlowLayout;
-import java.awt.Graphics;
-import java.awt.GridBagLayout;
 import java.awt.GridLayout;
 import java.awt.Rectangle;
 import java.awt.Toolkit;
@@ -26,24 +24,32 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import javax.swing.AbstractAction;
+import javax.swing.Action;
 import javax.swing.BorderFactory;
 import javax.swing.ButtonGroup;
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.ParallelGroup;
+import javax.swing.GroupLayout.SequentialGroup;
 import javax.swing.JButton;
 import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JComponent;
 import javax.swing.JDialog;
 import javax.swing.JLabel;
 import javax.swing.JMenu;
+import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JPopupMenu;
 import javax.swing.JRadioButtonMenuItem;
 import javax.swing.JScrollPane;
 import javax.swing.JToggleButton;
+import javax.swing.LayoutStyle;
 import javax.swing.SwingUtilities;
 
 import org.openstreetmap.josm.Main;
@@ -55,7 +61,6 @@
 import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.ShowHideButtonListener;
 import org.openstreetmap.josm.gui.SideButton;
-import org.openstreetmap.josm.gui.dialogs.DialogsPanel.Action;
 import org.openstreetmap.josm.gui.help.HelpUtil;
 import org.openstreetmap.josm.gui.help.Helpful;
 import org.openstreetmap.josm.gui.preferences.PreferenceDialog;
@@ -64,7 +69,6 @@
 import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
 import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
 import org.openstreetmap.josm.tools.Destroyable;
-import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.WindowGeometry;
@@ -152,7 +156,7 @@
 
     protected JToggleButton button;
     private JPanel buttonsPanel;
-    private final transient List<javax.swing.Action> buttonActions = new ArrayList<>();
+    private final transient List<Action> buttonActions = new ArrayList<>();
 
     /** holds the menu entry in the windows menu. Required to properly
      * toggle the checkbox on show/hide
@@ -283,7 +287,7 @@
             if (isShowing) {
                 hideDialog();
                 if (dialogsPanel != null) {
-                    dialogsPanel.reconstruct(Action.ELEMENT_SHRINKS, null);
+                    dialogsPanel.reconstruct(DialogsPanel.Action.ELEMENT_SHRINKS, null);
                 }
                 hideNotify();
             } else {
@@ -292,7 +296,7 @@
                     expand();
                 }
                 if (isDocked && dialogsPanel != null) {
-                    dialogsPanel.reconstruct(Action.INVISIBLE_TO_DEFAULT, ToggleDialog.this);
+                    dialogsPanel.reconstruct(DialogsPanel.Action.INVISIBLE_TO_DEFAULT, ToggleDialog.this);
                 }
                 showNotify();
             }
@@ -326,14 +330,14 @@
             return;
         if (isDialogInCollapsedView()) {
             expand();
-            dialogsPanel.reconstruct(Action.COLLAPSED_TO_DEFAULT, this);
+            dialogsPanel.reconstruct(DialogsPanel.Action.COLLAPSED_TO_DEFAULT, this);
         } else if (!isDialogShowing()) {
             showDialog();
             if (isDocked && isCollapsed) {
                 expand();
             }
             if (isDocked) {
-                dialogsPanel.reconstruct(Action.INVISIBLE_TO_DEFAULT, this);
+                dialogsPanel.reconstruct(DialogsPanel.Action.INVISIBLE_TO_DEFAULT, this);
             }
             showNotify();
         }
@@ -488,38 +492,39 @@
         /** the label which shows whether the toggle dialog is expanded or collapsed */
         private final JLabel lblMinimized;
         /** the label which displays the dialog's title **/
-        private final JLabel lblTitle;
-        private final JComponent lblTitleWeak;
+        private final JLabel lblTitleIcon;
+        private final JLabel[] lblTitle = new JLabel[4];
         /** the button which shows whether buttons are dynamic or not */
         private final JButton buttonsHide;
         /** the contextual menu **/
         private DialogPopupMenu popupMenu;
+        /** the mouse event handler for the titlebar **/
+        private MouseEventHandler mouseListener;
 
         public TitleBar(String toggleDialogName, String iconName) {
-            setLayout(new GridBagLayout());
+            GroupLayout gl = new GroupLayout(this);
+            setLayout(gl);
+
+            SequentialGroup hg = gl.createSequentialGroup();
+            ParallelGroup vg = gl.createParallelGroup();
+            gl.setHorizontalGroup(hg);
+            gl.setVerticalGroup(vg);
 
             lblMinimized = new JLabel(ImageProvider.get("misc", "normal"));
-            add(lblMinimized);
+            hg.addComponent(lblMinimized, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE);
+            vg.addComponent(lblMinimized);
 
             // scale down the dialog icon
-            lblTitle = new JLabel("", new ImageProvider("dialogs", iconName).setWidth(16).get(), JLabel.TRAILING);
-            lblTitle.setIconTextGap(8);
+            lblTitleIcon = new JLabel(new ImageProvider("dialogs", iconName).setWidth(16).get());
+            hg.addComponent(lblTitleIcon, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE);
+            vg.addComponent(lblTitleIcon);
 
-            JPanel conceal = new JPanel();
-            conceal.add(lblTitle);
-            conceal.setVisible(false);
-            add(conceal, GBC.std());
-
-            // Cannot add the label directly since it would displace other elements on resize
-            lblTitleWeak = new JComponent() {
-                @Override
-                public void paintComponent(Graphics g) {
-                    lblTitle.paint(g);
-                }
-            };
-            lblTitleWeak.setPreferredSize(new Dimension(Integer.MAX_VALUE, 20));
-            lblTitleWeak.setMinimumSize(new Dimension(0, 20));
-            add(lblTitleWeak, GBC.std().fill(GBC.HORIZONTAL));
+            hg.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
+            for (int i = 0; i < lblTitle.length; i++) {
+                lblTitle[i] = new JLabel("");
+                hg.addComponent(lblTitle[i], 0, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE);
+                vg.addComponent(lblTitle[i]);
+            }
 
             buttonsHide = new JButton(ImageProvider.get("misc", buttonHiding != ButtonHidingType.ALWAYS_SHOWN
                 ? /* ICON(misc/)*/ "buttonhide" :  /* ICON(misc/)*/ "buttonshow"));
@@ -535,7 +540,9 @@
                         }
                     }
                     );
-            add(buttonsHide);
+            hg.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE);
+            hg.addComponent(buttonsHide, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE);
+            vg.addComponent(buttonsHide);
 
             // show the pref button if applicable
             if (preferenceClass != null) {
@@ -557,7 +564,8 @@
                             }
                         }
                         );
-                add(pref);
+                hg.addComponent(pref, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE);
+                vg.addComponent(pref);
             }
 
             // show the sticky button
@@ -569,11 +577,12 @@
                         @Override
                         public void actionPerformed(ActionEvent e) {
                             detach();
-                            dialogsPanel.reconstruct(Action.ELEMENT_SHRINKS, null);
+                            dialogsPanel.reconstruct(DialogsPanel.Action.ELEMENT_SHRINKS, null);
                         }
                     }
                     );
-            add(sticky);
+            hg.addComponent(sticky, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE);
+            vg.addComponent(sticky);
 
             // show the close button
             JButton close = new JButton(ImageProvider.get("misc", "close"));
@@ -584,23 +593,47 @@
                         @Override
                         public void actionPerformed(ActionEvent e) {
                             hideDialog();
-                            dialogsPanel.reconstruct(Action.ELEMENT_SHRINKS, null);
+                            dialogsPanel.reconstruct(DialogsPanel.Action.ELEMENT_SHRINKS, null);
                             hideNotify();
                         }
                     }
                     );
-            add(close);
+            hg.addComponent(close, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE);
+            vg.addComponent(close);
+
             setToolTipText(tr("Click to minimize/maximize the panel content"));
-            setTitle(toggleDialogName);
+            lblTitle[0].setText(toggleDialogName);
+        }
+
+        public void setTitle(String s) {
+            setTitle(new String[]{s}, 0);
+        }
+
+        public void setTitle(String[] s, int from) {
+            for (int i = from; i < lblTitle.length; i++) {
+                lblTitle[i].setText(i-from < s.length ? s[i-from] : "");
+                lblTitle[i].repaint();
+            }
+            mouseListener.update();
         }
 
-        public void setTitle(String title) {
-            lblTitle.setText(title);
-            lblTitleWeak.repaint();
+        public void setTitleActions(Action[] actions) {
+            int i = -1;
+            for (final JLabel l: lblTitle) {
+                if (++i < actions.length && actions[i] != null) {
+                    mouseListener.actions.put(l, actions[i]);
+                    l.addMouseListener(mouseListener);
+                    popupMenu.insert(actions[i], 1);
+                }
+            }
         }
 
         public String getTitle() {
-            return lblTitle.getText();
+            StringBuffer r = new StringBuffer(0x80);
+            for (JLabel l: lblTitle) {
+                r.append(l.getText());
+            }
+            return r.toString();
         }
 
         public class DialogPopupMenu extends JPopupMenu {
@@ -619,7 +652,7 @@
                     buttonHidingMenu.add(rb);
                 }
                 add(buttonHidingMenu);
-                for (javax.swing.Action action: buttonActions) {
+                for (Action action: buttonActions) {
                     add(action);
                 }
             }
@@ -627,10 +660,12 @@
 
         public final void registerMouseListener() {
             popupMenu = new DialogPopupMenu();
-            addMouseListener(new MouseEventHandler());
+            addMouseListener(mouseListener = new MouseEventHandler());
         }
 
         class MouseEventHandler extends PopupMenuLauncher {
+            Map<JComponent, Action> actions = new HashMap<>();
+
             /**
              * Constructs a new {@code MouseEventHandler}.
              */
@@ -643,12 +678,64 @@
                 if (SwingUtilities.isLeftMouseButton(e)) {
                     if (isCollapsed) {
                         expand();
-                        dialogsPanel.reconstruct(Action.COLLAPSED_TO_DEFAULT, ToggleDialog.this);
+                        dialogsPanel.reconstruct(DialogsPanel.Action.COLLAPSED_TO_DEFAULT, ToggleDialog.this);
+                        updateTooltips();
                     } else {
-                        collapse();
-                        dialogsPanel.reconstruct(Action.ELEMENT_SHRINKS, null);
+                        Action a = actions.get(e.getComponent());
+                        if (a != null && a.isEnabled()) {
+                            a.actionPerformed(new ActionEvent(e.getSource(), e.getID(),
+                                (String) a.getValue(Action.ACTION_COMMAND_KEY)));
+                        } else {
+                            collapse();
+                            dialogsPanel.reconstruct(DialogsPanel.Action.ELEMENT_SHRINKS, null);
+                            updateTooltips();
+                        }
+                    }
+                }
+            }
+
+            public void update() {
+                short enabledActions = 0;
+                for (JComponent l: actions.keySet()) {
+                    if (update((JLabel) l).isEnabled()) enabledActions++;
+                }
+                for (Action a: actions.values()) {
+                    if (a instanceof SelectionListDialog.SelectAction) {
+                        a.setEnabled(a.isEnabled() && enabledActions > 1);
+                    }
+                }
+                for (Component mi: popupMenu.getComponents()) {
+                    if (mi instanceof JMenuItem) {
+                        Action a = ((JMenuItem) mi).getAction();
+                        if (actions.containsValue(a)) mi.setVisible(a.isEnabled());
                     }
                 }
+                updateTooltips();
+            }
+
+            private Action update(JLabel l) {
+                Action a = actions.get(l);
+                String s = "";
+
+                if (a instanceof SelectionListDialog.SelectAction) {
+                    s = l.getText().replaceAll("\\D", "").replaceAll("^0+", "");
+                    a.setEnabled(s.length() > 0);
+                }
+
+                if (a != null) {
+                    String name = tr((String) a.getValue(Action.ACTION_COMMAND_KEY), s);
+                    a.putValue(Action.NAME, name);
+                    a.putValue(Action.SHORT_DESCRIPTION, name);
+                }
+
+                return a;
+            }
+
+            private void updateTooltips() {
+                for (JComponent l: actions.keySet()) {
+                    Action a = actions.get(l);
+                    l.setToolTipText(isCollapsed || !a.isEnabled() ? getToolTipText() : (String) a.getValue(Action.NAME));
+                }
             }
         }
     }
@@ -671,7 +758,7 @@
                         if (isDialogInCollapsedView()) {
                             expand();
                         }
-                        dialogsPanel.reconstruct(Action.INVISIBLE_TO_DEFAULT, ToggleDialog.this);
+                        dialogsPanel.reconstruct(DialogsPanel.Action.INVISIBLE_TO_DEFAULT, ToggleDialog.this);
                     } else {
                         hideDialog();
                         hideNotify();
@@ -747,12 +834,40 @@
      * @param title The dialog's title
      */
     public void setTitle(String title) {
-        titleBar.setTitle(title);
+        setTitleImpl(new String[]{title}, 0);
+    }
+
+    /**
+     * Sets the title and title suffix strings all at once.
+     * @param title The dialog's title
+     */
+    public void setTitle(String[] title) {
+        setTitleImpl(title, 0);
+    }
+
+    /**
+     * Sets title suffixes.
+     * @param suffixes An array of strings to be used as title suffixes.
+     */
+    public void setTitleSuffixes(String[] suffixes) {
+        setTitleImpl(suffixes, 1);
+    }
+
+    protected void setTitleImpl(String[] s, int from) {
+        titleBar.setTitle(s, from);
         if (detachedDialog != null) {
-            detachedDialog.setTitle(title);
+            detachedDialog.setTitle(titleBar.getTitle());
         }
     }
 
+    /**
+     * Sets actions for titles.
+     * @param actions Action to perform when title and/or its suffixes are clicked, or when chosen from title popup menu.
+     */
+    public void setTitleActions(Action[] actions) {
+        titleBar.setTitleActions(actions);
+    }
+
     protected void setIsShowing(boolean val) {
         isShowing = val;
         Main.pref.put(preferencePrefix+".visible", val);
@@ -889,7 +1004,7 @@
                 buttonsPanel.add(buttonRowPanel);
                 for (SideButton button : buttonRow) {
                     buttonRowPanel.add(button);
-                    javax.swing.Action action = button.getAction();
+                    Action action = button.getAction();
                     if (action != null) {
                         buttonActions.add(action);
                     } else {
