public class DndTreeTransferHandler implements DragGestureListener,
DragSourceListener, DropTargetListener {
/**
* importiert DndTree
*/
private DndTree tree;
/**
* importiert die DragSource
*/
private DragSource dragSource;
/**
* importiert das DropTarget
*/
private DropTarget dropTarget;
/**
* draggedNode
*/
private static VDM_TreeNode draggedNode;
/**
* draggedNodeParrent
*/
private VDM_TreeNode draggedNodeParent;
/**
* image
*/
private static BufferedImage image = null;
/**
* Rectangle
*/
private Rectangle rect2D = new Rectangle();
/**
* drawImage
*/
private boolean drawImage;
/**
* Konstruktor
*
* @param tree
* @param action
* @param drawIcon
*/
protected DndTreeTransferHandler(DndTree tree, int action, boolean drawIcon) {
this.tree = tree;
drawImage = drawIcon;
dragSource = new DragSource();
dragSource.createDefaultDragGestureRecognizer(tree, action, this);
dropTarget = new DropTarget(tree, action, this);
}
/**
* wird aufgerufen wenn ein Drag & Drop beendet wurde
*
* @param dsde
*
*/
public void dragDropEnd(DragSourceDropEvent dsde) {
if (dsde.getDropSuccess()
&& dsde.getDropAction() == DnDConstants.ACTION_MOVE) {
((DefaultTreeModel) tree.getModel())
.nodeStructureChanged(draggedNodeParent);
tree.expandPath(new TreePath(draggedNodeParent.getPath()));
}
}
/**
* wird aufgerufen, wenn von außen ein hinübergezogenes Objekt die
* Komponente erreicht
*
* @param dsde
*/
public final void dragEnter(DragSourceDragEvent dsde) {
int action = dsde.getDropAction();
if (action == DnDConstants.ACTION_COPY) {
dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop);
} else {
if (action == DnDConstants.ACTION_MOVE) {
dsde.getDragSourceContext().setCursor(
DragSource.DefaultMoveDrop);
} else {
dsde.getDragSourceContext().setCursor(
DragSource.DefaultMoveNoDrop);
}
}
}
/**
*
* wird aufgerufen, wenn die gedrückte Maus über die Komponente gezogen wird
*
* @param dsde
*/
public final void dragOver(DragSourceDragEvent dsde) {
int action = dsde.getDropAction();
if (action == DnDConstants.ACTION_COPY) {
dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop);
} else {
if (action == DnDConstants.ACTION_MOVE) {
dsde.getDragSourceContext().setCursor(
DragSource.DefaultMoveDrop);
} else {
dsde.getDragSourceContext().setCursor(
DragSource.DefaultMoveNoDrop);
}
}
}
/**
* wird aufgerufen wenn die gewünschte Aktion (Kopieren, Verschieben oder
* Verknüpfen) geändert wurde
*
* @param dsde
*/
public final void dropActionChanged(DragSourceDragEvent dsde) {
int action = dsde.getDropAction();
if (action == DnDConstants.ACTION_COPY) {
dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop);
} else {
if (action == DnDConstants.ACTION_MOVE) {
dsde.getDragSourceContext().setCursor(
DragSource.DefaultMoveDrop);
} else {
dsde.getDragSourceContext().setCursor(
DragSource.DefaultMoveNoDrop);
}
}
}
/**
* wird aufgerufen, wenn der gedrückte Mauszeiger die Komponente verlässt
*
* @param dse
*/
public final void dragExit(DragSourceEvent dse) {
dse.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
}
/**
* wird aufgerufen, wenn der Benutzer bei gedrückter Maustaste den
* Mauszeiger bewegt
*
* @param dge
*
*/
public final void dragGestureRecognized(DragGestureEvent dge) {
TreePath path = tree.getSelectionPath();
if (path != null) {
draggedNode = (VDM_TreeNode) path.getLastPathComponent();
draggedNodeParent = (VDM_TreeNode) draggedNode.getParent();
if (drawImage) {
Rectangle pathBounds = tree.getPathBounds(path);
JComponent lbl = (JComponent) tree.getCellRenderer()
.getTreeCellRendererComponent(
tree,
draggedNode,
false,
tree.isExpanded(path),
((DefaultTreeModel) tree.getModel())
.isLeaf(path.getLastPathComponent()),
0, false);
lbl.setBounds(pathBounds);
image = new BufferedImage(lbl.getWidth(), lbl.getHeight(),
java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE);
Graphics2D graphics = image.createGraphics();
graphics.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.5f));
lbl.setOpaque(false);
lbl.paint(graphics);
graphics.dispose();
}
if (!draggedNode.isRoot()) {
dragSource.startDrag(dge, DragSource.DefaultMoveDrop, image,
new Point(0, 0), new TransferableNode(draggedNode),
this);
}
}
}
/**
* wird aufgerufen, wenn von außen ein hinübergezogenes Objekt die
* Komponente erreicht
*
* @param dtde
*/
public final void dragEnter(DropTargetDragEvent dtde) {
Point pt = dtde.getLocation();
int action = dtde.getDropAction();
if (drawImage) {
paintImage(pt);
}
if (canPerformAction(tree, draggedNode, action, pt)) {
dtde.acceptDrag(action);
} else {
dtde.rejectDrag();
}
}
/**
* wird aufgerufen, wenn der gedrückte Mauszeiger die Komponente verlässt
*
* @param dte
*/
public final void dragExit(DropTargetEvent dte) {
if (drawImage) {
clearImage();
}
}
/**
* wird aufgerufen, wenn die gedrückte Maus über die Komponente gezogen wird
*
* @param dtde
*/
public final void dragOver(DropTargetDragEvent dtde) {
Point pt = dtde.getLocation();
int action = dtde.getDropAction();
if (drawImage) {
paintImage(pt);
}
if (canPerformAction(tree, draggedNode, action, pt)) {
dtde.acceptDrag(action);
} else {
dtde.rejectDrag();
}
}
/**
* wird aufgerufen wenn die gewünschte Aktion (Kopieren, Verschieben oder
* Verknüpfen) geändert wurde
*
* @param dtde
*/
public final void dropActionChanged(DropTargetDragEvent dtde) {
Point pt = dtde.getLocation();
int action = dtde.getDropAction();
if (drawImage) {
paintImage(pt);
}
if (canPerformAction(tree, draggedNode, action, pt)) {
dtde.acceptDrag(action);
} else {
dtde.rejectDrag();
}
}
/**
* wird aufgerufen, wenn die Maustaste losgelassen (Drop) wird
*
* @param dtde
*
*/
public final void drop(DropTargetDropEvent dtde) {
try {
if (drawImage) {
clearImage();
}
int action = dtde.getDropAction();
Transferable transferable = dtde.getTransferable();
Point pt = dtde.getLocation();
if (transferable
.isDataFlavorSupported(TransferableNode.NODE_FLAVOR)
&& canPerformAction(tree, draggedNode, action, pt)) {
TreePath pathTarget = tree
.getClosestPathForLocation(pt.x, pt.y);
VDM_TreeNode node = (VDM_TreeNode) transferable
.getTransferData(TransferableNode.NODE_FLAVOR);
VDM_TreeNode newParentNode = (VDM_TreeNode) pathTarget
.getLastPathComponent();
if (executeDrop(tree, node, newParentNode, action)) {
dtde.acceptDrop(DnDConstants.ACTION_MOVE);
dtde.getDropTargetContext().dropComplete(true);
return;
}
}
dtde.rejectDrop();
dtde.dropComplete(false);
} catch (Exception e) {
System.out.println(e);
dtde.rejectDrop();
dtde.dropComplete(false);
}
}
/**
* zeichnet das Image
*
* @param pt
*/
private final void paintImage(Point pt) {
tree.paintImmediately(rect2D.getBounds());
rect2D.setRect((int) pt.getX(), (int) pt.getY(), image.getWidth(),
image.getHeight());
tree.getGraphics().drawImage(image, (int) pt.getX(), (int) pt.getY(),
tree);
}
/**
* löscht das Image
*
*
*/
private final void clearImage() {
tree.paintImmediately(rect2D.getBounds());
}
/**
* liefert zurück ob Drag & Drop möglich ist
*
* @param target
* @param draggedNode
* @param action
* @param location
* @return true, false
*/
public boolean canPerformAction(DndTree target, VDM_TreeNode draggedNode,
int action, Point location) {
TreePath pathTarget = target.getPathForLocation(location.x, location.y);
if (pathTarget == null) {
target.setSelectionPath(null);
return (false);
} else if (action == DnDConstants.ACTION_MOVE) {
VDM_TreeNode parentNode = (VDM_TreeNode) pathTarget
.getLastPathComponent();
if (parentNode == draggedNode.getParent()) {
return (false);
} else {
return (true);
}
} else {
return (false);
}
}
/**
* setzt die darggedNode an eine neue Position
*
* @param target
* @param draggedNode
* @param newParentNode
* @param action
* @return true, false
*/
public boolean executeDrop(DndTree target, VDM_TreeNode draggedNode,
VDM_TreeNode newParentNode, int action) {
if (action == DnDConstants.ACTION_MOVE) {
((DefaultTreeModel) target.getModel()).insertNodeInto(draggedNode,
newParentNode, newParentNode.getChildCount());
TreePath treePath = new TreePath(draggedNode.getPath());
target.scrollPathToVisible(treePath);
target.setSelectionPath(treePath);
return (true);
}
return (false);
}
}