Index: src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java
===================================================================
--- src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java	(revision 1213)
+++ src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java	(working copy)
@@ -10,27 +10,34 @@
 import java.awt.GridLayout;
 import java.awt.LayoutManager;
 import java.awt.Rectangle;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.io.IOException;
 import java.util.HashMap;
-import java.util.TreeMap;
 import java.util.Map;
 
+import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.DefaultListCellRenderer;
 import javax.swing.DefaultListModel;
 import javax.swing.Icon;
 import javax.swing.JButton;
+import javax.swing.JComponent;
 import javax.swing.JLabel;
 import javax.swing.JList;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.JToolBar;
 import javax.swing.ListCellRenderer;
+import javax.swing.TransferHandler;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.util.ReorderAndMoveListDndHandler;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -107,9 +114,10 @@
             @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                 String s = tr("Separator");
                 Icon i = ImageProvider.get("preferences/separator");
-                if (value != null) {
-                    s = (String)((Action)value).getValue(Action.NAME);
-                    i = (Icon)((Action)value).getValue(Action.SMALL_ICON);
+                Action action = actions.get(value);
+                if (action != null) {
+                    s = (String) action.getValue(Action.NAME);
+                    i = (Icon) action.getValue(Action.SMALL_ICON);
                 }
                 JLabel l = (JLabel)oldRenderer.getListCellRendererComponent(list, s, index, isSelected, cellHasFocus);
                 l.setIcon(i);
@@ -136,20 +144,35 @@
                 downButton.setEnabled(sel);
             }
         });
+        
+        selectedList.setDragEnabled(true);
+        selectedList.setTransferHandler(new ReorderAndMoveListDndHandler(ACTION_FLAVOR) {
+            @Override
+            protected Transferable createTransferable(JComponent c) {
+                return new ActionTransferable(((JList)c).getSelectedValues());
+            } 
+        });
+        unselectedList.setDragEnabled(true);
+        unselectedList.setTransferHandler(new TransferHandler() {
+            private static final long serialVersionUID = 1L;
+        
+            @Override
+            public int getSourceActions( JComponent c ){
+                return TransferHandler.MOVE;
+            }
+            
+            @Override
+            protected void exportDone(JComponent source, Transferable data, int action) {
+            }
+            
+            @Override
+            protected Transferable createTransferable(JComponent c) {
+                return new ActionTransferable(((JList)c).getSelectedValues());
+            }
+    });
     }
 
     public void addGui(PreferenceDialog gui) {
-        selected.removeAllElements();
-        unselected.removeAllElements();
-        Map<String, Action> us = new TreeMap<String, Action>();
-        for (Action a : actions.values())
-        {
-            us.put(a.getValue(Action.NAME).toString()+a.toString(), a);
-        }
-        for (String a : us.keySet())
-            unselected.addElement(us.get(a));
-        unselected.addElement(null);
-
         final JPanel left = new JPanel(new GridBagLayout());
         left.add(new JLabel(tr("Toolbar")), GBC.eol());
         left.add(new JScrollPane(selectedList), GBC.std().fill(GBC.BOTH));
@@ -179,8 +202,8 @@
                 return new Dimension(l.width+b.width+10+r.width,l.height+b.height+10+r.height);
             }
             public Dimension preferredLayoutSize(Container parent) {
-                Dimension l = left.getPreferredSize();
-                Dimension r = right.getPreferredSize();
+                Dimension l = new Dimension(200, 200); //left.getPreferredSize();
+                Dimension r = new Dimension(200, 200); //right.getPreferredSize();
                 return new Dimension(l.width+r.width+10+buttons.getPreferredSize().width,Math.max(l.height, r.height));
             }
             public void layoutContainer(Container parent) {
@@ -200,21 +223,26 @@
                 tr("Customize the elements on the toolbar."), false);
         panel.add(p, GBC.eol().fill(GBC.BOTH));
 
+        selected.removeAllElements();
+        unselected.removeAllElements();
+        for (String a : actions.keySet())
+            unselected.addElement(a);
+        unselected.addElement(null);
         for (String s : getToolString()) {
             if (s.equals("|"))
                 selected.addElement(null);
             else {
-                Action a = actions.get(s);
-                if (a != null) {
-                    selected.addElement(a);
-                    unselected.removeElement(a);
+                if (actions.get(s) != null) {
+                    selected.addElement(s);
+                    unselected.removeElement(s);
                 }
             }
         }
     }
 
     private String[] getToolString() {
-        String s = Main.pref.get("toolbar", "open;save;exportgpx;|;download;upload;|;undo;redo;|;preference");
+        String s = Main.pref.get("toolbar",
+                "open;save;exportgpx;|;download;upload;|;undo;redo;|;preference");
         if (s == null || s.equals("null") || s.equals(""))
             return new String[0];
         return s.split(";");
@@ -239,7 +267,7 @@
             if (selected.get(i) == null)
                 b.append("|");
             else
-                b.append(((Action)selected.get(i)).getValue("toolbar"));
+                b.append((actions.get(selected.get(i))).getValue("toolbar"));
             b.append(";");
         }
         String s = b.toString();
@@ -276,4 +304,34 @@
         }
         control.setVisible(control.getComponentCount() != 0);
     }
-}
+
+    private static DataFlavor ACTION_FLAVOR = new DataFlavor(
+            AbstractAction.class, "ActionItem");
+    
+    private class ActionTransferable implements Transferable {
+        
+        private DataFlavor[] flavors = new DataFlavor[] { ACTION_FLAVOR };
+        
+        private Object[] actions;
+        
+        public ActionTransferable(Action action) {
+            this.actions = new Action[] { action };
+        }
+        
+        public ActionTransferable(Object[] actions) {
+            this.actions = actions;
+        }
+
+        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
+            return actions;
+        }
+
+        public DataFlavor[] getTransferDataFlavors() {
+            return flavors;
+        }
+
+        public boolean isDataFlavorSupported(DataFlavor flavor) {
+            return flavors[0] == flavor;
+        }
+    }
+ }
Index: src/org/openstreetmap/josm/gui/util/ReorderAndMoveListDndHandler.java
===================================================================
--- src/org/openstreetmap/josm/gui/util/ReorderAndMoveListDndHandler.java	(revision 0)
+++ src/org/openstreetmap/josm/gui/util/ReorderAndMoveListDndHandler.java	(revision 0)
@@ -0,0 +1,105 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.util;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+
+import javax.swing.DefaultListModel;
+import javax.swing.JComponent;
+import javax.swing.JList;
+import javax.swing.SwingUtilities;
+import javax.swing.TransferHandler;
+
+/**
+ * @author Igor Shubovych igor.shubovych@gmail.com
+ */
+public class ReorderAndMoveListDndHandler extends TransferHandler {
+    
+    public ReorderAndMoveListDndHandler(DataFlavor flavor) {
+        this.flavor = flavor;
+    }
+    
+    private DataFlavor flavor;
+    
+    private static final long serialVersionUID = 1L;
+    
+    public int getSourceActions( JComponent c ){
+        return TransferHandler.MOVE;
+    }
+    
+    @Override
+    public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
+        for (DataFlavor f : transferFlavors) {
+            if (flavor.equals(f)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    @Override
+    public boolean importData(JComponent comp, Transferable t) {
+        try{
+            // this is the index of the element onto which the dragged element, is dropped
+            final JList dragList = (JList) comp;
+            final int dropIndex = dragList.locationToIndex( dragList.getDropLocation().getDropPoint() );
+            Object[] draggedData = (Object[]) t.getTransferData(flavor);
+            DefaultListModel dragModel    = (DefaultListModel)dragList.getModel();
+            DefaultListModel dropModel    = (DefaultListModel)dragList.getModel();
+            
+            final Object leadItem     = dropIndex >= 0 ? dropModel.elementAt( dropIndex ) : null;
+            final int dataLength     = draggedData.length;            
+
+            if( leadItem != null )
+                for( int i = 0 ; i < dataLength ; i++ )
+                    if( draggedData[i].equals( leadItem ) )
+                        return false;                
+            
+            int dragLeadIndex        = -1;
+            final boolean localDrop    = dropModel.contains( draggedData[0] );
+            
+            if( localDrop )
+                dragLeadIndex    = dropModel.indexOf( draggedData[0] );
+            
+            for( int i = 0 ; i < dataLength ; i++ )
+                dragModel.removeElement( draggedData[i] );
+                    
+            if( localDrop ){
+                final int adjustedLeadIndex = dropModel.indexOf( leadItem );
+                final int insertionAdjustment = dragLeadIndex <= adjustedLeadIndex ? 1 : 0;
+                    
+                final int [] indices = new int[dataLength];
+                for( int i = 0 ; i < dataLength ; i++ ){
+                    dropModel.insertElementAt( draggedData[i], adjustedLeadIndex + insertionAdjustment + i );
+                    indices[i] = adjustedLeadIndex + insertionAdjustment + i;
+                }
+                
+                SwingUtilities.invokeLater( new Runnable(){
+                    public void run() {
+                        dragList.clearSelection();        
+                        dragList.setSelectedIndices( indices );
+                    }
+                });
+            }
+            else{
+                final int [] indices = new int[dataLength];
+                for( int i = 0 ; i < dataLength ; i++ ){
+                    dropModel.insertElementAt( draggedData[i], dropIndex + 1 );
+                    indices[i] = dropIndex + 1 + i;
+                }
+                
+                SwingUtilities.invokeLater( new Runnable(){
+                    public void run() {
+                        dragList.clearSelection();        
+                        dragList.setSelectedIndices( indices );
+                        dragList.clearSelection();
+                    }
+                });
+            }
+        }
+        catch( Exception x ){
+            x.printStackTrace();
+        }            
+        return false;
+    }
+}
\ No newline at end of file

Property changes on: src/org/openstreetmap/josm/gui/util/ReorderAndMoveListDndHandler.java
___________________________________________________________________
Added: svn:executable
   + *

