I am currently experimenting with drag&drop using Java 7 Update 21.
My target operating systems are:
The requirements are:
drag files from the filesystem and drop it to my Java application (making a copy of the file to a temporary directory) -> works for Linux & MacOSX & Windows
drag e-mails from Thunderbird and drop them to my Java application (saving them as complete *.eml file on the filesystem)
The following code works with simple file drops to my application for Windows, MacOSX and Ubuntu. A further requirement is to drop e-mails from Thunderbird to my Java application (the mail is automatically converted to an *.eml file and stored to disk). This also works fine for Windows but I get a "Data Flavor not supported exception" in Ubuntu and MacOSX...
EDIT: I tried it with OpenJDK 7 on Ubuntu, but with that, even normal file drops doesn't work. Only with the JDK version of Oracle.
Does somebody has an idea how to fix / achieve that?
Many thanks in advance!
Here's a simple executeable sample:
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.List;
public class DragDropTest extends javax.swing.JFrame {
public DragDropTest() {
initComponents();
initDragAndDrop();
}
private void initDragAndDrop() {
this.setDropTarget(new DropTarget(){
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
try {
Transferable transfer = dtde.getTransferable();
if(transfer.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
List objects = (List)transfer.getTransferData(DataFlavor.javaFileListFlavor);
for(Object object : objects) {
if(object instanceof File) {
File source = (File)object;
File dest = new File(System.getProperty("user.home")+File.separator+source.getName());
Files.copy(Paths.get(source.getAbsolutePath()), Paths.get(dest.getAbsolutePath()), StandardCopyOption.REPLACE_EXISTING);
System.out.println("File copied from "+source.getAbsolutePath()+" to "+dest.getAbsolutePath());
}
}
} else if(transfer.isDataFlavorSupported(DataFlavor.stringFlavor)) {
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
String type = (String)transfer.getTransferData(DataFlavor.stringFlavor);
System.err.println("Data flavor not supported: "+type);
} else {
System.err.println("Data flavor not supported.");
}
} catch(UnsupportedFlavorException ex) {
System.err.println(ex.getMessage());
} catch(IOException ex) {
System.err.println(ex.getMessage());
} catch(Exception ex) {
System.err.println(ex.getMessage());
} finally {
dtde.dropComplete(true);
}
}
});
}
@SuppressWarnings("unchecked")
private void initComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Drag & Drop");
setResizable(false);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 200, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 200, Short.MAX_VALUE)
);
pack();
}
public static void main(String args[]) {
new DragDropTest().setVisible(true);
}
}
Actually the problem is not in your Java code... It's a bug in ubuntu itself while Ubuntu Unity doesn't support Drag and Drop across two Windows (In your application between Mozilla Thunderbird and Java App). while it's possible to a drag and drop a file from the file system to a window..
To confirm this try to drag a mail file from Thunderbird to a browser windows as Gmail Attachment,,, it will not work.
To keep up with this bug review Bug updates in Ubuntu Bugs Launchpad from: https://bugs.launchpad.net/unity/+bug/995039
Instead of throwing, why not print out what data flavors you get on the transferable, and see if there is one you can use. Something like,
else {
for(DataFlavor f : transfer.getTransferDataFlavors()) {
System.out.println("flavor f:" + f + " type:" + f.getMimeType() + " javaClas:" + f.getDefaultRepresentationClass());
}
}
Given the output of that, there is a good chance you can see how to save it to a file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With