<AWT Dev> 4808793: Allow initiation of drags without local data

Damjan Jovanovic damjan.jov at gmail.com
Wed Dec 2 07:28:44 PST 2009


Is anybody working on this bug (http://bugs.sun.com/view_bug.do?bug_id=4808793)?

If not I'd like to have a go at it. My idea is described below.

java.awt.datatransfer.DataFlavor.javaFileListFlavor has drop target
pull semantics, with the drop target being responsible for the
operation on the files. It needs the files to already exist. It's
essentially a "take these files and use them" action. For example, if
you drag files into a Java SVN client, the SVN client could check them
in. These semantics work when the drop target is not the local

But these semantics are exactly the opposite of what's needed when the
files in the drag source are not actual files from the local
filesystem - for example they are files in an FTP server or even
virtual files that don't exist yet. For this we need drag source push
semantics, with the drop target either telling the drag source where
to save the files, or using some sort of protocol to move the file
contents from the drag source to wherever they are to be saved or

Windows, X11 and MacOS all support this latter option, and while it is
a less commonly used file drag scenario, some important applications
require it (eg. Microsoft Outlook) and others support it among other
possible formats (eg. Windows Explorer, GIMP, File Roller). The bug
has been open since early 2003 and has 60 votes; the drag from
Microsoft Outlook to Java bug
(http://bugs.sun.com/view_bug.do?bug_id=6242241) which relies on this
bug has another 20 votes.

this. Basically files are presented using their contents, in the form
of IStream, IStorage or HGLOBAL, with additional data describing the
file name and properties

OS X has "promise data flavors"
The drag source supplies a promise instead of data, and a callback
that's invoked to supply the data. When the callback is called, it can
get a URL where the files should be saved.

X11 has the X direct save protocol
(http://www.freedesktop.org/wiki/Specifications/XDS), which seems to
be a mixture of the Windows and OS X ways. The emphasis in the
protocol is on saving a file, rather than transferring a list of
files. First the drop target gives the drag source a URL where to save
the file(s), just like OS X would. If the drag source cannot access
that URL or doesn't have permission, it reports this to the drop
target, and the drop target then falls back to requesting the file
contents as application/octet-stream - similar to the Windows way, but
it only works for one file.

Obviously there are big differences on these platforms that AWT has to
unify. Here is a proposal of how.

Drop target
We add a new DataFlavor, called FileDropReferralFlavor. When the drop
target asks for this flavor, it gets back an object called
FileDropReferral, and must call a "public void setFileDropLocation(URL
location)" method to tell the drag source where it should save the
files. The file transfer proceeds asynchronously, and potentially
within the JVM (ie. the application shouldn't exit if it has
outstanding transfers). After the transfer is complete, some event to
that effect is sent to the drop application's EDT, maybe to a listener
registered with the FileDropReferral.

Drag source
The drag source uses a different DataFlavor to provide its files as
streams, say AsyncFileStreamsFlavor. After the drop it provides an
enumeration that can be used to lazy open InputStream objects, and
some kind of header at least naming each stream.

On all platforms, when Java is the drag source it spawns a separate
thread where possible, and writes the streams into the drop target or
URL. When Java is the drop target, on Windows, it spawns a separate
thread where possible and reads in the streams and saves them to the
target URL that the drop target set, while on X11 and MacOS it just
provides the target URL to the drag source and lets the drag source do
the saving.

These interfaces are unintuitive, asymmetric and ugly. But then again
desktops in different operating systems have given file transfers
little real thought so there isn't much better we can do now, and it's
still vastly uglier to do these in native code (using COM or low-level
X11 - yuck!) than in Java. Also this is an advanced DataFlavor, which
should be used by a minority of applications, and only in special
cases where javaFileListFlavor doesn't fit.

Finally, GTK+ still doesn't even have an API for this, SWT is
struggling and only works on Windows, and even Microsoft's .NET
doesn't support this
(http://www.pcreview.co.uk/forums/thread-1854594.php) so this is a
real opportunity for Java+AWT/Swing to be a shining example and lead
the way.

Any thoughts before I start hacking?


More information about the awt-dev mailing list