JTree DnD

Hi all,
I have a Jtree with Drag & drop (1.4 model). It is set up so you can only drag leaves but you can currently drop leaves to leaves. What I want to do is only drop leaves to non-leaves; but can't work out how how to do this.
canImport(JComponent comp, DataFlavor[] transferFlavors) only gets called once for the table not each time the drop moves over a different nodes
Anyone any clues on how the functionality I want can be accomplished?

I have exactly the same problem. Leaning toward your solution (4) of having dummy modes. Did you eventually get a good solution, and if so, what?
Lindsay

Similar Messages

  • How do show JTree DnD drop location with custom TreeRenderer?

    I am adding DnD support to a JTree with a custom renderer.
    With the custom renderer I am losing the display of drop location on the tree.
    Is there a method to determine if the passed in node object in the getTreeCellRendererComponent is currently a drop location?
    I can tell if the node is selected, but not if a DnD is in action on the tree.
    Thanks,
    Chris

    Is there a method to determine if the passed in node object in the getTreeCellRendererComponent is currently a drop location?
    I can tell if the node is selected, but not if a DnD is in action on the tree.If you are using Java 1.6 you should be able to do something along these lines:Install a TransferHandler on your tree, and override the method canImport() that takes a TransferHandler.TransferSupport as input argument. That method is called repeatedly during the drag process.
    In that method, ask the passed in TransferSupport for the current drop location, by calling getDropLocation(). For a JTree that will return a JTree.DropLocation, which in turn has methods for finding out which node is the current drop target. Store that node in a variable that your renderer can access.

  • JTree DnD, disable clipboard

    We have a JTree which contains custom nodes. We have enabled inter-tree Drag and Drop on the tree (Java 6 only. For java 5, we disable it), which works wonderfully, although in the example that you see below, it's only partially enabled. These nodes contain references to data (in the example, this data is represented via the Death class).
    The problem, though, is that the clipboard appears to be enabled on this tree. In our case, it does not make sense to allow the clipboard, and in fact hinders the usefulness of our tree, because the shortcut keys (in particular, Shift-Delete) throw exceptions about the data not being serializable. We have plans to map Shift-Delete to something else, and would like to disable the clipboard, so that any other shortcuts also do not interfere with the tree's functioning.
    So basically our question is "How do we disable the clipboard on our JTree?"
    The code below is an example that demonstrates the problem. Our project is very large, so of course I'm not going to include the full thing, but this should be enough to give you an idea of the general layout of our tree, as well as the problem. When you run it, you will see a very basic tree with a node selected. You then press Shift-Delete and you will get a NotSerializableException because it's trying to serialize the node to the clipboard.
    Notice, I have only tested this on Windows. It is most likely OS dependent and Look and Feel dependent due to the shortcut keys.
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.Transferable;
    import java.awt.datatransfer.UnsupportedFlavorException;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JTree;
    import javax.swing.TransferHandler;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.TreePath;
    public class ResNode extends DefaultMutableTreeNode implements Transferable
         private static final long serialVersionUID = 1L;
         private static final DataFlavor NODE_FLAVOR = new DataFlavor(ResNode.class,"Node");
         private static final DataFlavor[] flavors = { NODE_FLAVOR };
         public Death death; //used in another module
         public ResNode(String name)
              super(name);
              death = new Death();
         //Truncated for the purposes of this example
         public class Death
         public DataFlavor[] getTransferDataFlavors()
              return flavors;
         public boolean isDataFlavorSupported(DataFlavor flavor)
              return flavor == NODE_FLAVOR;
         public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException
              if (flavor != NODE_FLAVOR) throw new UnsupportedFlavorException(flavor);
              return this;
         public static void main(String[] args)
              ResNode root = new ResNode("Root");
              ResNode node = new ResNode("Node");
              root.add(node);
              JTree tree = new JTree(root);
              tree.setSelectionPath(new TreePath(node.getPath()));
              tree.setTransferHandler(new TransferHandler()
                        private static final long serialVersionUID = 1L;
                        protected Transferable createTransferable(JComponent c)
                             return (ResNode) ((JTree) c).getLastSelectedPathComponent();
                        public int getSourceActions(JComponent c)
                             return MOVE;
              JFrame frame = new JFrame("Test");
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.add(tree);
              frame.pack();
              frame.setLocationRelativeTo(null);
              frame.setVisible(true);
         }

    We have a JTree which contains custom nodes. We have enabled inter-tree Drag and Drop on the tree (Java 6 only. For java 5, we disable it), which works wonderfully, although in the example that you see below, it's only partially enabled. These nodes contain references to data (in the example, this data is represented via the Death class).
    The problem, though, is that the clipboard appears to be enabled on this tree. In our case, it does not make sense to allow the clipboard, and in fact hinders the usefulness of our tree, because the shortcut keys (in particular, Shift-Delete) throw exceptions about the data not being serializable. We have plans to map Shift-Delete to something else, and would like to disable the clipboard, so that any other shortcuts also do not interfere with the tree's functioning.
    So basically our question is "How do we disable the clipboard on our JTree?"
    The code below is an example that demonstrates the problem. Our project is very large, so of course I'm not going to include the full thing, but this should be enough to give you an idea of the general layout of our tree, as well as the problem. When you run it, you will see a very basic tree with a node selected. You then press Shift-Delete and you will get a NotSerializableException because it's trying to serialize the node to the clipboard.
    Notice, I have only tested this on Windows. It is most likely OS dependent and Look and Feel dependent due to the shortcut keys.
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.Transferable;
    import java.awt.datatransfer.UnsupportedFlavorException;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JTree;
    import javax.swing.TransferHandler;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.TreePath;
    public class ResNode extends DefaultMutableTreeNode implements Transferable
         private static final long serialVersionUID = 1L;
         private static final DataFlavor NODE_FLAVOR = new DataFlavor(ResNode.class,"Node");
         private static final DataFlavor[] flavors = { NODE_FLAVOR };
         public Death death; //used in another module
         public ResNode(String name)
              super(name);
              death = new Death();
         //Truncated for the purposes of this example
         public class Death
         public DataFlavor[] getTransferDataFlavors()
              return flavors;
         public boolean isDataFlavorSupported(DataFlavor flavor)
              return flavor == NODE_FLAVOR;
         public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException
              if (flavor != NODE_FLAVOR) throw new UnsupportedFlavorException(flavor);
              return this;
         public static void main(String[] args)
              ResNode root = new ResNode("Root");
              ResNode node = new ResNode("Node");
              root.add(node);
              JTree tree = new JTree(root);
              tree.setSelectionPath(new TreePath(node.getPath()));
              tree.setTransferHandler(new TransferHandler()
                        private static final long serialVersionUID = 1L;
                        protected Transferable createTransferable(JComponent c)
                             return (ResNode) ((JTree) c).getLastSelectedPathComponent();
                        public int getSourceActions(JComponent c)
                             return MOVE;
              JFrame frame = new JFrame("Test");
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.add(tree);
              frame.pack();
              frame.setLocationRelativeTo(null);
              frame.setVisible(true);
         }

  • Need simple JTree DnD support

    Hi,
    I'm developing an app where multiple components are displayed in a central part of a BorderLayout. A JTree with a node per component is shown on the EAST part of the layout. This is basically intended to be an outline (a-la Eclipse) of the content in the central part. I now want to be able to reorganize the components (which are stacked vertically) by dragging and dropping the corresponding outline nodes.
    However, I don't want swing to actually modify the tree. I only want to know which node is being dragged, where it's dropped, and the appropriate visual feedback. Having that, I modify the panel containing the components, and my JTree, which is registered as a listener, reacts to that adjusting itself. In particular, I don't want to have to make the user object serializable.
    Any suggestion on how to achieve this?

    See this well commented example (btw: "serializable" isn't needed):
    http://www.java-forum.org/de/userfiles/user3690/TreeDnd.jar
    (source code in jar)
    The physical transfer is done within the class "NodeMoveTransferHandler".
    Each node is moved to the new parent node in "addNodes"
    respectively inserted between two nodes in "insertNodes".
    Within each of these two methods, the method-calls "removeNodeFromParent"
    and "insertNodeInto" are responsible for the transfer.
    Thus, you can easily replace them according to your needs.

  • JTree DnD Problem - public void drop(DropTargetDropEvent e)

    This method won't executed, can someone give me some ideas what the problem could be.
    After the following (simplified) method is called nothing happens.
    public void dragOver(DropTargetDragEvent e)
    e.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE );
    How usually the void drop(DropTargetDropEvent e) method gets executetd ?
    thanks for answers...

    Ensure that you have initialised a DropTarget
    and implemented the DropTargetListener

  • DnD from JTree to JTable

    Hi guys,
    It seems JTree DnD support is a quit difficult feature to implement of all swing components.
    I'm writing an application in which I have a JTree structure representing the file system of user machine and another JTable component at the right.
    I want to be able to drag files nodes from left JTree to right JTable.
    I would appreciate a lot if someone share with me some source code examples for this functionality.
    can someone post some basic java code to get me started or point me to some web resource discussing this feature?
    thanks much.

    http://forum.java.sun.com/thread.jspa?threadID=296255Thank you. I already looked at this thread but it's not what i'm looking for: it shows dnd from a JTree to another JTree..however i need to implement dnd from JTree to JTable.
    Is there some basic example on how to do that ?
    thanks.

  • DnD exception when Draging a component

    Hi,
    I am trying to implement a Drag n Drop feature for our application and always get the following exception, when drag a node from JTree and try to drop it another instance of the same JTree. this happens as soon as I call the startDrag method from the TransferHandler.
    java.awt.dnd.InvalidDnDOperationException: The operation requested cannot be performed by the DnD system since it is not in the appropriate state
         at sun.awt.dnd.SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(SunDropTargetContextPeer.java:105)
         at sun.awt.windows.WDragSourceContextPeer.startDrag(WDragSourceContextPeer.java:82)
         at java.awt.dnd.DragSource.startDrag(DragSource.java:260)
         at java.awt.dnd.DragSource.startDrag(DragSource.java:326)
    For some other reasons, I am limited to using JDK 1.3.1 on NT.
    I understand this a very uncommon problem but I get this exception every time.
    Anybody have any ideas as what is wrong or whats the workaround? Any help in this matter would be highly appreciated.
    Thanks,
    N.

    Check out the link shown below:
    http://forum.java.sun.com/thread.jsp?forum=57&thread=296255
    If that doesn't answer your question, search the forum with "deudeu +dnd" and you'll find a lot of posts by this person on JTree DnD.
    ;o)
    V.V.

  • Autoscroll behavior during DnD in JTree, 1.4 vs 1.6

    The following code compiles under both Java 1.4 and Java 1.6. I'm wondering if anyone knows why the following actions cause different behaviors between the two versions:
    1. When the frame opens, you should see a fully-expanded tree (which, because of the small size, causes a vertical scrollbar to appear).
    2. Make a drag-and-drop gesture on the first child node ("blue"), and attempt to cause the tree to scroll down so you can drop it on the last parent node ("food").
    Under 1.6, the tree scrolls nicely as you hold the DnD gesture.
    Under 1.4, the tree does not scroll. I had some hope JTree.setAutoscrolls(true) would help, but it did not.
    Any suggestions how to get 1.4 to behave the way 1.6 does?
    Thanks for your time.
    import javax.swing.*;
    import javax.swing.tree.DefaultTreeModel;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.TreePath;
    import javax.swing.tree.TreeNode;
    import java.awt.*;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.Transferable;
    import java.awt.datatransfer.UnsupportedFlavorException;
    import java.io.IOException;
    import java.util.Enumeration;
    public class AutoScroll14 extends JFrame {
        public static void main(String[] args) {
            new AutoScroll14();
        public AutoScroll14() throws HeadlessException {
            super("AutoScroll 1.4");
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            JTree tree = new JTree();
            tree.setDragEnabled(true);
            tree.setTransferHandler(new MyTransferHandler());
            expand(tree, tree.getPathForRow(0));
            JScrollPane sp = new JScrollPane(tree);
            sp.setPreferredSize(new Dimension(300, 200));
            Container content = getContentPane();
            content.setLayout(new BorderLayout());
            content.add(sp, BorderLayout.CENTER);
            pack();
            setVisible(true);
        private void expand(JTree tree, TreePath path) {
            TreeNode node = (TreeNode) path.getLastPathComponent();
            for (Enumeration e = node.children(); e.hasMoreElements();) {
                TreeNode n = (TreeNode) e.nextElement();
                TreePath newPath = path.pathByAddingChild(n);
                expand(tree, newPath);
            tree.expandPath(path);
        private class MyTransferHandler extends TransferHandler {
            private DataFlavor localStringFlavor;
            private String localStringType = DataFlavor.javaJVMLocalObjectMimeType + ";class=java.lang.String";
            private MyTransferHandler() {
                try {
                    localStringFlavor = new DataFlavor(localStringType);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
            public boolean importData(JComponent comp, Transferable t) {
                if (!canImport(comp, t.getTransferDataFlavors())) {
                    return false;
                String data = null;
                try {
                    if (hasLocalStringFlavor(t.getTransferDataFlavors())) {
                        data = (String) t.getTransferData(localStringFlavor);
                    } else {
                        return false;
                } catch (UnsupportedFlavorException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                String location = null;
                if (comp instanceof JTree) {
                    location = ((JTree) comp).getSelectionPath().toString();
                System.out.println("Dropping [" + data + "] on location [" + location + "]");
                return true;
            private boolean hasLocalStringFlavor(DataFlavor[] flavors) {
                if (localStringFlavor == null) {
                    return false;
                for (int i = 0; i < flavors.length; i++) {
                    if (flavors.equals(localStringFlavor)) {
    return true;
    return false;
    public boolean canImport(JComponent comp, DataFlavor[] flavors) {
    return hasLocalStringFlavor(flavors);
    protected Transferable createTransferable(JComponent c) {
    if (c instanceof JTree) {
    String toTransfer = ((JTree) c).getSelectionPath().toString();
    System.out.println("Creating transferable [" + toTransfer + "]");
    return new StringTransferable(toTransfer);
    System.out.println("Could not create transferable");
    return null;
    public int getSourceActions(JComponent c) {
    return COPY_OR_MOVE;
    private class StringTransferable implements Transferable {
    private String data;
    private StringTransferable(String data) {
    this.data = data;
    public DataFlavor[] getTransferDataFlavors() {
    return new DataFlavor[] { localStringFlavor };
    public boolean isDataFlavorSupported(DataFlavor flavor) {
    return localStringFlavor.equals(flavor);
    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
    if (!isDataFlavorSupported(flavor)) {
    throw new UnsupportedFlavorException(flavor);
    return data;

    I added the class "TreeDropTarget".
    "TreeDropTarget" extends the class "DropTarget", which implements the interface "DropTargetListener".
    DropTargetListener has a few methods, that are called automatically by Swing during drag operation
    (dragOver, dragExit, drop). So we can implement "autoscroll", as well as "automatic node expansion".
    With "automatic node expansion", a collapsed node will be expanded,
    so that its children become visible and we can do a drop on them:
    package demo;
    * AutoScroll.java
    * source level 1.4
    import javax.swing.*;
    import javax.swing.tree.*;
    import java.awt.*;
    import java.awt.datatransfer.*;
    import java.awt.dnd.*;
    import java.io.*;
    import java.util.*;
    public class AutoScroll extends JFrame {
        public static void main(String[] args) {
            new AutoScroll();
        public AutoScroll() throws HeadlessException {
            super("AutoScroll " + System.getProperty("java.version"));
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            JTree tree = new JTree();
            tree.setDragEnabled(true);
            tree.setTransferHandler(new MyTransferHandler());
            tree.setDropTarget(new TreeDropTarget());//<----------------------
            expand(tree, tree.getPathForRow(0));
            JScrollPane sp = new JScrollPane(tree);
            sp.setPreferredSize(new Dimension(300, 200));
            Container content = getContentPane();
            content.setLayout(new BorderLayout());
            content.add(sp, BorderLayout.CENTER);
            pack();
            setVisible(true);
        private void expand(JTree tree, TreePath path) {
            TreeNode node = (TreeNode) path.getLastPathComponent();
            for (Enumeration e = node.children(); e.hasMoreElements();) {
                TreeNode n = (TreeNode) e.nextElement();
                TreePath newPath = path.pathByAddingChild(n);
                expand(tree, newPath);
            tree.expandPath(path);
        private class MyTransferHandler extends TransferHandler {
            private DataFlavor localStringFlavor;
            private String localStringType = DataFlavor.javaJVMLocalObjectMimeType + ";class=java.lang.String";
            private AutoScroll.MyTransferHandler.StringTransferable transferable;
            private MyTransferHandler() {
                try {
                    localStringFlavor = new DataFlavor(localStringType);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
            protected void exportDone(JComponent comp, Transferable t, int action) {
                if (t == null) {
                    t = transferable;
                if (!canImport(comp, t.getTransferDataFlavors())) {
                    return;
                String data = null;
                try {
                    if (hasLocalStringFlavor(t.getTransferDataFlavors())) {
                        data = (String) t.getTransferData(localStringFlavor);
                    } else {
                        return;
                } catch (UnsupportedFlavorException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                String location = null;
                if (comp instanceof JTree) {
                    location = ((JTree) comp).getSelectionPath().toString();
                System.out.println("Dropping [" + data + "] on location [" + location + "]");
                return;
            private boolean hasLocalStringFlavor(DataFlavor[] flavors) {
                if (localStringFlavor == null) {
                    return false;
                for (int i = 0; i < flavors.length; i++) {
                    if (flavors.equals(localStringFlavor)) {
    return true;
    return false;
    public boolean canImport(JComponent comp, DataFlavor[] flavors) {
    return hasLocalStringFlavor(flavors);
    protected Transferable createTransferable(JComponent c) {
    if (c instanceof JTree) {
    String toTransfer = ((JTree) c).getSelectionPath().toString();
    System.out.println("Creating transferable [" + toTransfer + "]");
    transferable = new StringTransferable(toTransfer);
    return transferable;
    System.out.println("Could not create transferable");
    return null;
    public int getSourceActions(JComponent c) {
    return COPY_OR_MOVE;
    private class StringTransferable implements Transferable {
    private String data;
    private StringTransferable(String data) {
    this.data = data;
    public DataFlavor[] getTransferDataFlavors() {
    return new DataFlavor[]{localStringFlavor};
    public boolean isDataFlavorSupported(DataFlavor flavor) {
    return localStringFlavor.equals(flavor);
    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
    if (!isDataFlavorSupported(flavor)) {
    throw new UnsupportedFlavorException(flavor);
    return data;
    class TreeDropTarget extends DropTarget {
    public TreeDropTarget() {
    super();
    public void dragOver(DropTargetDragEvent dtde) {
    JTree tree = (JTree) dtde.getDropTargetContext().getComponent();
    Point loc = dtde.getLocation();
    updateDragMark(tree, loc);
    autoscroll(tree, loc);
    super.dragOver(dtde);
    private Insets getAutoscrollInsets() {
    return autoscrollInsets;
    private void autoscroll(JTree tree, Point cursorLocation) {
    Insets insets = getAutoscrollInsets();
    Rectangle outer = tree.getVisibleRect();
    Rectangle inner = new Rectangle(
    outer.x + insets.left,
    outer.y + insets.top,
    outer.width - (insets.left + insets.right),
    outer.height - (insets.top + insets.bottom));
    if (!inner.contains(cursorLocation)) {
    Rectangle scrollRect = new Rectangle(
    cursorLocation.x - insets.left,
    cursorLocation.y - insets.top,
    insets.left + insets.right,
    insets.top + insets.bottom);
    tree.scrollRectToVisible(scrollRect);
    public void updateDragMark(JTree tree, Point location) {
    int row = tree.getRowForPath(tree.getClosestPathForLocation(location.x, location.y));
    TreePath path = tree.getPathForRow(row);
    if (path != null) {
    markNode(tree, location);
    private void markNode(JTree tree, Point location) {
    TreePath path = tree.getClosestPathForLocation(location.x, location.y);
    if (path != null) {
    if (lastRowBounds != null) {
    Graphics g = tree.getGraphics();
    g.setColor(Color.white);
    g.drawLine(lastRowBounds.x, lastRowBounds.y,
    lastRowBounds.x + lastRowBounds.width, lastRowBounds.y);
    tree.setSelectionPath(path);
    tree.expandPath(path);
    private Rectangle lastRowBounds;
    private Insets autoscrollInsets = new Insets(20, 20, 20, 20);

  • Does JTree support multiple DnD?

    I'm working on an applet which displays a JTree tree, which has to support multiple DnD.
    i mean, user has to be capable of selecting several nodes at a time and drag all of them, dropping them into a target.
    Though i have asked about it, and somebody told me about it, the solution was with a JFrame, and all the examples which work and i've read, arre with JFrame.
    So i guess that maybe JTree does not support multiple DnD, and moreover, there is a website
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4165577
    in which someone says that, in fact, JTree does not support it. But it's and old page, so i want to know if at present, Jtree still has this debug.
    Thanks in advance!

    http://www.java-forum.org/de/viewtopic.php?p=139820#139820

  • DnD, JTree and inter-node placement

    Hi, there.
    Drag'n'Drop with JTrees has been discussed at length in this list. I have a DnD-capable application, and the user sees the nodes affected by the drag position as selected, so he knows where the drop will perform.
    Now I want to drop not only on other nodes, but also inbetween. You may imagine there is a red bar shown as soon as the drag is between tree nodes, and the result will be a new node inserted at exactly this position.
    Any ideas how to implement that?
    Hiran

    Still on the problem. Have some thoughts. But absolutely no idea whether this may work at all:
    Upon dragover, the cell affected is selected. That means I query getClosestPathForLocation() and then call setSelectionPath with the result. This works for nodes.
    Now I need to detect the inter-node placement. So the row must get calculated by myself, and if necessary, an extra node will be inserted into the tree. This extra node is rendered just as slim red line, so the user knows now he drops between nodes. Whatever happens now (drop performed, mouse moved elsewhere), the red line will be removed first.
    What do you think?

  • DND in JTrees

    Is there anyway that we can prevent DND on a specific Node of a JTree?
    Thanks,
    ananth

    Please read my first message in the start of this thread DnD are not always turned off. Meaning if a user selects a red category, the CSF device is set to DnD. If the user sets the category to "Available" the DnD are not removed everytime.
    Any idea?
    Thanks
    Kristian   

  • DnD from JList into JTree

    Can anyone point me at a tutorial demonstarting how to drag objects from a JList into a JTree?
    many thanks

    Let me add some more information to maybe get some suggestions:
    I have DnD implemented in my tree - as my nodes are DefaultMutableTreeNode it is easy to getUserObject() and carry out the necessary changes to model and underlying object.
    In my JList(x2) I have custom objects, DnD is implemented on each list. My question is how should I wrap my JList objects so that I can retrieve the user object when I drop it into my tree?
    I have found an example of dragging nodes from one tree to another tree, but this is of little help as the DnD is simply dragging the String object about.
    Any pointers/suggestions please

  • DnD: custom TransferHandler and JTree

    Hi!
    I have seen a similar post like this one before, but there was no real answer.
    When I use the standard TransferHandler for DnD in a JTree, things work the way they should. However, when I use my own custom subclass of TransferHandler, no dragging behaviour is to be seen. Obviously, some crucial piece of code is missing from my class, but what is it?
    public class TopicTransferHandler extends TransferHandler {
        private TM4J_FSControllerFactory factory;
        private Object objectInTree = null;
        public TopicTransferHandler(TM4J_FSControllerFactory factory) {
         super();
         this.factory = factory;
        protected Transferable createTransferable(JComponent c) {
         Transferable trans = null;
         // if we are dragging from a tree (should always be the case)...
         if (c instanceof FSTree) {
             // then we let the HTMController construct a transferable from
             // the currently selected object in the tree
             FSTree tree = (FSTree) c;
             HandleTopicMirrorController mc =
              factory.createMirrorController(true);
             trans = mc.getTransferable(objectInTree);
             System.out.println("createTransferable(): " + trans);
         return trans;
        public int getSourceActions(JComponent c) {
         return COPY_OR_MOVE;
    }I appreciate any help!
    Dunk

    Hello!!
    I was having the same problem, but using the source code of TransferHandler and the tutorial I finally got it!! Eba!!
    /** Check http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html
    * @author Stenio L. Ferreira
    * Created on 20/08/2003
    * [email protected]
    import javax.swing.*;
    import java.awt.datatransfer.*;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionListener;
    import javax.swing.tree.*;
    import com.exactus.vbcomponentes.*;
    public class JTreeTransferHandler extends TransferHandler {
         protected Transferable createTransferable(JComponent c) {
              return new StringSelection(exportString(c));
         public int getSourceActions(JComponent c) {
              return COPY_OR_MOVE;
         protected String exportString(JComponent c) {
              DefaultMutableTreeNode treeNode =
                   (DefaultMutableTreeNode) ((JTree) c)
                        .getSelectionPath()
                        .getLastPathComponent();
              Node meuNode = (Node) treeNode.getUserObject();
              Integer result = new Integer(meuNode.getMeuId());
              return (result.toString());
         private static class DragHandler implements MouseMotionListener {
              MouseEvent firstMouseEvent;
              public void mousePressed(MouseEvent e) {
                   firstMouseEvent = e;
                   e.consume();
              public void mouseDragged(MouseEvent e) {
                   if (firstMouseEvent != null) {
                        e.consume();
                        int dx = Math.abs(e.getX() - firstMouseEvent.getX());
                        int dy = Math.abs(e.getY() - firstMouseEvent.getY());
                        //Arbitrarily define a 5-pixel shift as the
                        //official beginning of a drag.
                        if (dx > 5 || dy > 5) {
                             JComponent c = ((JTree) e.getSource());
                             JTreeTransferHandler th =
                                  (JTreeTransferHandler) c.getTransferHandler();
                             Transferable t = th.createTransferable(c);
                             th.exportDone(c, null, NONE);
                             firstMouseEvent = null;
              public void mouseReleased(MouseEvent e) {
                   firstMouseEvent = null;
              public void mouseMoved(MouseEvent e) {
    }Hope this helps!

  • DnD with JTree

    Hi All,
    I am creating two JTree ojects and registering it for DnD by calling method setDragEnabled(true). I created Class that extends from TransferHandler which contains all the required method including importData(). I have also created class for Transferable. But when i try to perform drag from one tree and drop it on another tree it is not working, but if I do it on the same tree it is working fine which I don't want to do. Here are the code snippets that create tree object and initialization.
    JPanel panel = new JPanel();
    JTree onTree = new JTree(new Vector());
    onTree.setCellRenderer(new MyTreeCellRenderer());
    onTree.setShowsRootHandles(true);
    transferHandler1 = new MyTransferHandler();
    onTree.setTransferHandler(transferHandler1);
    onTree.setDragEnabled(true);
    MyObjectJB myObj = (MyObjectJB) createData();
    AdPlanningTreeNode root = new AdPlanningTreeNode(spot);
    AdPlanningTreeNode spotNode = constructSubTree(root, spot);
    JTree offTree = new JTree(root);
    offTree.setCellRenderer(new DisplayTreeCellRenderer());
    offTree.setShowsRootHandles(true);
    transferHandler2 = new DisplayTransferHandler();
    offTree.setTransferHandler(transferHandler2);
    offTree.setDragEnabled(true);
    AdPlanningJScrollPane offScroller = new AdPlanningJScrollPane(offTree);
    AdPlanningJScrollPane onScroller = new AdPlanningJScrollPane(onTree);
    panel.add(offScroller);
    panel.add(onScroller);Here is code in importData() method of MyTransferHandler.
    public boolean importData(JComponent comp, Transferable t) {
    boolean isImported = false;
    try {
         if (!canImport(comp, t.getTransferDataFlavors())) {
              System.out.println("MyTransferHandler.importData ; can not import");
              return false;
         JTree targetTree = (JTree) comp;
         TreePath parentPath = targetTree.getSelectionPath();
         MyTreeNode parentNode = null;
         DefaultTreeModel model = (DefaultTreeModel) targetTree.getModel();
         MyObject item = (MyObject) DeepCopyUtil.createDeepCopy(t.getTransferData(SUPPORTED_FLAVORS));
         MyTreeNode node = new MyTreeNode((MyObjectJB) item);
         if (parentPath == null) {
              model.setRoot(node);
              targetTree.setSelectionRow(0);
              targetTree.repaint();
         else {
              parentNode = (MyTreeNode) parentPath.getLastPathComponent();
              model.insertNodeInto(node, parentNode, 0);
         isImported = true;
    catch (UnsupportedFlavorException e) {
         e.printStackTrace();
         return false;
    catch (IOException e) {
         e.printStackTrace();
         return false;
    catch (Exception e) {
         e.printStackTrace();
         return false;
    System.out.println("DisplayTransferHandler.importData completed");
    return isImported;
    One important thing is after dragging and importData method calls
    model.setRoot(node), then model is showing change in data but not reflected in Tree.

    Following link may help you understand: http://forums.java.net/jive/thread.jspa?threadID=9196

  • JTree change after Dnd

    Hello,
    I try to change the icon of the node source after a drag and drop in a JTree. Even if the icon information has changed in the node, I couldn't force the tree to reload with the changes.
    How could I do that ? Tell the treeCellRenderer to focus on the node source ?
    Regards,
    Anne

    You can use one of the methods of DefaultTreeModel
    ((DefaultTreeModel)tree.getModel()).nodeChanged(...)):
    void nodeChanged(TreeNode node)
              "Invoke this method after you've changed how node is to be represented in the tree. "
    void nodesChanged(TreeNode node, int[] childIndices)
              "Invoke this method after you've changed how the children identified by childIndicies are to be represented in the tree. "
    void nodeStructureChanged(TreeNode node)
              "Invoke this method if you've totally changed the children of node and its childrens children... "
    void nodesWereInserted(TreeNode node, int[] childIndices)
              "Invoke this method after you've inserted some TreeNodes into node. "
    void nodesWereRemoved(TreeNode node, int[] childIndices, Object[] removedChildren)
              "Invoke this method after you've removed some TreeNodes from node."
    Denis                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

Maybe you are looking for