package com.revolsys.swing.tree.dnd;
import java.awt.Component;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.util.Collection;
import javax.swing.JComponent;
import javax.swing.JTree;
import javax.swing.TransferHandler;
import javax.swing.tree.TreePath;
import com.revolsys.logging.Logs;
import com.revolsys.swing.tree.BaseTreeNode;
public class TreeTransferHandler extends TransferHandler {
private static final long serialVersionUID = 1L;
public static boolean isDndCopyAction(final TransferSupport support) {
final int dropAction = support.getDropAction();
return (dropAction & DnDConstants.ACTION_COPY) == DnDConstants.ACTION_COPY;
}
public static boolean isDndMoveAction(final int dropAction) {
return (dropAction & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE;
}
public static boolean isDndMoveAction(final TransferSupport support) {
final int dropAction = support.getDropAction();
return isDndMoveAction(dropAction);
}
public static boolean isDndNoneAction(final TransferSupport support) {
final int dropAction = support.getDropAction();
return dropAction == DnDConstants.ACTION_NONE;
}
public TreeTransferHandler() {
}
@Override
public boolean canImport(final TransferSupport support) {
final Component component = support.getComponent();
if (component instanceof JTree) {
final JTree.DropLocation loc = (JTree.DropLocation)support.getDropLocation();
final TreePath path = loc.getPath();
if (path != null) {
final Object pathItem = path.getLastPathComponent();
if (pathItem instanceof BaseTreeNode) {
final BaseTreeNode node = (BaseTreeNode)pathItem;
return node.isDndCanImport(path, support);
}
}
}
return false;
}
@Override
protected Transferable createTransferable(final JComponent c) {
if (c instanceof JTree) {
final JTree tree = (JTree)c;
final TreePath[] selectedPaths = tree.getSelectionPaths();
if (selectedPaths != null) {
final TreePathListTransferable transferable = new TreePathListTransferable(selectedPaths);
return transferable;
}
}
return null;
}
@Override
protected void exportDone(final JComponent component, final Transferable transferable,
final int action) {
if (isDndMoveAction(action)) {
try {
final Object data = transferable.getTransferData(TreePathListTransferable.FLAVOR);
if (data instanceof TreePathListTransferable) {
final TreePathListTransferable pathTransferable = (TreePathListTransferable)data;
final Collection<TreePath> paths = pathTransferable.getPaths();
for (final TreePath path : paths) {
final TreePath parentPath = path.getParentPath();
final Object parent = parentPath.getLastPathComponent();
if (parent instanceof BaseTreeNode) {
final BaseTreeNode parentNode = (BaseTreeNode)parent;
if (pathTransferable.isMoved(path)) {
parentNode.removeChild(path);
}
}
}
pathTransferable.reset();
}
} catch (final Throwable e) {
Logs.error(this, "Cannot export data", e);
}
}
}
@Override
public int getSourceActions(final JComponent c) {
if (c instanceof JTree) {
return COPY_OR_MOVE;
} else {
return NONE;
}
}
@Override
public boolean importData(final TransferSupport support) {
final Component component = support.getComponent();
if (component instanceof JTree) {
final JTree.DropLocation loc = (JTree.DropLocation)support.getDropLocation();
final TreePath path = loc.getPath();
final int index = loc.getChildIndex();
if (path != null) {
try {
final Object pathItem = path.getLastPathComponent();
if (pathItem instanceof BaseTreeNode) {
final BaseTreeNode node = (BaseTreeNode)pathItem;
return node.dndImportData(support, index);
}
} catch (final Exception e) {
Logs.error(this, "Cannot import data", e);
return false;
}
}
}
return false;
}
}