JDK-4774532 : Incorrect drop action after rejectDrag()
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2002-11-06
  • Updated: 2002-11-15
  • Resolved: 2002-11-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.2 mantisFixed
Related Reports
Relates :  
Relates :  
Description

Name: dsR10078			Date: 11/06/2002

###@###.###

The problem is reproducible on all platforms with JDK 1.4.2-b03 and later.
To reproduce compile and run the following test case:
-----------------------------------------------------------------------------------
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;

public class Test {
    public static void main(String[] args) {
        final Frame f = new Frame();
        final DragSource ds = DragSource.getDefaultDragSource();
        final Transferable t = new StringSelection("TEXT");
        final DragSourceListener dsl = new DragSourceAdapter() {
                public void dragEnter(DragSourceDragEvent dsde) {
                    System.out.println("[Source]dragEnter userAction=" +
                                       Integer.toHexString(dsde.getUserAction())
                                       + " dropAction=" +
                                       Integer.toHexString(dsde.getDropAction()));
                }
                public void dragOver(DragSourceDragEvent dsde) {
                    System.out.println("[Source]dragOver userAction=" +
                                       Integer.toHexString(dsde.getUserAction())
                                       + " dropAction=" +
                                       Integer.toHexString(dsde.getDropAction()));
                }        
                public void dropActionChanged(DragSourceDragEvent dsde) {
                    System.out.println("[Source]dropActionChanged userAction=" +
                                       Integer.toHexString(dsde.getUserAction())
                                       + " dropAction=" +
                                       Integer.toHexString(dsde.getDropAction()));
                    }
            };
        final DragGestureListener dgl = new DragGestureListener() {
                public void dragGestureRecognized(DragGestureEvent dge) {
                    dge.startDrag(null, t, dsl);
                }
            };
        final DragGestureRecognizer dgr =
            ds.createDefaultDragGestureRecognizer(f,
                                                  DnDConstants.ACTION_COPY_OR_MOVE, dgl);
        final DropTargetListener dtl = new DropTargetAdapter() {
                public void dragEnter(DropTargetDragEvent dtde) {
                    System.out.println("[Target]dragEnter action=" +
                                       Integer.toHexString(dtde.getDropAction()));
                    dtde.rejectDrag();
                }
                public void dragOver(DropTargetDragEvent dtde) {
                    int dropAction = dtde.getDropAction();
                    System.out.println("[Target]dragOver action=" +
                                       Integer.toHexString(dropAction));
                    if (dropAction != DnDConstants.ACTION_NONE) {
                        dtde.acceptDrag(dropAction);
                    }
                }
                public void drop(DropTargetDropEvent dtde) {
                    dtde.rejectDrop();
                }
            };
        final DropTarget dt = new DropTarget(f, dtl);

        f.setBounds(100, 100, 100, 100);
        f.setVisible(true);
    }
}
-----------------------------------------------------------------------------------
A frame will appear. 
Press the left mouse button inside the frame and drag the mouse, holding 
the mouse button pressed. Do not press any modifier keys during drag. 
Here is a typical output for 1.4.2-b01:
-----------------------------------------------------------------------------------
[Target]dragEnter action=2
[Target]dragOver action=2
[Source]dragOver userAction=2 dropAction=2
[Target]dragOver action=2
[Source]dragOver userAction=2 dropAction=2
[Target]dragOver action=2
[Source]dragOver userAction=2 dropAction=2
[Target]dragOver action=2
[Source]dragOver userAction=2 dropAction=2
[Target]dragOver action=2
-----------------------------------------------------------------------------------
The output for 1.4.2-b03 and later:
-----------------------------------------------------------------------------------
[Target]dragEnter action=2
[Target]dragOver action=0
[Target]dragOver action=0
[Target]dragOver action=0
[Target]dragOver action=0
[Target]dragOver action=0
[Target]dragOver action=0
-----------------------------------------------------------------------------------
The new behavior doesn't match the javadoc, as 
DropTargetDragEvent.getDropAction() is documented to return the "user drop 
action" that depends on the drop actions supported by the drag source and 
the drop action selected by the user. According to the specification the 
"user drop action" is ACTION_MOVE as the drag source supports COPY and MOVE 
actions and the user doesn't select a drop action. 
With 1.4.2-b03 and later, getDropAction() incorrectly returns ACTION_NONE.

Another problem is that according to the javadoc, DragSourceListener.dragOver() 
should be called if the drop target accepts the drag. The test case demonstrates 
that with 1.4.2-b03, if the drop target rejected the drag initially,
DragSourceListener.dragOver() will never be called even if the drop target 
accepts the drag later.

###@###.### 2002-11-06
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mantis FIXED IN: mantis INTEGRATED IN: mantis mantis-b08
14-06-2004

WORK AROUND Name: dsR10078 Date: 11/06/2002 ======================================================================
11-06-2004

SUGGESTED FIX Name: dsR10078 Date: 11/06/2002 Reset SunDropTargetContextPeer.dragRejected flag whenever acceptDrag is called with a drop action other than ACTION_NONE. Check if dragRejected and reset the current drop action to ACTION_NONE after the DropTargetListener is called, not before. --- SunDropTargetContextPeer.java Wed Nov 6 13:58:27 2002 *************** *** 463,472 **** currentA = currentDT.getDefaultActions(); - if (dragRejected) { - currentDA = DnDConstants.ACTION_NONE; - } - try { DropTargetDragEvent dtde = new DropTargetDragEvent(dtc, hots, --- 463,468 ---- *************** *** 478,483 **** --- 474,483 ---- } else { dtl.dragOver(dtde); } + + if (dragRejected) { + currentDA = DnDConstants.ACTION_NONE; + } } catch (Exception e) { e.printStackTrace(); currentDA = DnDConstants.ACTION_NONE; *************** *** 565,570 **** --- 565,573 ---- throw new InvalidDnDOperationException("No Drag pending"); } currentDA = mapOperation(dragOperation); + if (currentDA != DnDConstants.ACTION_NONE) { + dragRejected = false; + } } /** ###@###.### 2002-11-06 ======================================================================
06-11-2002

EVALUATION Name: dsR10078 Date: 11/06/2002 This change in behavior was introduced with the fix for 4407521. Another manifestation of this problem is that the workaround for the bug 4716067 doesn't work anymore. See evaluation for 4716067 for details. ###@###.### 2002-11-06 ======================================================================
06-11-2002