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

Swing drag and drop deadlock

    XMLWordPrintable

Details

    • Bug
    • Resolution: Duplicate
    • P2
    • None
    • 1.2.0
    • client-libs
    • None
    • x86
    • windows_nt

    Description

      import java.awt.*;
      import java.awt.event.*;
      import java.awt.dnd.*;
      import java.awt.datatransfer.*;
      import javax.swing.event.*;
      import javax.swing.*;
      import java.io.*;
      import java.util.*;


      public class BugDndDeadlock
      {


              public static void main(String argv[])
              {
                      // Display the Description
                      for(int i=0; i<desc.length; i++)
                              System.out.println(desc[i]);
                              

                      Frame frame = new Frame("Java-2 Drag/Drop Deadlock Bug");
                      BugDndDeadlock c = new BugDndDeadlock(frame);
              }

              private static final String desc[] =
              {
                      
                      "Usage: java BugDndDeadlock",
                      " This test demonstrates a deadlock problem in Java-2 Drag-Drop.",
                      " Just drag text from one label to another and a deadlock will occur.",
                      " The deadlock is caused by the Label calling setCursor in MOUSE_MOVED",
                      " and can be avoided by removing the call to setCursor."
                      
              };


              public BugDndDeadlock(Frame f)
              {
                      DraggableLabel north = new DraggableLabel("One");
                      DraggableLabel south = new DraggableLabel("Two");
                      DraggableLabel east = new DraggableLabel("Three");
                      DraggableLabel west = new DraggableLabel("Four");
              
                      f.add (north, BorderLayout.NORTH);
                      f.add (south, BorderLayout.SOUTH);
                      f.add (east, BorderLayout.EAST);
                      f.add (west, BorderLayout.WEST);
                      f.setBounds (200, 200, 300, 300);
                      f.addWindowListener (new WindowAdapter()
                                                              {
                                                                              public void windowClosing(WindowEvent e)
                                                                              {
                                                                                      System.exit(0);
                                                                              }
                                                              });
                      f.setVisible (true);
              }

              // ================================================================
              // This is a Subclass of JLabel that supports drag and drop
              // ================================================================
              class DraggableLabel extends JLabel
              implements DragSourceListener
                               , DragGestureListener
                               , DropTargetListener
              {
              
                      
                      public DraggableLabel(String s)
                      {
                              super (s);
                              DragSource dragSource = new DragSource();
                              dragSource.createDefaultDragGestureRecognizer(this
                                                                                                              , DnDConstants.ACTION_COPY_OR_MOVE
                                                                                                              , this);
                              DropTarget dropTarget = new DropTarget (this, this);
                      }

                      // This label changes the cursor when the mouse flys over it
                      //
                      public void processMouseMotionEvent(MouseEvent e)
                      {
                              // Allow Drag/Drop the first crack at mouse events
                              super.processMouseMotionEvent(e);
                              if(!e.isConsumed())
                              {
                                      setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                              }
                      }

                      public void dragGestureRecognized(DragGestureEvent e)
                      {
                              StringSelection transferable = new StringSelection(getText());
                              e.startDrag(DragSource.DefaultCopyDrop, transferable, this);
                      }

                      public void dragDropEnd (DragSourceDropEvent e)
                      {
                              System.out.println("Label: DragDropEnd");
                      }
                      public void dragEnter (DragSourceDragEvent e){}
                      public void dragExit (DragSourceEvent e){}
                      public void dragOver (DragSourceDragEvent e){}
                      public void dropActionChanged (DragSourceDragEvent e){}
                      
                      

                      public void dragEnter (DropTargetDragEvent e)
                      {
                              System.out.println("Entering Drop Target");
                              e.acceptDrag (DnDConstants.ACTION_COPY);
                      }

                      public void dragExit (DropTargetEvent e)
                      {
                              System.out.println("Exiting Drop Target");
                      }

                      public void dragOver (DropTargetDragEvent e)
                      {
                              e.acceptDrag (DnDConstants.ACTION_COPY);
                      }


                      public void drop (DropTargetDropEvent e)
                      {
                              try {
                                      Transferable tr = e.getTransferable();
                                      if (tr.isDataFlavorSupported (DataFlavor.stringFlavor))
                                      {
                                              e.acceptDrop(e.getDropAction());
                                              String s = (String)tr.getTransferData (DataFlavor.stringFlavor);
                                              System.out.println("Accepting Drop of '"+s+"'");
                                              setText(s);
                                              e.dropComplete(true);
                                      } else {
                                              System.err.println ("Rejected");
                                              e.rejectDrop();
                                      }
                              } catch (IOException io) {
                                      io.printStackTrace();
                                      e.rejectDrop();
                              } catch (UnsupportedFlavorException ufe){
                                      ufe.printStackTrace();
                                      e.rejectDrop();
                              }
                      }

                      public void dropActionChanged(DropTargetDragEvent e)
                      {
                      }
                      
              }


      }


      /*

      Here's the JDB Thread Dump at the time of deadlock

      C:\Dev\com\sssw\test\Jdk12>java -version
      java version "1.2"
      Classic VM (build JDK-1.2-V, native threads)

      C:\Dev\com\sssw\test\Jdk12>\jdk1.2\bin\jdb BugDndDeadlock
      Initializing jdb...
      0xae:class(BugDndDeadlock)
      > run
      run BugDndDeadlock
      running ...
      main[1] Usage: java BugDndDeadlock
          This test demonstrates a deadlock problem in Java-2 Drag-Drop.
          Just drag text from one label to another and a deadlock will occur.
          The deadlock is caused by the Label calling setCursor in MOUSE_MOVED
          and can be avoided by removing the call to setCursor.

      Current thread "main" died. Execution continuing...
      > Entering Drop Target
      Exiting Drop Target
      Accepting Drop of 'Four'
      Label: DragDropEnd
      Entering Drop Target
      Exiting Drop Target
      Entering Drop Target
      Exiting Drop Target

      > wherei all
      AWT-EventQueue-0:
        [1] sun.awt.windows.WComponentPeer.setCursor (native method), pc = -1
        [2] java.awt.Component.setCursor (Component:1759), pc = 16
        [3] java.awt.LightweightDispatcher.retargetMouseEvent (LightweightDispatcher:1953), pc = 156
        [4] java.awt.LightweightDispatcher.trackMouseEnterExit (LightweightDispatcher:1817), pc = 117
        [5] java.awt.LightweightDispatcher.processMouseEvent (LightweightDispatcher:1705), pc = 25
        [6] java.awt.LightweightDispatcher.dispatchEvent (LightweightDispatcher:1645), pc = 40
        [7] java.awt.Container.dispatchEventImpl (Container:1019), pc = 12
        [8] java.awt.Window.dispatchEventImpl (Window:714), pc = 89
        [9] java.awt.Component.dispatchEvent (Component:2289), pc = 2
        [10] java.awt.EventQueue.dispatchEvent (EventQueue:258), pc = 36
        [11] java.awt.EventDispatchThread.run (EventDispatchThread:68), pc = 16

      SunToolkit.PostEventQueue-0:
        [1] java.lang.Object.wait (native method), pc = -1
        [2] java.lang.Object.wait (Object:424), pc = 2
        [3] sun.awt.PostEventQueue.run (PostEventQueue:363), pc = 11

      AWT-Windows:
        [1] java.lang.Object.wait (native method), pc = -1
        [2] java.lang.Object.wait (Object:424), pc = 2
        [3] sun.awt.windows.WDropTargetContextPeer.handleMotionMessage (WDropTargetContextPeer:698), pc = 107
        [4] sun.awt.windows.WToolkit.eventLoop (native method), pc = -1
        [5] sun.awt.windows.WToolkit.run (WToolkit:134), pc = 26
        [6] java.lang.Thread.run (Thread:479), pc = 11

      Screen Updater:
        [1] java.lang.Object.wait (native method), pc = -1
        [2] java.lang.Object.wait (Object:424), pc = 2
        [3] sun.awt.ScreenUpdater.nextEntry (ScreenUpdater:79), pc = 8
        [4] sun.awt.ScreenUpdater.run (ScreenUpdater:99), pc = 6
      Thread-2:
        [1] sun.awt.windows.WDragSourceContextPeer.doDragDrop (native method), pc = -1
        [2] sun.awt.windows.WDragSourceContextPeer$1.run (WDragSourceContextPeer$1:163
      ), pc = 18
      >
      */

      Attachments

        Issue Links

          Activity

            People

              rbrinkle Roger Brinkley (Inactive)
              duke J. Duke
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: