United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4217341 Problems with drag and drop across Java applications
JDK-4217341 : Problems with drag and drop across Java applications

Details
Type:
Bug
Submit Date:
1999-03-04
Status:
Closed
Updated Date:
2000-10-05
Project Name:
JDK
Resolved Date:
2000-10-05
Component:
client-libs
OS:
windows_nt
Sub-Component:
java.awt
CPU:
x86
Priority:
P2
Resolution:
Not an Issue
Affected Versions:
1.2.0
Fixed Versions:

Related Reports
Relates:
Relates:

Sub Tasks

Description

Name: vi73552			Date: 03/04/99


Despite the closed bug report 4126713 drag and drop is still
not working between java applications. The code which follows
illustrates the point...

The code works fine when the drag and drop is within one 
application but when two instances are started and you attempt
to drag and drop between them an exception is generated which
reads as follows...

java.io.IOException: class java.awt.dnd.InvalidDnDOperationException:No drop current caught while getting Data
        at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:270)
        at dnd$MyDropTargetListener.drop(dnd.java:69)
        at java.awt.dnd.DropTarget.drop(DropTarget.java:343)
        at sun.awt.windows.WDropTargetContextPeer.processDropMessage(WDropTargetContextPeer.java:941)
        at sun.awt.windows.WDropTargetContextPeer.run(Compiled Code)
        at javax.swing.SystemEventQueueUtilities.processRunnableEvent(Compiled Code)
        at javax.swing.SystemEventQueueUtilities$RunnableTarget.processEvent(Compiled Code)
        at java.awt.Component.dispatchEventImpl(Compiled Code)
        at java.awt.Component.dispatchEvent(Compiled Code)
        at java.awt.EventQueue.dispatchEvent(Compiled Code)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:68)

//
// Simple Drag & Drop Program
//
// Author:  M.Shaw (###@###.###)
// Date:    15 Dec 1998
//

import java.io.IOException;

import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Container;
import java.awt.Component;
import java.awt.Label;
import java.awt.Cursor;
import java.awt.Point;

import java.awt.dnd.*; // about 20 classes/interfaces are used

import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;

import java.awt.event.WindowEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JComponent;
import javax.swing.ImageIcon;
import javax.swing.SwingConstants;

public class dnd extends JFrame
{
    public static void main( String[] args )
    {
        dnd dd = new dnd();
    }

    class MyDropTargetListener implements DropTargetListener
    {
        public void dragEnter(DropTargetDragEvent dtde)
        {
//            System.out.println("MyDropTargetListener.dragEnter");
//            dropOntoMe.setIcon(new ImageIcon("images/openbox.gif"));
        }

        public void dragExit(DropTargetEvent dtde)
        {
//            System.out.println("MyDropTargetListener.dragExit");
//            dropOntoMe.setIcon(new ImageIcon("images/closedbox.gif"));
        }

        public void dragOver(DropTargetDragEvent dtde)
        {
//            System.out.println("MyDropTargetListener.dragOver");
        }

        public void drop(DropTargetDropEvent dtde)
        {
//            System.out.println("MyDropTargetListener.drop");
            if (dtde.isDataFlavorSupported(DataFlavor.stringFlavor))
            {
                try
                {
                    Object transData = dtde.getTransferable().getTransferData(DataFlavor.stringFlavor);
                    if ( transData instanceof String )
                        System.out.println("Dropped a '" + (String) transData + "'!!");
                    dtde.acceptDrop(DnDConstants.ACTION_COPY);
//                    dropOntoMe.setIcon(new ImageIcon("images/box.gif"));
                }
                catch (UnsupportedFlavorException ufe)
                {
//                    System.out.println("trans.getTransferData() threw UnsupportedFlavorException");
                    ufe.printStackTrace();
                    dtde.rejectDrop();
                    dtde.dropComplete(true);
                }
                catch (IOException ioe)
                {
//                    System.out.println("trans.getTransferData() threw IOException");
                    ioe.printStackTrace();
                    dtde.rejectDrop();
                    dtde.dropComplete(false);
                }
            }
            else
            {
                dtde.rejectDrop();
                dtde.dropComplete(false);
            }
        }

        public void dropActionChanged(DropTargetDragEvent dtde)
        {
            //System.out.println("MyDropTargetListener.dropActionChanged");
        }
    }

    class MyDragSourceListener implements DragSourceListener
    {
        public void dragDropEnd(DragSourceDropEvent e)
        {
//            System.out.println("MyDragSourceListener.dragDropEnd");
        }

        public void dragEnter(DragSourceDragEvent e)
        {
//            System.out.println("MyDragSourceListener.dragEnter");
        }

        public void dragExit(DragSourceEvent e)
        {
//            System.out.println("MyDragSourceListener.dragExit");
        }

        public void dragOver(DragSourceDragEvent e)
        {
//            System.out.println("MyDragSourceListener.dragOver");
            if ( e.getDragSourceContext().getCursor().getType() != Cursor.DEFAULT_CURSOR );
              e.getDragSourceContext().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
        }

        public void dropActionChanged(DragSourceDragEvent e)
        {
//            System.out.println("MyDragSourceListener.dropActionChanged");
        }
    }

    class MyDragGestureListener implements DragGestureListener
    {
        public void dragGestureRecognized(DragGestureEvent dge)
        {
//            System.out.println("MyDragGestureListener.dragGestureRecognized");
            MyDragSourceListener dsl = new MyDragSourceListener();
            MyTransferable transfer = new MyTransferable();

            try
            {
                dge.startDrag(new Cursor(Cursor.DEFAULT_CURSOR), transfer, dsl);
            }
            catch (InvalidDnDOperationException e)
            {
                System.err.println("startDrag threw InvalidDndOperationException");
                e.printStackTrace();
            }
        }
    }

    class MyTransferable implements Transferable
    {
        public DataFlavor[] getTransferDataFlavors()
        {
            //System.out.println("MyTransferable.getTransferDataFlavors");
            DataFlavor[] flavors = { DataFlavor.stringFlavor };
            return flavors;
        }

        public boolean isDataFlavorSupported(DataFlavor flavor)
        {
            //System.out.println("MyTransferable.isDataFlavorSupported");
            return (flavor.equals(DataFlavor.stringFlavor));
        }

        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException
        {
            //System.out.println("MyTransferable.getTransferData");
            return new String("dragon");
        }

    }

    class MyActionListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            resetAction();
        }
    }

    public dnd()
    {
        JPanel panel = new JPanel();
        getContentPane().add(panel);
        panel.setLayout(new GridBagLayout());
        dragMe = new JLabel("drag me", /*new ImageIcon("images/duke.gif"),*/ SwingConstants.CENTER);
        dropOntoMe = new JLabel("drop onto me", /*new ImageIcon("images/closedbox.gif"),*/ SwingConstants.CENTER);
//        JButton reset = new JButton("reset");
//    	MyActionListener al = new MyActionListener();
//        reset.addActionListener(al);
        attachWidget(panel, dragMe, 0, 0, 1, 1, 1, 1);
        attachWidget(panel, dropOntoMe, 1, 0, 1, 1, 1, 1);
//        attachWidget(panel, reset, 0, 1, 2, 1, 1, 1);

        DragSource ds = new DragSource();

        MyDragGestureListener dgl = new MyDragGestureListener();
        DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer(dragMe, DnDConstants.ACTION_COPY, dgl);

        MyDropTargetListener dtl = new MyDropTargetListener();
        DropTarget dt = new DropTarget(dropOntoMe, dtl);
        dt.setDefaultActions(DnDConstants.ACTION_COPY);
        dt.setActive(true);
        pack();
        show();
    }

    protected void resetAction()
    {
//        dropOntoMe.setIcon(new ImageIcon("images/closedbox.gif"));
    }

    protected void processWindowEvent (WindowEvent e)
    {
        if (e.getID() == WindowEvent.WINDOW_CLOSING)
            System.exit(0);
        super.processWindowEvent (e);
    }

    static void attachWidget(Container cont, JComponent comp, int x, int y, int w, int h,
                          double weightx, double weighty)
    {
        GridBagLayout gbl = (GridBagLayout) cont.getLayout();
        GridBagConstraints c = new GridBagConstraints();

        c.fill = GridBagConstraints.BOTH;
        c.gridx = x;
        c.gridy = y;
        c.gridwidth = w;
        c.gridheight = h;
        c.weightx = weightx;
        c.weighty = weighty;
        cont.add(comp);
        gbl.setConstraints(comp, c);
    }

    JLabel dragMe;
    JLabel dropOntoMe;
}
(Review ID: 48148) 
======================================================================

                                    

Comments
WORK AROUND



Name: vi73552			Date: 03/04/99


I have tried various workarounds including including using
the clipboard and sockets. So far none are satisfactory.
======================================================================
                                     
2004-06-11
EVALUATION

The situation is even worse in kestrel and merlin. Java crashes as soon as
a drag is initiated.
david.mendenhall@eng 2000-08-03

I am committing this bug to ladybird and merlin-beta, but only the regression
portion of this bug is critical for these releases. Once we are back to the
1.2.2 behavior, this bug should be reevaluated and possibly decommitted.
david.mendenhall@east 2000-08-04


Name: dsR10078			Date: 09/09/2000

###@###.###

The crash which is a regression from kestrel is a duplicate of 4343300.

The rest of the bug is 'not a bug', since there are two bugs in the
test case.

1.DropTargetDropEvent.getTransferable() is invoked before 
  DropTargetDropEvent.acceptDrop()
  
  Javadoc for DropTargetListener.drop() prescribes that
  DropTargetDropEvent.getTransferable() may be invoked 
  only subsequent to DropTargetDropEvent.acceptDrop().

  Failing to do so causes the exception described in the bug report.

2.DropTargetListener.drop() doesn't call DropTargetDropEvent.dropComplete().

  Javadoc for DropTargetListener.drop() prescribes that
  DropTargetDropEvent.dropComplete() must be called at the completion
  of a drop. 

  Failing to do so causes the test case to hang.
  This hang is documented 4187912.

When the test is corrected accordingly dnd operates 
successfully between two jvms.

======================================================================
                                     
2004-06-11



Hardware and Software, Engineered to Work Together