Consider the following code:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.TransferHandler;
import javax.swing.TransferHandler.TransferSupport;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
class Element {
String s;
public Element(String s) {
this.s = s;
}
}
public class DnDTest {
public static void main(String args[]) {
JFrame f = new JFrame("Test");
f.setSize(640, 400);
Container c = f.getContentPane();
c.setLayout(new BorderLayout());
JTree t = new JTree();
t.setDragEnabled(true);
DefaultMutableTreeNode root = new DefaultMutableTreeNode(new Element("root"));
root.add(new DefaultMutableTreeNode(new Element("child")));
t.setModel(new DefaultTreeModel(root));
c.add(t, BorderLayout.WEST);
JPanel p = new JPanel();
c.add(p, BorderLayout.CENTER);
p.setTransferHandler(new TransferHandler("entity") {
@Override
public boolean canImport(TransferSupport support) {
return true;
}
@Override
public boolean importData(TransferHandler.TransferSupport support) {
Transferable t = support.getTransferable();
DataFlavor[] fv = t.getTransferDataFlavors();
Object o;
try {
for (DataFlavor f: fv) {
o = t.getTransferData(f);
System.out.println(f + " => " + o.getClass().getName()+", " + o);
}
} catch (UnsupportedFlavorException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
});
f.setVisible(true);
}
}
When I drag a node from the tree to the right panel, this prints the following output:
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.lang.String] => java.lang.String, <html>
<body>
<ul>
<li>Element@4d405ef7
</ul>
</body>
</html>
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.Reader] => java.io.StringReader, java.io.StringReader@217d12b3
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=unicode] => java.io.ByteArrayInputStream, java.io.ByteArrayInputStream@5c9992b3
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.lang.String] => java.lang.String, Element@4d405ef7
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.Reader] => java.io.StringReader, java.io.StringReader@34715be
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=unicode] => java.io.ByteArrayInputStream, java.io.ByteArrayInputStream@325e55cd
java.awt.datatransfer.DataFlavor[mimetype=application/x-java-jvm-local-objectref;representationclass=java.lang.String] => java.lang.String, Element@4d405ef7
java.awt.datatransfer.DataFlavor[mimetype=application/x-java-serialized-object;representationclass=java.lang.String] => java.lang.String, Element@4d405ef7
So, no matter which DataFlavor
I use, the result is always a String
. What do I need to change to actually get a reference to the Element
instance associated as user object to the tree node?
I did some more digging, and found the solution. Posting for reference: