JDK-4808793 : Allow initiation of drags without local data
  • Type: Enhancement
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 5.0,6,6u10
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS:
    windows_2000,windows_xp,windows_vista windows_2000,windows_xp,windows_vista
  • CPU: x86
  • Submitted: 2003-01-27
  • Updated: 2009-07-11
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Name: jl125535			Date: 01/27/2003

java version "1.4.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)

Microsoft Windows 2000 [Version 5.00.2195]

The current Drag and Drop specification requires that the
data for a drag operation be produced locally before the
drag operation.  For dynamically produced data (e.g.,
dragging a server-based file), the data is not available
and would be prohibitively expensive to create locally.

The desired behavior is a slightly modified drag and drop
protocol.  The first change would be to let the DragSource
provide only the DataFlavor objects that can be produced
for this drag operation.  The second change would be to add
a generic callback function to identify to the application
that the drop operation has succeeded and that the promised
DataFlavor must now be produced.

This limitation is critical to anyone needing deferred data
callbacks in a native application trying to port to JAVA.
An example of a potential drag and drop scenario can be
found under the SWT, at

1. Try to produce a drag operation without the data in

This bug can be reproduced always.
(Review ID: 153350) 

SUGGESTED FIX See attached patch from OpenJDK bugzilla.

PUBLIC COMMENTS Adding comments from http://bugs.openjdk.java.net/show_bug.cgi?id=100124 Description From Damjan Jovanovic 2009-12-14 11:55:25 PDT Created an attachment (id=171) [details] Patch for drag source push-model file transfers This addresses these 2 bugs with a current total of 81 votes: http://bugs.sun.com/view_bug.do?bug_id=4808793 http://bugs.sun.com/view_bug.do?bug_id=6242241 Start of email thread on awt-dev: http://mail.openjdk.java.net/pipermail/awt-dev/2009-December/001043.html Basically this patch adds support for the X Direct Save protocol on X11, and the CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR formats on Windows, and allows them to be used in Java to do drag source push-model style file transfers. The ideas are all described in the above email. It's been tested with Nautilus and File Roller on Linux, Windows Explorer and Windows Mail on Windows. All work. Known outstanding problems: 1. Copy and paste of the new formats not tested, and probably broken on X11. 2. Windows drag from one Java app to another Java app -> exception in drop target (format ambiguity problem?). 3. URL handling is messy. 4. Do we want/need both new DataFlavors? One could do. 5. Wrong atoms used for actions on X11 (but the same mistake is consistently made in all GTK apps using X Direct Save :-). Test with ROX apps that use the right atoms. 6. Better text charset support on X11 (currently it's ignored). 7. Should try to support asynchronous transfers on Windows, and probably on X11 too, so the EDT doesn't block for long. SWT has a rough patch at https://bugs.eclipse.org/bugs/show_bug.cgi?id=196176 for Windows. 8. Needs jtreg tests. 9. Test with a security manager: might need AccessController.doPrivileged() blocks in X11. 10. Are the public interfaces suitable for implementing this on MacOS? Comment #1 From Damjan Jovanovic 2009-12-14 12:00:32 PDT Added sunbug to whiteboard. Comment #2 From Tim Bell 2012-07-06 17:20:46 PDT Closing. This is SUNBUG 4808793 "Allow initiation of drags without local data"

EVALUATION Name: dsR10078 Date: 01/31/2003 To initiate a drag operation, it is sufficient to provide any instance of Transferable. It is possible to implement Transferable interface so that it doesn't have a local copy of the data, but retrieves the data from a remote source by request. For example, if the source needs to support a drag operation with the contents of a specific URL as a drop data a possible Transferable implementation would be as follows: ------------------------------------------------------------------------------- public class URLContentsTransferable implements Transferable { private final URL url; private final DataFlavor flavor = new DataFlavor("mime/type; class=java.io.InputStream", "URL contents"); public URLContentsTransferable(URL url) { this.url = url; } public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[] { flavor }; } public boolean isDataFlavorSupported(DataFlavor df) { return flavor.equals(df); } public Object getTransferData(DataFlavor df) throws UnsupportedFlavorException, IOException { if (!isDataFlavorSupported(df)) { throw new UnsupportedFlavorException(df); } return url.openStream(); } } ------------------------------------------------------------------------------- Note that this implementation doesn't attempt to read the contents of an URL or open a connection until the data is requested. An alternative solution is to implement drag source and drop target so that they transfer only a link to the remote data (URL in the example), so that the source doesn't even need to open a connection and the target is free to retrieve any data using the transferred link. Please let us know if either of the two approaches is applicable in your scenario. ###@###.### 2003-01-31 ====================================================================== It seems that the example [given by the submitter in a subsequent email] assumes that the files must be created/retrieved before the drag operation starts. This assumption is incorrect. You don't need to create File objects until the transfer data is actually requested by the drop target. Here is the modified example that demonstrates the ability to delay the actual file creation/retrieval: ----------------------------------------------------------------------------- import java.awt.datatransfer.Transferable; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceListener; import java.awt.dnd.DragSourceAdapter; import java.awt.FlowLayout; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; import java.io.IOException; import java.io.File; import java.util.List; import java.util.ArrayList; import javax.swing.JFrame; import javax.swing.JLabel; /** * * @author mmacaluso */ public class TestDragJFrame extends JFrame { public static class FileListContentsTransferable implements Transferable { public static final DataFlavor DATAFLAVOR = DataFlavor.javaFileListFlavor; public static final DataFlavor[] DATAFLAVORS = new DataFlavor[] { DataFlavor.javaFileListFlavor }; private Object[] m_FileHandles = null; private List m_FileList = null; public FileListContentsTransferable(final File aFile) { m_FileList = new ArrayList(1); m_FileList.add(aFile); } public FileListContentsTransferable(final File[] aFileArray) { m_FileList = new ArrayList(aFileArray.length); for (int i = 0; i < aFileArray.length; i++) { File aFile = aFileArray[i]; m_FileList.add(aFile); } } public FileListContentsTransferable(final Object[] aFileHandlesArray) { m_FileHandles = (Object[])aFileHandlesArray.clone(); } public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { if (!isDataFlavorSupported(flavor)) { throw new UnsupportedFlavorException(flavor); } if (m_FileList == null && m_FileHandles != null) { m_FileList = new ArrayList(m_FileHandles.length); for (int i = 0; i < m_FileHandles.length; i++) { File aFile = new File(m_FileHandles[i].toString()); if (!aFile.exists()) { aFile.createNewFile(); } m_FileList.add(aFile); } } System.out.println("FileContentsTransferable->getTransferData(" + flavor + ")"); return m_FileList; } public DataFlavor[] getTransferDataFlavors() { return DATAFLAVORS; } public boolean isDataFlavorSupported(DataFlavor flavor) { return DATAFLAVOR.equals(flavor); } } private JLabel m_DragLabel; private Object[] m_RemoteFileHandles = null; FileListContentsTransferable m_FileListContentsTransferable; public TestDragJFrame() { initComponents(); try { // While this example is trivial, imagine that these Strings are keys used to pull // filedata from a remote database. Or it could be a "token" used call into via a // proprietary api to get the file. The main point is that we do not have the // file locally, and we can not create a URL of File reference to it. m_RemoteFileHandles = new Object[] { new String("HelloWorld1.txt"), new String("HelloWorld2.txt") }; m_FileListContentsTransferable = new FileListContentsTransferable(m_RemoteFileHandles); DragGestureListener aDragGestureListener = new DragGestureListener() { public void dragGestureRecognized(DragGestureEvent dge) { dge.startDrag(DragSource.DefaultCopyDrop, m_FileListContentsTransferable); } }; DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(m_DragLabel, DnDConstants.ACTION_COPY, aDragGestureListener); } catch (Exception e) { } } private void initComponents() { m_DragLabel = new JLabel(); getContentPane().setLayout(new FlowLayout()); addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } } ); m_DragLabel.setText("Drag Me to the file system"); getContentPane().add(m_DragLabel); pack(); } /** * @param args the command line arguments */ public static void main(String args[]) { new TestDragJFrame().show(); } } ----------------------------------------------------------------------------- So it seems that this problem can be resolved with the existing API. ###@###.### 2003-05-07 ====================================================================== Please provide more information to justify the need for the enhancement. ###@###.### 2003-05-07 ====================================================================== Name: agR10216 Date: 03/31/2004 Useful discussions on this ussue: http://www.javadesktop.org/forums/thread.jspa?threadID=1883 http://www.javadesktop.org/forums/thread.jspa?messageID=85578 ###@###.### 2005-06-03 10:34:38 GMT

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mustang