1 Reply Latest reply on Sep 11, 2007 9:56 PM by 807592

    JTree Drag and Drop issues

    807592
      Ok so my issue is when ever i move an object in the tree, it no longer displays its name, which has totally miffed me, as i tracked it to when it goes does the drop it calls this code
       TreePath p = (TreePath) tr.getTransferData(flavors);

      now that goes into the transferable proxy or sometihng, and gets to the TestTreeTransferableNode which returns the wanted TreePath object, but somewhere inbetween in the proxy part it is set to null, there is a null object sitting in my tree where the object SHOULD have been moved too :(

      and help would be great, heres the full tree code also
      import java.awt.BorderLayout;
      import java.awt.Color;
      import java.awt.Graphics;
      import java.awt.Insets;
      import java.awt.Point;
      import java.awt.Rectangle;
      import java.awt.datatransfer.DataFlavor;
      import java.awt.datatransfer.Transferable;
      import java.awt.datatransfer.UnsupportedFlavorException;
      import java.awt.dnd.Autoscroll;
      import java.awt.dnd.DnDConstants;
      import java.awt.dnd.DragGestureEvent;
      import java.awt.dnd.DragGestureListener;
      import java.awt.dnd.DragGestureRecognizer;
      import java.awt.dnd.DragSource;
      import java.awt.dnd.DragSourceDragEvent;
      import java.awt.dnd.DragSourceDropEvent;
      import java.awt.dnd.DragSourceEvent;
      import java.awt.dnd.DragSourceListener;
      import java.awt.dnd.DropTarget;
      import java.awt.dnd.DropTargetContext;
      import java.awt.dnd.DropTargetDragEvent;
      import java.awt.dnd.DropTargetDropEvent;
      import java.awt.dnd.DropTargetEvent;
      import java.awt.dnd.DropTargetListener;
      import java.io.IOException;
      
      import javax.swing.JFrame;
      import javax.swing.JScrollPane;
      import javax.swing.JTree;
      import javax.swing.tree.DefaultMutableTreeNode;
      import javax.swing.tree.DefaultTreeModel;
      import javax.swing.tree.TreeNode;
      import javax.swing.tree.TreePath;
      
      
        public class TestTree extends JTree implements Autoscroll {
          private int margin = 12;
          
          TestTreeDragSource ds;
      
          TestTreeDropTarget dt;
      
          public TestTree(DefaultMutableTreeNode tree) {
            super(tree);
            
            ds = new TestTreeDragSource(this, DnDConstants.ACTION_COPY_OR_MOVE);
            dt = new TestTreeDropTarget(this);
            
          }
      
          public void autoscroll(Point p) {
            int realrow = getRowForLocation(p.x, p.y);
            Rectangle outer = getBounds();
            realrow = (p.y + outer.y <= margin ? realrow < 1 ? 0 : realrow - 1
                : realrow < getRowCount() - 1 ? realrow + 1 : realrow);
            scrollRowToVisible(realrow);
          }
      
          public Insets getAutoscrollInsets() {
            Rectangle outer = getBounds();
            Rectangle inner = getParent().getBounds();
            return new Insets(inner.y - outer.y + margin, inner.x - outer.x
                + margin, outer.height - inner.height - inner.y + outer.y
                + margin, outer.width - inner.width - inner.x + outer.x
                + margin);
          }
      
          // Use this method if you want to see the boundaries of the
          // autoscroll active region
      
          public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Rectangle outer = getBounds();
            Rectangle inner = getParent().getBounds();
            g.setColor(Color.red);
            g.drawRect(-outer.x + 12, -outer.y + 12, inner.width - 24,
                inner.height - 24);
          }
      
        }
      
      
      //TreeDragSource.java
      //A drag source wrapper for a JTree. This class can be used to make
      //a rearrangeable DnD tree with the TransferableTreeNode class as the
      //transfer data type.
      
      class TestTreeDragSource implements DragSourceListener, DragGestureListener {
      
        DragSource source;
      
        DragGestureRecognizer recognizer;
      
        TestTransferableTreeNode transferable;
      
        DefaultMutableTreeNode oldNode;
      
        JTree sourceTree;
      
        public TestTreeDragSource(JTree tree, int actions) {
          sourceTree = tree;
          source = new DragSource();
          recognizer = source.createDefaultDragGestureRecognizer(sourceTree,
              actions, this);
        }
      
        /*
         * Drag Gesture Handler
         */
        public void dragGestureRecognized(DragGestureEvent dge) {
          TreePath path = sourceTree.getSelectionPath();
          if ((path == null) || (path.getPathCount() <= 1)) {
            // We can't move the root node or an empty selection
            return;
          }
          oldNode = (DefaultMutableTreeNode) path.getLastPathComponent();
          transferable = new TestTransferableTreeNode(path);
          source.startDrag(dge, DragSource.DefaultMoveNoDrop, transferable, this);
      
          // If you support dropping the node anywhere, you should probably
          // start with a valid move cursor:
          //source.startDrag(dge, DragSource.DefaultMoveDrop, transferable,
          // this);
        }
      
        /*
         * Drag Event Handlers
         */
        public void dragEnter(DragSourceDragEvent dsde) {
        }
      
        public void dragExit(DragSourceEvent dse) {
        }
      
        public void dragOver(DragSourceDragEvent dsde) {
        }
      
        public void dropActionChanged(DragSourceDragEvent dsde) {
          System.out.println("Action: " + dsde.getDropAction());
          System.out.println("Target Action: " + dsde.getTargetActions());
          System.out.println("User Action: " + dsde.getUserAction());
        }
      
        public void dragDropEnd(DragSourceDropEvent dsde) {
          /*
           * to support move or copy, we have to check which occurred:
           */
          System.out.println("Drop Action: " + dsde.getDropAction());
          if (dsde.getDropSuccess()
              && (dsde.getDropAction() == DnDConstants.ACTION_MOVE)) {
            ((DefaultTreeModel) sourceTree.getModel())
                .removeNodeFromParent(oldNode);
          }
      
          /*
           * to support move only... if (dsde.getDropSuccess()) {
           * ((DefaultTreeModel)sourceTree.getModel()).removeNodeFromParent(oldNode); }
           */
        }
      }
      
      //TreeDropTarget.java
      //A quick DropTarget that's looking for drops from draggable JTrees.
      //
      
      class TestTreeDropTarget implements DropTargetListener {
      
        DropTarget target;
      
        JTree targetTree;
      
        public TestTreeDropTarget(JTree tree) {
          targetTree = tree;
          target = new DropTarget(targetTree, this);
        }
      
        /*
         * Drop Event Handlers
         */
        private TreeNode getNodeForEvent(DropTargetDragEvent dtde) {
          Point p = dtde.getLocation();
          DropTargetContext dtc = dtde.getDropTargetContext();
          JTree tree = (JTree) dtc.getComponent();
          TreePath path = tree.getClosestPathForLocation(p.x, p.y);
          return (TreeNode) path.getLastPathComponent();
        }
      
        public void dragEnter(DropTargetDragEvent dtde) {
          TreeNode node = getNodeForEvent(dtde);
          if (node.isLeaf()) {
            dtde.rejectDrag();
          } else {
            // start by supporting move operations
            //dtde.acceptDrag(DnDConstants.ACTION_MOVE);
            dtde.acceptDrag(dtde.getDropAction());
          }
        }
      
        public void dragOver(DropTargetDragEvent dtde) {
          TreeNode node = getNodeForEvent(dtde);
          if (node.isLeaf()) {
            dtde.rejectDrag();
          } else {
            // start by supporting move operations
            //dtde.acceptDrag(DnDConstants.ACTION_MOVE);
            dtde.acceptDrag(dtde.getDropAction());
          }
        }
      
        public void dragExit(DropTargetEvent dte) {
        }
      
        public void dropActionChanged(DropTargetDragEvent dtde) {
        }
      
        public void drop(DropTargetDropEvent dtde) {
          Point pt = dtde.getLocation();
          DropTargetContext dtc = dtde.getDropTargetContext();
          JTree tree = (JTree) dtc.getComponent();
          TreePath parentpath = tree.getClosestPathForLocation(pt.x, pt.y);
          DefaultMutableTreeNode parent = (DefaultMutableTreeNode) parentpath
              .getLastPathComponent();
          if (parent.isLeaf()) {
            dtde.rejectDrop();
            return;
          }
      
          try {
            Transferable tr = dtde.getTransferable();
            DataFlavor[] flavors = tr.getTransferDataFlavors();
            for (int i = 0; i < flavors.length; i++) {
              if (tr.isDataFlavorSupported(flavors)) {
      dtde.acceptDrop(dtde.getDropAction());
      TreePath p = (TreePath) tr.getTransferData(flavors[i]);
      DefaultMutableTreeNode node = (DefaultMutableTreeNode) p
      .getLastPathComponent();
      DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
      model.insertNodeInto(node, parent, 0);
      dtde.dropComplete(true);
      return;
      }
      }
      dtde.rejectDrop();
      } catch (Exception e) {
      e.printStackTrace();
      dtde.rejectDrop();
      }
      }
      }

      //TransferableTreeNode.java
      //A Transferable TreePath to be used with Drag & Drop applications.
      //

      class TestTransferableTreeNode implements Transferable {

      public static DataFlavor TREE_PATH_FLAVOR = new DataFlavor(TreePath.class,
      "Tree Path");

      DataFlavor flavors[] = { TREE_PATH_FLAVOR };

      TreePath path;

      public TestTransferableTreeNode(TreePath tp) {
      path = tp;
      }

      public synchronized DataFlavor[] getTransferDataFlavors() {
      return flavors;
      }

      public boolean isDataFlavorSupported(DataFlavor flavor) {
      return (flavor.getRepresentationClass() == TreePath.class);
      }

      public synchronized Object getTransferData(DataFlavor flavor)
      throws UnsupportedFlavorException, IOException {
      if (isDataFlavorSupported(flavor)) {
      return (Object) path;
      } else {
      throw new UnsupportedFlavorException(flavor);
      }
      }
      }



      Message was edited by:
      QWERTY