Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Java Tip 97: Add drag and drop to your JTrees

Improve JTree usability with drag and drop

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 2 of 4

  • Line 2: You grab the node that will be dragged. (You will have to implement getSelectedNode().)
  • Lines 5-6: You grab the object you wish to transfer (more about the Transferable object later).
  • Lines 8 : You set the drag cursor type appropriately.
  • Line 10: You start the drag event. Its parameters are as follows:
  • e is the DragGestureEvent
  • cursor is the cursor you wish to use
  • transferable is the object to be transferred
  • dragSourceListener is the component that has implemented the DragSourceListener interface


DragSourceListener

The DragSourceListener interface is implemented by the component that contains the draggable object. There are five possible drag actions, and the DragSourceListener has a method to handle each one. The code in those methods is not required. Some of them can be left empty, but the dragEnter and dragOver are useful for setting the cursor type to indicate whether the drop target is valid. I'll revisit how you do this later in the article.

DropTargetListener

The DropTargetListener interface is implemented by the component that will drop the object. Once again, there are five possible drop actions and the DropTargetListener has a method to handle each one. You use the dragOver method to obtain the cursor location and decide if the drop location is valid, but the most interesting method is the drop method. Below is an example code listing of that method. Its code completes the desired action to take when a drop action occurs.

      //The Drag operation has terminated with a Drop on this DropTarget
      1 void drop(DropTargetDropEvent dtde) {
      2        Transferable transferable = dtde.getTransferable();
      3
      4        //flavor not supported, reject drop
      5        if (!transferable.isDataFlavorSupported( <DATA FLAVOR> )) {
      6           e.rejectDrop();
      7           return;
      8        }
      9
     10        DefaultMutableTreeNode oldParent =
getSelectedNode().getParent(); 11 12 Point loc = dtde.getLocation(); 13 TreePath destinationPath = getPathForLocation(loc.x, loc.y); 14 DefaultMutableTreeNode newParent = 15 (DefaultMutableTreeNode) destinationPath.getLastPathComponent(); 16 17 DefaultMutableTreeNode newChild = null; 18 if (dtde.getDropAction() == DnDConstants.ACTION_COPY) {
//make a new child 19 Object data = tranferable.getTransferData( <DATA FLAVOR> ); 20 DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(data.clone()); 21 } 22 else { //move 23 newChild = getSelectedNode(); 24 oldParent.remove(newChild); 25 } 26 27 newParent.add(child); 28 }


Here's an explanation of the steps taken in the above code:

  • Line 2: You grab the Transferable object.
  • Lines 4-8: You verify that the flavor of data you want is supported. If not, then cancel. Above, I have used the notation <DATAFLAVOR> to indicate the flavor. That constant is of DataFlavor type and can be user-defined or one of the flavors found within the DataFlavor class. This is just sample code, so you don't know what flavor it is.
  • Lines 10-15: You retrieve the old and new parent nodes.
  • Line 17-24: Based on the action, you determine the newChild. If it's a copy, then clone the data and make newChild a new DefaultMutableTreeNode with the cloned data as the user object. Otherwise, set newChild to be the old child and remove it from the old parent.
  • Line 27: You add the new child to its new parent.


Note that the code above is shortened for the sake of clarity and neglects error-handling code. If you want to cut and paste, refer to DnDJTree.java in the source code zip in Resources for a more production-worthy example.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources