HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"A Reusable Drag and Drop Handler"
Vol. 6, Issue 9, p. 63

	


Listing 1 - Draggable Tree1

import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.dnd.*;
import java.io.IOException;

public class DraggableTree extends JTree implements DragGestureListener
{
  DragSource dragSource = DragSource.getDefaultDragSource();

  final static DragSourceListener dragSourceListener = new theDragSourceListener();

  public DraggableTree ()
  {
    dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
    setAutoscrolls(true);
  }

  // DragGestureListener

  public void dragGestureRecognized(DragGestureEvent dragGestureEvent)
  {
    TreePath path = getSelectionPath();
    if (path == null)
    {
      // Nothing selected, nothing to drag
      System.out.println ("Nothing selected - beep");
      getToolkit().beep();
    }
    else
    {
      DefaultMutableTreeNode selection = (DefaultMutableTreeNode)path.getLastPathComponent();
      TransferableDataItem node = new TransferableDataItem(selection);
      dragSource.startDrag(dragGestureEvent, DragSource.DefaultCopyDrop, node, dragSourceListener);
    }
  }

  static class theDragSourceListener implements DragSourceListener
  {
    public void dragDropEnd(DragSourceDropEvent dragSourceDropEvent)
    {
    }
    public void dragEnter(DragSourceDragEvent dragSourceDragEvent)
    {
    }
    public void dragExit(DragSourceEvent dragSourceEvent)
    {
    }
    public void dragOver(DragSourceDragEvent dragSourceDragEvent)
    {
    }
    public void dropActionChanged(DragSourceDragEvent dragSourceDragEvent)
    {
    }
  }

}

Listing 2 - Droppable List1

import java.awt.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
import java.util.List;

public class DroppableList extends JList implements DropTargetListener
{

  DropTarget dropTarget;

  public DroppableList()
  {
    dropTarget = new DropTarget (this, this);
    setModel(new DefaultListModel());
  }

  public void dragEnter (DropTargetDragEvent dropTargetDragEvent)
  {
    dropTargetDragEvent.acceptDrag (DnDConstants.ACTION_COPY_OR_MOVE);
  }

  public void dragExit (DropTargetEvent dropTargetEvent)
  {
  }

  public void dragOver (DropTargetDragEvent dropTargetDragEvent)
  {
  }

  public void dropActionChanged (DropTargetDragEvent dropTargetDragEvent)
  {
  }

  public synchronized void drop (DropTargetDropEvent dropTargetDropEvent)
  {
    Point location = dropTargetDropEvent.getLocation();
    try
    {
     Transferable tr = dropTargetDropEvent.getTransferable();
      if (tr.isDataFlavorSupported(TransferableDataItem.DEFAULT_MUTABLE_DATAITEM_FLAVOR))
      {
        dropTargetDropEvent.acceptDrop (DnDConstants.ACTION_COPY_OR_MOVE);
        Object userObject = tr.getTransferData(TransferableDataItem.DEFAULT_MUTABLE_DATAITEM_FLAVOR);
        addElement(location, userObject);
        dropTargetDropEvent.getDropTargetContext().dropComplete(true);
      }
      else
      {
        System.err.println ("Rejected");
        dropTargetDropEvent.rejectDrop();
      }
    }
    catch (IOException io)
    {
      io.printStackTrace();
      dropTargetDropEvent.rejectDrop();
    }
    catch (UnsupportedFlavorException ufe)
    {
      ufe.printStackTrace();
      dropTargetDropEvent.rejectDrop();
    }
  }
  private void addElement(Point location, Object element) {
    int index = locationToIndex(location);
    // If index not found, add at end, otherwise add one beyond position
    if (index == -1) {
      index = getModel().getSize();
    }
    else
    {
      index++;
    }
    ((DefaultListModel)getModel()).add(index, element);
  }
}

Listing 3 - DnDHandler1


import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.awt.Cursor;
import java.awt.Component;

public abstract class DnDHandler implements DropTargetListener,DragSourceListener, DragGestureListener
{

  protected DropTarget dropTarget;
  protected DragSource dragSource;

  public DnDHandler(Component dndComponent)
  {
    dropTarget = new DropTarget (dndComponent, this);
    dragSource = new DragSource();
    dragSource.createDefaultDragGestureRecognizer( dndComponent, DnDConstants.ACTION_COPY_OR_MOVE, this);
  }


  //creates transferable based on what's selected or returns null if nothings selected
  protected abstract Transferable getTransferable();
  protected abstract void handleDrop(Transferable transferable, DropTargetDropEvent event) throws Exception;
  protected abstract DataFlavor[] getSupportedDataFlavors();

  public void dropFailed (DragSourceDropEvent event)
  {
     System.out.println("Drop Failed");
  }

  public void dropSuccess (DragSourceDropEvent event)
  {
     System.out.println("Drop was successful");
  }

  private boolean isTransferableSupported(Transferable t)
  {
      DataFlavor[] flavors = getSupportedDataFlavors();
      for (int i=0; i<flavors.length; i++)
      {
          if (t.isDataFlavorSupported(flavors[i]) )
              return true;
      }
      return false;
  }


  public void dragGestureRecognized( DragGestureEvent event)
  {

        Transferable trans = getTransferable();
        Cursor dragIcon = getDragCursor(event);

        if (trans != null)
        {
            // Starts the dragging
            dragSource.startDrag (event, dragIcon, trans, this);
        }
        else
        {
            System.out.println( "nothing was selected");
        }
  }

  /**
   * a drop has occurred
   *
   */
  public void drop (DropTargetDropEvent event)
  {

    try
    {
        Transferable transferable = event.getTransferable();

        // we accept only Strings
        if (isTransferableSupported (transferable))
        {
            event.acceptDrop(event.getDropAction());
            handleDrop(transferable, event);
            event.getDropTargetContext().dropComplete(true);
        }
        else
        {
            event.rejectDrop();
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
        System.err.println( "Drop Exception" + e.getMessage());
        event.rejectDrop();
    }

  }

  //DragSourceListener interfaces
  /**
   * is invoked when you are dragging over the DropSite
   *
   */
  public void dragEnter (DropTargetDragEvent event)
  {

    // debug messages for diagnostics
    //System.out.println( "dragEnter");

    int action = event.getDropAction();
    event.acceptDrag (action);

  }

  /**
   * is invoked when you are exit the DropSite without dropping
   *
   */
  public void dragExit (DropTargetEvent event)
  {
    //System.out.println( "dragExit");
  }

  /**
   * is invoked when a drag operation is going on
   *
   */
  public void dragOver (DropTargetDragEvent event)
  {
    //System.out.println( "dragOver");
  }

  /**
   * is invoked if the use modifies the current drop gesture
   *
   */


  public void dropActionChanged ( DropTargetDragEvent event )
  {
  }



  //gets the cursor to start drag
  protected Cursor getDragCursor( DragGestureEvent event)
  {
      if (event.getDragAction() == DnDConstants.ACTION_MOVE)
      {
          return DragSource.DefaultMoveDrop;
      }
      if (event.getDragAction() == DnDConstants.ACTION_COPY_OR_MOVE)
      {
          return DragSource.DefaultCopyDrop;
      }
      else
      {
          return Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
      }
  }


  /**
   * this message goes to DragSourceListener, informing it that the dragging
   * has ended
   *
   */

  public void dragDropEnd (DragSourceDropEvent event) {
    if ( event.getDropSuccess())
    {
        dropSuccess(event);
    }
    else
    {
        dropFailed(event);
    }
  }

  /**
   * this message goes to DragSourceListener, informing it that the dragging
   * has entered the DropSite
   *
   */
  public void dragEnter (DragSourceDragEvent event)
  {
    //System.out.println( " dragEnter");
  }

  /**
   * this message goes to DragSourceListener, informing it that the dragging
   * has exited the DropSite
   *
   */
  public void dragExit (DragSourceEvent event)
  {
    //System.out.println( "dragExit");

  }

  /**
   * this message goes to DragSourceListener, informing it that the dragging is currently
   * ocurring over the DropSite
   *
   */
  public void dragOver (DragSourceDragEvent event)
  {
    //System.out.println( "dragExit");

  }

  /**
   * is invoked when the user changes the dropAction
   *
   */
  public void dropActionChanged ( DragSourceDragEvent event)
  {
    //System.out.println( "dropActionChanged");
  }

}

Listing 4 - DNDTree1 

import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.dnd.*;
import java.awt.dnd.DnDConstants;
import java.io.IOException;
import java.awt.datatransfer.*;

/**
 * Title:
 * Description:
 * Copyright:    Copyright (c)
 * Company:
 * @author
 * @version 1.0
 */

public class DNDTree extends JTree
{
  public DNDTree ()
  {
    DNDTreeHandler dndHandler = new DNDTreeHandler(this);

    setAutoscrolls(true);
  }

  public class DNDTreeHandler extends DnDHandler
  {
     TransferableDataItem transDataItem = new TransferableDataItem();

     public DNDTreeHandler(Component dndComponent)
     {
        super(dndComponent);
     }
     public DataFlavor[] getSupportedDataFlavors()
     {
        return transDataItem.getTransferDataFlavors();
     }


    /**
     * Gets the data from the selected object being dragged
     *
     * @return node DataItem being dragged
     */
    public Transferable getTransferable()
    {
       TreePath path = getSelectionPath();
       DefaultMutableTreeNode selection = (DefaultMutableTreeNode)path.getLastPathComponent();
       if (path == null)
       {
          return(null);
       }
       else
       {
         TransferableDataItem node = new TransferableDataItem(selection);
         return(node);
       }
     }

     /**
      * Handles the drop of the component after the drag is complete
      *
      * @param transferable Object being dropped
      * @param event drop event information
      */
     public void handleDrop(Transferable transferable, DropTargetDropEvent event) throws Exception
     {
           Point location = event.getLocation();
           //Get path of node where object being dropped
           TreePath path = getClosestPathForLocation(location.x, location.y);
           //No drop target
           if(path == null)
           {
              System.err.println ("Rejected");
              event.rejectDrop();
           }
           else
           {
              Transferable tr = event.getTransferable();

              if(tr.isDataFlavorSupported(TransferableDataItem.DEFAULT_MUTABLE_DATAITEM_FLAVOR))
              {
                 System.out.println("Got transfered data");
                 Object userObject = tr.getTransferData(TransferableDataItem.DEFAULT_MUTABLE_DATAITEM_FLAVOR);
                 DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
                 DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(userObject.toString());
                 DefaultTreeModel model = (DefaultTreeModel)getModel();
                 model.insertNodeInto(newNode, node, 0);
              }
              else
              {
                 System.err.println ("Rejected");
                 event.rejectDrop();
              }
           }

     }
   }
}

Listing 5 - DNDList1

import javax.swing.JList;
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.dnd.*;
import java.awt.dnd.DnDConstants;
import java.io.IOException;
import java.awt.datatransfer.*;

public class DNDList extends JList
{
  DropTarget dropTarget;

  public DNDList()
  {
    DNDListHandler dndHandler = new DNDListHandler(this);

    setModel(new DefaultListModel());
  }

  private void addElement(Point location, Object element)
  {
    int index = locationToIndex(location);
    // If index not found, add at end, otherwise add one beyond position
    if (index == -1) {
      index = getModel().getSize();
    }
    else
    {
      index++;
    }
    ((DefaultListModel)getModel()).add(index, element);
  }

  public class DNDListHandler extends DnDHandler
  {
     TransferableDataItem transDataItem = new TransferableDataItem();

     public DNDListHandler(Component dndComponent)
     {
        super(dndComponent);
     }
     public DataFlavor[] getSupportedDataFlavors()
     {
        return transDataItem.getTransferDataFlavors();
     }
     public DataFlavor[] getTransferDataFlavors()
     {
       return transDataItem.getTransferDataFlavors();
     }

    /**
     * Gets the data from the selected object being dragged
     *
     * @return node Node being dragged
     */
    public Transferable getTransferable()
    {
       Object selectedItem = getSelectedValue();
       System.out.println("Selected Value is " + selectedItem);
       TransferableDataItem item = new TransferableDataItem(selectedItem);
       return(item);
    }
     /**
      * Handles the drop of the component after the drag is complete
      *
      * @param transferable Object being dropped
      * @param event drop event information
      */
     public void handleDrop(Transferable transferable, DropTargetDropEvent event) throws Exception
     {
           Transferable tr = event.getTransferable();
           Point location = event.getLocation();
           if (tr.isDataFlavorSupported(TransferableDataItem.DEFAULT_MUTABLE_DATAITEM_FLAVOR))
           {
              //event.acceptDrop (DnDConstants.ACTION_COPY_OR_MOVE);
              Object userObject = tr.getTransferData(TransferableDataItem.DEFAULT_MUTABLE_DATAITEM_FLAVOR);
              addElement(location, userObject);
             //dropTargetDropEvent.getDropTargetContext().dropComplete(true);
           }
           else
           {
              System.err.println ("Rejected");
              event.rejectDrop();
           }
      }
   }
}



import javax.swing.tree.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.io.*;


public class TransferableDataItem extends DefaultMutableTreeNode implements Transferable
{

  final static int DATA_ITEM = 0;
  final static int STRING = 1;
  final static int PLAIN_TEXT = 2;

  final public static DataFlavor DEFAULT_MUTABLE_DATAITEM_FLAVOR =
    new DataFlavor(DefaultMutableTreeNode.class, "Default Mutable Data Item");

  static DataFlavor flavors[] = {DEFAULT_MUTABLE_DATAITEM_FLAVOR, DataFlavor.stringFlavor, DataFlavor.plainTextFlavor};

  private Object data;

  public TransferableDataItem()
  {
  }
  public TransferableDataItem(Object data)
  {
    this.data = data;
  }

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

  public Object getTransferData(DataFlavor flavor)
      throws UnsupportedFlavorException, IOException
  {
    Object returnObject;
    if (flavor.equals(flavors[DATA_ITEM]))
    {
        returnObject = data;
    }
    else if (flavor.equals(flavors[STRING]))
    {

        returnObject = data.toString();
    }
    else if (flavor.equals(flavors[PLAIN_TEXT]))
    {
        returnObject = new ByteArrayInputStream(data.toString().getBytes());
    }
    else
    {
      throw new UnsupportedFlavorException(flavor);
    }
    return returnObject;
  }
  public boolean isDataFlavorSupported(DataFlavor flavor)
  {
    boolean returnValue = false;
    for (int i=0, n=flavors.length; i<n; i++) {
      if (flavor.equals(flavors[i]))
      {
        returnValue = true;
        break;
      }
    }
    return returnValue;
  }
}

  
 
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: info@sys-con.com

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.