United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4899516 Transferable has no DataFlavors when dragging from Gnome window to Swing
JDK-4899516 : Transferable has no DataFlavors when dragging from Gnome window to Swing

Details
Type:
Bug
Submit Date:
2003-07-31
Status:
Resolved
Updated Date:
2009-12-16
Project Name:
JDK
Resolved Date:
2009-12-16
Component:
client-libs
OS:
linux
Sub-Component:
java.awt
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.2,5.0
Fixed Versions:

Related Reports
Relates:

Sub Tasks

Description
Name: jl125535			Date: 07/31/2003


FULL PRODUCT VERSION :
java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)


FULL OPERATING SYSTEM VERSION : Red Hat Linux 7.2, glibc-
2.2.4-13, kernel=2.4.7-10


A DESCRIPTION OF THE PROBLEM :
When dragging a file or group of files from a Gnome
directory browser window, the DnD Transferables contain
empty DataFlavor arrays and will not coerce their payload
into any flavor at all.

On Windows, same vm version, the Transferable supports
DataFlavor.javaFileListFlavor.  I would expect the Linux
version to do the same.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.Run the given test case.
2.Drag a file from Gnome into the drop target.
3.Drop it.

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected:  The drop method is given a Transferable with
DataFlavor of type DataFlavor.javaFileList.

Actual: The drop method is given a Transferable with no
DataFlavors at all.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
No error messages/exceptions.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.swing.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

/**
 * Displays a window that can accept drops.  It then displays the flavors
 * supported by the drop, and if one of the flavors is
DataFlavor.javaFileListFlavor,
 * iterates the list and displays it's contents.
 *
 * On Windows, dragging files into the window shows the flavors as expected.
On
 * Linux (Red Hat 7.2, Gnome), however, the flavor array is empty.
 */

public class DNDList extends JList
    implements DropTargetListener
{
    DropTarget dropTarget = null;
    

    public DNDList()
    {
        dropTarget = new DropTarget(this, this);
    }

    public void dragEnter(DropTargetDragEvent event)
    {
       event.acceptDrag(DnDConstants.ACTION_MOVE);
    }

    public void dragExit(DropTargetEvent event)
    {}

    public void dragOver(DropTargetDragEvent event)
    {}

    public void drop(DropTargetDropEvent event)
    {
        Transferable transferable = event.getTransferable();
        DefaultListModel model = new DefaultListModel();
        DataFlavor[] flavors = transferable.getTransferDataFlavors();
        
        event.acceptDrop(DnDConstants.ACTION_MOVE);
        
        if (flavors.length == 0)
            model.addElement("Drop contains no flavors!");
        else
            for (int i = 0; i < flavors.length; i++)
                model.addElement(flavors[i]);
        
        if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
        {
            try
            {
                List files = (List) transferable.getTransferData
(DataFlavor.javaFileListFlavor);
                Iterator i = files.iterator();
            
                while (i.hasNext())
                    model.addElement("    " + i.next().toString());
            }
            catch (UnsupportedFlavorException e)
            {
                System.out.println(e.getMessage());
            }
            catch (IOException e)
            {
                System.out.println(e.getMessage());
            }
        }
        
        setModel(model);
    }

    public void dropActionChanged(DropTargetDragEvent event)
    {}
    
    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        
        frame.getContentPane().add(new DNDList());
        frame.setSize(400, 200);
        
        frame.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
        
        frame.setVisible(true);
    }
}
---------- END SOURCE ----------

CUSTOMER WORKAROUND :
No workaround.
(Incident Review ID: 164756) 
======================================================================

                                    

Comments
EVALUATION

Name: agR10216			Date: 08/06/2003



With the build 1.4.2-b28, when dropping a file from the GNOME
directory browser, the following data flavors are available:
DataFlavor.stringFlavor and several data flavors of text/plain
MIME type. So, strictly speaking, I couldn't reproduce the bug
as it's described.

With the build 1.5.0-beta-b10 (after the fix 4859006 [XDnD: Can not
drag and drop from Staroffice to Java Application] was integrated)
several data flavors with text/uri-list are available in addition to
the mentioned flavors.

When dragging a file from the GNOME directory browser,
it provides data in the folliwing native formats:
  x-special/gnome-icon-list
  text/uri-list
  _NETSCAPE_URL
  text/plain
None of them are mapped to DataFlavor.javaFileListFlavor.
(The native format FILE_NAME is mapped to javaFileListFlavor.)
The format text/uri-list is a standard MIME type and data in this
format is known to contain a list of URIs, not merely file names.
The format of text/uri-list resources is specified in the RFC 2483,
section 5. Generally speaking, Java datatransfer subsystem shouldn't
map text/uri-list to javaFileListFlavor, since data of the type
text/uri-list may not be files. Other formats aren't suitable
to be mapped to javaFileListFlavor either.

One could retrieve data for the data flavor
'new DataFlavor("text/uri-list;class=java.lang.String")',
parse the retrieved string and create File(s).

Also could retrieve data for DataFlavor.stringFlavor since it appears
that data in this flavor is the same as in the previous one. (The
GNOME directory browser exports the same data in text/uri-list and
text/plain formats.)

###@###.###  2003-08-06


======================================================================

Name: agR10216			Date: 08/07/2003


Probably it would be convenient if Java datatransfer system mapped the
native format text/uri-list to DataFlavor.javaFileListFlavor, but the
list contained only valid files (non-file URIs excluded).

Also the format text/uri-list might be mapped to some data flavor,
data in that flavor would be a complete list of transferred URIs
(java.net.URI), but introducing and specifying such a flavor is a
change of API that will be allowed only for the next major release.

###@###.###  2003-08-07


======================================================================
                                     
2003-08-07
WORK AROUND

Name: agR10216			Date: 08/07/2003


To get dropped data as a list of files one could use something
like the following in DropTargetListener.drop():

DataFlavor uriListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");

    try {
        if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
            java.util.List data = (java.util.List)
                    transferable.getTransferData(DataFlavor.javaFileListFlavor);
            // the list contains java.io.File(s)
            System.out.println(data);
        } else if (transferable.isDataFlavorSupported(uriListFlavor)) {
            String data = (String)transferable.getTransferData(uriListFlavor);
            System.out.println(textURIListToFileList(data));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

with the method textURIListToFileList() defined like this:

    private static java.util.List textURIListToFileList(String data) {
        java.util.List list = new java.util.ArrayList(1);
        for (java.util.StringTokenizer st = new java.util.StringTokenizer(data, "\r\n");
                st.hasMoreTokens();) {
            String s = st.nextToken();
            if (s.startsWith("#")) {
                // the line is a comment (as per the RFC 2483)
                continue;
            }
            try {
                java.net.URI uri = new java.net.URI(s);
                java.io.File file = new java.io.File(uri);
                list.add(file);
            } catch (java.net.URISyntaxException e) {
                // malformed URI
            } catch (IllegalArgumentException e) {
                // the URI is not a valid 'file:' URI
            }
        }
        return list;
    }

###@###.###  2003-08-07
======================================================================


To enable dropping of files from a Java app to GNOME/KDE desktop and
file browser, export data in the text/uri-list format (refer to 
RFC 2483 for the text/uri-list format).
A file transferable may look like the following:

private static DataFlavor uriListFlavor;
static {
     try {
         uriListFlavor = new 
DataFlavor("text/uri-list;class=java.lang.String");
     } catch (ClassNotFoundException e) { // can't happen
         e.printStackTrace();
     }
}
 
private static DataFlavor[] FLAVORS = new DataFlavor[] { 
DataFlavor.javaFileListFlavor, uriListFlavor };
 
 
public Object getTransferData(DataFlavor flavor) throws 
UnsupportedFlavorException, java.io.IOException {
     if (flavor.equals(DataFlavor.javaFileListFlavor)) {
         java.util.List data = new java.util.ArrayList();
         java.io.File file = new java.io.File("file.txt");
         data.add(file);
         return data;
     } else if (flavor.equals(uriListFlavor)) {
         java.io.File file = new java.io.File("file.txt");
         // refer to RFC 2483 for the text/uri-list format
         String data = file.toURI() + "\r\n";
         return data;
      } else {
         throw new UnsupportedFlavorException(flavor);
     }
}
 
public DataFlavor[] getTransferDataFlavors(){
     return FLAVORS.clone();
}
 
public boolean isDataFlavorSupported(DataFlavor flavor){
     for (int i = 0; i < FLAVORS.length; i++) {
         if (flavor.equals(FLAVORS[i])) {
             return true;
         }
     }
     return false;
}
                                     
2004-09-17
EVALUATION

http://www.javadesktop.org/forums/thread.jspa?messageID=128000
                                     
2005-12-05
EVALUATION

Open discussion of the issue:
https://bugs.openjdk.java.net/show_bug.cgi?id=100041
                                     
2009-04-14



Hardware and Software, Engineered to Work Together