| |
"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;
}
}
|
|