Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4950103

InvalidDnDOperationException when Dragging/Dropping in the same JTable

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 1.4.2
    • client-libs
    • x86
    • windows_xp



      Name: rmT116609 Date: 11/06/2003


      FULL PRODUCT VERSION :
      java version "1.4.2_01"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_01-b06)
      Java HotSpot(TM) Client VM (build 1.4.2_01-b06, mixed mode)

      FULL OS VERSION :
      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      When trying to move rows around in a JTable (by dragging and ropping them). I get an InvalidDnDOperationException with the message "Drag and drop in progress".

      This only happens if you try to initiate a drag with the exact row that you just dropped, without changing the selection. The drag and drop will be successful if you try other rows, or you change the selection.

      I am pretty sure I am accepting and completing the drop correctly in the drop method of the DropTargetListener.

      The exact stack trace is below.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1) Run RowDraggingTable
      2) Click & Drag the first row and drop it on the second row (for example)... the rows should swap
      3) Click & Drag the new second row anywhere... the exception should occur

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The newly dropped row should be able to be dragged like any other row
      ACTUAL -
      I get the InvalidDnDOperationException when I try to initiate a drag with the newly dropped row

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.awt.dnd.InvalidDnDOperationException: Drag and drop in progress
      at sun.awt.dnd.SunDragSourceContextPeer.setDragDropInProgress(SunDragSourceContextPeer.java:328)
      at java.awt.dnd.DragSource.startDrag(DragSource.java:285)
      at java.awt.dnd.DragSource.startDrag(DragSource.java:402)
      at java.awt.dnd.DragGestureEvent.startDrag(DragGestureEvent.java:201)
      at RowDraggingTable.dragGestureRecognized(RowDraggingTable.java:83)
      at java.awt.dnd.DragGestureRecognizer.fireDragGestureRecognized(DragGestureRecognizer.java:339)
      at sun.awt.windows.WMouseDragGestureRecognizer.mouseDragged(WMouseDragGestureRecognizer.java:205)
      at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:262)
      at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:261)
      at java.awt.Component.processMouseMotionEvent(Component.java:5148)
      at javax.swing.JComponent.processMouseMotionEvent(JComponent.java:2779)
      at java.awt.Component.processEvent(Component.java:4901)
      at java.awt.Container.processEvent(Container.java:1569)
      at java.awt.Component.dispatchEventImpl(Component.java:3615)
      at java.awt.Container.dispatchEventImpl(Container.java:1627)
      at java.awt.Component.dispatchEvent(Component.java:3477)
      at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3483)
      at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3215)
      at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3128)
      at java.awt.Container.dispatchEventImpl(Container.java:1613)
      at java.awt.Window.dispatchEventImpl(Window.java:1606)
      at java.awt.Component.dispatchEvent(Component.java:3477)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:456)
      at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)
      at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.swing.table.TableModel;
      import javax.swing.table.TableColumnModel;
      import javax.swing.table.DefaultTableModel;
      import javax.swing.*;
      import java.awt.dnd.*;
      import java.awt.*;
      import java.awt.datatransfer.Transferable;
      import java.awt.datatransfer.DataFlavor;
      import java.awt.datatransfer.UnsupportedFlavorException;
      import java.util.Vector;
      import java.util.HashSet;
      import java.util.Set;
      import java.util.Iterator;
      import java.io.IOException;


      public class RowDraggingTable extends JTable implements Autoscroll, DropTargetListener, DragGestureListener {
      private static final int AUTOSCROLL_MARGIN = 25;
      protected Insets autoscrollInsets = new Insets(0, 0, 0, 0);

      private Set listeners = new HashSet();

      public RowDraggingTable() {
      initdrag();
      }

      public RowDraggingTable(int numRows, int numColumns) {
      super(numRows, numColumns);
      initdrag();
      }

      public RowDraggingTable(Object[][] rowData, Object[] columnNames) {
      super(rowData, columnNames);
      initdrag();
      }

      public RowDraggingTable(TableModel dm) {
      super(dm);
      initdrag();
      }

      public RowDraggingTable(TableModel dm, TableColumnModel cm) {
      super(dm, cm);
      initdrag();
      }

      public RowDraggingTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) {
      super(dm, cm, sm);
      initdrag();
      }

      public RowDraggingTable(Vector rowData, Vector columnNames) {
      super(rowData, columnNames);
      initdrag();
      }

      private void initdrag() {
      setDragEnabled(true);
      DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, this);
      setDropTarget(new DropTarget(this, DnDConstants.ACTION_MOVE, this));
      }

      /** Add a listener to tell when a row is dragged to a new spot */
      public void addRowDragListener(RowDragListener l) {
      listeners.add(l);
      }

      /** Remove the row drag listener */
      public void removeRowDragListener(RowDragListener l) {
      listeners.remove(l);
      }

      public void dragGestureRecognized(DragGestureEvent e) {
      if (getDragEnabled() == true) {
      int row = getSelectedRow();

      if (row > -1) {
      if (isEditing() == true) {
      getCellEditor().stopCellEditing();
      }

      try {
      e.startDrag(DragSource.DefaultMoveDrop, new IntegerTransfer(row));
      } catch (InvalidDnDOperationException dnd) {
      for (Iterator it = listeners.iterator(); it.hasNext();) {
      RowDragListener l = (RowDragListener) it.next();
      l.dropError(this, dnd);
      }
      }
      }
      }
      }


      public void autoscroll(Point location) {
      int top = 0;
      int left = 0;
      int bottom = 0;
      int right = 0;

      Dimension size = getSize();
      Rectangle rect = getVisibleRect();
      int bottomEdge = rect.y + rect.height;
      int rightEdge = rect.x + rect.width;

      if (((location.y - rect.y) <= AUTOSCROLL_MARGIN) && (rect.y > 0)) {
      top = AUTOSCROLL_MARGIN;
      }

      if (((location.x - rect.x) <= AUTOSCROLL_MARGIN) && (rect.x > 0)) {
      left = AUTOSCROLL_MARGIN;
      }

      if (((bottomEdge - location.y) <= AUTOSCROLL_MARGIN) && (bottomEdge < size.height)) {
      bottom = AUTOSCROLL_MARGIN;
      }

      if (((rightEdge - location.x) <= AUTOSCROLL_MARGIN) && (rightEdge < size.width)) {
      right = AUTOSCROLL_MARGIN;
      }

      rect.x += right - left;
      rect.y += bottom - top;

      scrollRectToVisible(rect);
      }


      public Insets getAutoscrollInsets() {
      Dimension size = getSize();
      Rectangle rect = getVisibleRect();
      autoscrollInsets.top = rect.y + AUTOSCROLL_MARGIN;
      autoscrollInsets.left = rect.x + AUTOSCROLL_MARGIN;
      autoscrollInsets.bottom = size.height - (rect.y + rect.height) + AUTOSCROLL_MARGIN;
      autoscrollInsets.right = size.width - (rect.x + rect.width) + AUTOSCROLL_MARGIN;
      return autoscrollInsets;
      }


      public void dragEnter(DropTargetDragEvent dtde) {
      if (dtde.getDropAction() != DnDConstants.ACTION_MOVE)
      dtde.acceptDrag(DnDConstants.ACTION_MOVE);

      };

      public void dragExit(DropTargetEvent dte) {
      }

      public void dragOver(DropTargetDragEvent dtde) {
      if (dtde.getDropAction() != DnDConstants.ACTION_MOVE)
      dtde.acceptDrag(DnDConstants.ACTION_MOVE);
      }

      public void drop(DropTargetDropEvent dtde) {
      DataFlavor df = IntegerTransfer.flavor;
      if (dtde.isDataFlavorSupported(df)) {
      dtde.acceptDrop(dtde.getDropAction());
      Transferable transferable = dtde.getTransferable();

      try {
      int source_row = ((Integer) transferable.getTransferData(df)).intValue();
      int dest_row = rowAtPoint(dtde.getLocation());

      //notify...
      for (Iterator it = listeners.iterator(); it.hasNext();) {
      RowDragListener l = (RowDragListener) it.next();
      l.rowDragged(this, source_row, dest_row);
      }

      dtde.dropComplete(true);
      } catch (Exception e) {
      for (Iterator it = listeners.iterator(); it.hasNext();) {
      RowDragListener l = (RowDragListener) it.next();
      l.dropError(this, e);
      }
      dtde.dropComplete(false);
      }
      } else {
      dtde.rejectDrop();
      }
      }

      public void dropActionChanged(DropTargetDragEvent dtde) {
      if (dtde.getDropAction() != DnDConstants.ACTION_MOVE)
      dtde.acceptDrag(DnDConstants.ACTION_MOVE);
      };


      private static class IntegerTransfer implements Transferable {
      static DataFlavor flavor = new DataFlavor(Integer.class, "Integer");
      private Integer row = null;

      public IntegerTransfer(int row) {
      this.row = new Integer(row);
      }

      public DataFlavor[] getTransferDataFlavors() {
      return new DataFlavor[]{flavor};
      }

      public boolean isDataFlavorSupported(DataFlavor flavor) {
      return this.flavor.equals(flavor);
      }

      public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
      if (!isDataFlavorSupported(flavor)) throw new UnsupportedFlavorException(flavor);

      return row;
      }
      }

      /** Use to listen to drag events from this RowDraggingTable */
      public static interface RowDragListener {
      /** Called when there is some sort of error while dragging */
      void dropError(RowDraggingTable source, Exception e);

      /** Called when a drop is complete... it is up to the listener
      * to modify the model to reflect any needed changes */
      void rowDragged(RowDraggingTable source, int source_row, int dest_row);
      }


      public static final void main(String[] args) {
      JFrame testframe = new JFrame("Test Window");
      testframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      testframe.getContentPane().setLayout(new BorderLayout(0, 0));

      DefaultTableModel model = new DefaultTableModel(new Object[] {"Col 1", "Col 2"}, 0);
      for (int i = 0; i < 100; i++) {
      model.addRow(new Object[] {new Integer(i), "Row Data " + i});
      }

      RowDraggingTable rdt = new RowDraggingTable(model);
      rdt.addRowDragListener(new RowDragListener() {
      public void dropError(RowDraggingTable source, Exception e) {
      e.printStackTrace();
      }

      public void rowDragged(RowDraggingTable source, int source_row, int dest_row) {
      DefaultTableModel model = (DefaultTableModel) source.getModel();
      model.moveRow(source_row, source_row, dest_row);
      source.getSelectionModel().setSelectionInterval(dest_row, dest_row);
      }
      });

      testframe.getContentPane().add(new JScrollPane(rdt), BorderLayout.CENTER);

      testframe.pack();
      testframe.setVisible(true);
      }
      }

      ---------- END SOURCE ----------

      (Incident Review ID: 223420)
      ======================================================================

            agerasimsunw Alexander Gerasimov (Inactive)
            rmandalasunw Ranjith Mandala (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: