FULL PRODUCT VERSION :
java version "1.5.0_03"
Java (TM) 2 Runtime Environment, Standard Edition (build 1.5.0_03-b07)
Java HotSpot(TM) Client VM (build 1.5.0_03-b07, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP Version 5.1.2600
A DESCRIPTION OF THE PROBLEM :
When attempting to drag items from a multi-selected JList using the left mouse button for the drag gesture, an InvalidDndException gets thrown when the statement
SunDragSourceContextPeer.setDragDropInProgress(true);
is executed in java.awt.dnd.DragSource.startDrag().
This problem does not occur if you use the right mouse button for the drag gesture.
This problem does not occur if the list as a single item selected.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the attached class DndBug.
Select more than one item from the list labeled "Drag From List" and holding down the left mouse button initiate a drag. As soon as the drag gesture is recognized the exception is thrown.
Selecting one item does not have this problem when using the left mosue button.
Selecting more than one item, then holding down the right mouse button for the drag gesture does not have this problem.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The drag gesture from the multi-selected JList should work if the left mouse button is being used for the drag gesture.
ACTUAL -
An InvalidDndOperationException was thrown with the message "Drag and drop in progress"
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.awt.dnd.InvalidDnDOperationException: Drag and drop in progress
at sun.awt.dnd.SunDragSourceContextPeer.setDragDropInProgress(SunDragSourceContextPeer.java:298)
at java.awt.dnd.DragSource.startDrag(DragSource.java:286)
at java.awt.dnd.DragSource.startDrag(DragSource.java:403)
at java.awt.dnd.DragGestureEvent.startDrag(DragGestureEvent.java:223)
at DnDBug.dragGestureRecognized(DnDBug.java:122)
at java.awt.dnd.DragGestureRecognizer.fireDragGestureRecognized(DragGestureRecognizer.java:339)
at sun.awt.windows.WMouseDragGestureRecognizer.mouseDragged(WMouseDragGestureRecognizer.java:202)
at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:262)
at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:261)
at java.awt.Component.processMouseMotionEvent(Component.java:5536)
at javax.swing.JComponent.processMouseMotionEvent(JComponent.java:3111)
at java.awt.Component.processEvent(Component.java:5257)
at java.awt.Container.processEvent(Container.java:1966)
at java.awt.Component.dispatchEventImpl(Component.java:3955)
at java.awt.Container.dispatchEventImpl(Container.java:2024)
at java.awt.Component.dispatchEvent(Component.java:3803)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3909)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)
at java.awt.Container.dispatchEventImpl(Container.java:2010)
at java.awt.Window.dispatchEventImpl(Window.java:1774)
at java.awt.Component.dispatchEvent(Component.java:3803)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
public class DnDBug implements DragGestureListener, DragSourceListener,
DropTargetListener {
private JFrame frame;
private JList list1;
private JList list2;
public DnDBug() {
super();
initialize();
showFrame();
}
private void initialize() {
initComponents();
initLayout();
}
private void initComponents() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setTitle("Multi-Select Drag and Drop Bug");
list1 = new JList(new Object[] { "Test 1", "Test 2", "Test 3" });
list2 = new JList(new Object[] { "Test 4", "Test 5" });
list1.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
list1.setDragEnabled(true);
DragSource ds = DragSource.getDefaultDragSource();
DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer(
list1, DnDConstants.ACTION_COPY, this);
}
private void initLayout() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.insets = new Insets(10, 10, 10, 10);
c.anchor = GridBagConstraints.SOUTH;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(new JLabel("Drag From List"), c);
c.gridx = 1;
panel.add(Box.createHorizontalStrut(5), c);
c.gridx = 2;
panel.add(new JLabel("Drag To List"));
c.gridy++;
c.gridx = 0;
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.NORTHWEST;
panel.add(list1, c);
c.gridx = 1;
panel.add(Box.createRigidArea(new Dimension(70, 70)), c);
c.gridx = 2;
panel.add(list2, c);
frame.getContentPane().add(panel);
}
private void showFrame() {
frame.pack();
frame.setSize(800, 600);
Dimension sd = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation((sd.width - 800) / 2, (sd.height - 600) / 2);
frame.setVisible(true);
frame.toFront();
}
/**
* Set the offset point and drag image in the dnd manager
*/
public void dragGestureRecognized(DragGestureEvent dge) {
Component component = dge.getComponent();
if (component instanceof JList) {
JList jList = (JList) component;
try {
dge.startDrag(null, new ObjectsTransfer(jList.getSelectedValues()),
this);
}
catch (Exception exp) {
exp.printStackTrace();
}
}
}
public static void main(String[] args) {
new DnDBug();
}
/////////////// Start Of Drag Source Listener Interface ////////////////
public void dragDropEnd(DragSourceDropEvent dsde) {}
public void dragEnter(DragSourceDragEvent dsde) {}
public void dragExit(DragSourceEvent dse) {}
public void dragOver(DragSourceDragEvent dsde) {}
public void dropActionChanged(DragSourceDragEvent dsde) {}
/////////////// End Of Drag Source Listener Interface ////////////////
/////////////// Start Of Drop Target Listener Interface ////////////////
public void dragEnter(DropTargetDragEvent dtde) {}
public void dragExit(DropTargetEvent dte) {}
public void dragOver(DropTargetDragEvent dtde) {}
public void drop(DropTargetDropEvent dtde) {}
public void dropActionChanged(DropTargetDragEvent dtde) {}
/////////////// End Of Drop Target Listener Interface ////////////////
class ObjectsTransfer implements Transferable {
private final DataFlavor OT_Flavor = new DataFlavor(ObjectsTransfer.class, "ObjectsTransfer");
private Object[] objectArr;
public ObjectsTransfer(Object[] objectArr) {
this.objectArr = objectArr;
}
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
return objectArr;
}
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] {OT_Flavor};
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return OT_Flavor.equals(flavor);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use the Right mouse button for any multi-selecting drags, which is not acceptable.
If JList.setDragEnabled(false) is called on the drag list, a multi-select drag cannot be accomplished because the mouse press to initiate the drag gesture will cause the current selection to be lost.
###@###.### 2005-07-08 12:50:47 GMT