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

DragSourceListener.dragExit() is called unexpectedly

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 5.0
    • 5.0
    • client-libs
    • None
    • tiger
    • generic
    • generic



      Name: dsR10078 Date: 02/17/2003



      The problem is reproducible with JDK 1.5.0-b01 on all platforms
      with the following test case:
      ----------------------------------------------------------------------
      import java.awt.*;
      import java.awt.datatransfer.*;
      import java.awt.dnd.*;

      public class Test {
          final Frame frame = new Frame();
          final TextField source = new TextField("Drag me!");
          final TextField target = new TextField("Drop here");

          final DragSource ds = DragSource.getDefaultDragSource();
          final DragSourceListener dsl = new DragSourceListener() {
                  public void dragEnter(DragSourceDragEvent dsde) {
                      System.out.println("[Source] dragEnter");
                  }
                  public void dragOver(DragSourceDragEvent dsde) {
                      System.out.println("[Source] dragOver");
                  }
                  public void dragMouseMoved(DragSourceDragEvent dsde) {
                      System.out.println("[Source] dragMouseMoved");
                  }
                  public void dropActionChanged(DragSourceDragEvent dsde) {
                      System.out.println("[Source] dropActionChanged");
                  }
                  public void dragExit(DragSourceEvent dse) {
                      System.out.println("[Source] dragExit");
                  }
                  public void dragDropEnd(DragSourceDropEvent dsde) {
                      System.out.println("[Source] dragDropEnd");
                  }
              };
          final DragGestureListener dgl = new DragGestureListener() {
                  public void dragGestureRecognized(DragGestureEvent dge) {
                      Transferable t = new StringSelection("TEXT");
                      dge.startDrag(null, t, dsl);
                  }
              };
          final DragGestureRecognizer dgr =
              ds.createDefaultDragGestureRecognizer(source,
                                                    DnDConstants.ACTION_COPY,
                                                    dgl);

          final DropTargetListener dtl = new DropTargetListener() {
                  public void dragEnter(DropTargetDragEvent dtde) {
                      System.out.println("[Target] dragEnter");
                      dtde.rejectDrag();
                  }
                  public void dragOver(DropTargetDragEvent dtde) {
                      System.out.println("[Target] dragOver");
                  }
                  public void dropActionChanged(DropTargetDragEvent dtde) {
                      System.out.println("[Target] dropActionChanged");
                  }
                  public void dragExit(DropTargetEvent dte) {
                      System.out.println("[Target] dragExit");
                  }
                  public void drop(DropTargetDropEvent dtde) {
                      System.out.println("[Target] drop");
                      dtde.rejectDrop();
                  }
              };
          final DropTarget dt = new DropTarget(target, dtl);

          public static void main(String[] args) {
              Test test = new Test();
              test.run();
          }

          public void run() {
              frame.setLayout(new FlowLayout());
              frame.add(source);
              frame.add(target);
              frame.pack();
              frame.setVisible(true);
          }
      }
      ----------------------------------------------------------------------

      Run the test case - a frame will appear.
      Drag from "Drag me!" text field to "Drop here" text field and watch
      the output dumped to the console.
      On Solaris/Linux the typical output is as follows:
      ----------------------------------------------------------------------
      [Source] dragExit
      [Source] dragExit
      [Source] dragExit
      [Source] dragExit
      [Source] dragExit
      [Target] dragEnter
      [Target] dragOver
      [Source] dragExit
      [Target] dragOver
      [Source] dragExit
      [Target] dragOver
      [Source] dragExit
      [Target] dragOver
      [Source] dragExit
      [Source] dragExit
      [Target] dragExit
      [Source] dragDropEnd
      ----------------------------------------------------------------------

      On Windows the typical output is as follows:
      ----------------------------------------------------------------------
      [Source] dragExit
      [Source] dragExit
      [Target] dragEnter
      [Source] dragExit
      [Target] dragOver
      [Source] dragExit
      [Target] dragOver
      [Source] dragExit
      [Target] dragOver
      [Source] dragExit
      [Target] dragOver
      [Source] dragExit
      [Target] dragExit
      [Source] dragExit
      [Source] dragDropEnd
      ----------------------------------------------------------------------

      There are two problems with the observed behavior:
      1.DragSourceListener.dragExit() is called even before the drag enters the drop
        target. This behavior doesn't match the javadoc comments for the method.
      2.DragSourceListener.dragExit() is called after the drag enters the drop target
        and the drop target rejects the drag. This behavior matches the javadoc
        comments for the method, but it contradicts with the Drag and Drop
        Specification (see
      http://java.sun.com/j2se/1.4.1/docs/guide/dragndrop/spec/dnd1.doc5.html#920315).
       
        The difference between the javadoc and the Drag and Drop Specification is in
        the condition for the DragSourceListener.dragExit() to be called if the drop
        target rejected the drag. dragExit() is invoked when:

      javadoc:
         "...the current drop site has rejected the drag."
      DnD spec:
         "...the current DropTarget's DropTargetListener has invoked rejectDrag()
          since the last dragEnter() or dragOver() invocation."

      We believe that the behavior prescribed by javadoc is counter-intuitive:
      dragExit() can be called without preceeding dragEnter() or dragOver().
      The behavior documented in the DnD spec is more reasonable:
      dragExit() is called only after respective dragEnter() or dragOver().

      ###@###.### 2003-02-17
      ======================================================================

            dassunw Das Das (Inactive)
            dassunw Das Das (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: