20 package net.sf.gridarta.gui.mapmenu;
22 import java.awt.Point;
23 import java.awt.Rectangle;
24 import java.awt.datatransfer.DataFlavor;
25 import java.awt.datatransfer.Transferable;
26 import java.awt.datatransfer.UnsupportedFlavorException;
27 import java.awt.dnd.DnDConstants;
28 import java.awt.dnd.DropTarget;
29 import java.awt.dnd.DropTargetContext;
30 import java.awt.dnd.DropTargetDragEvent;
31 import java.awt.dnd.DropTargetDropEvent;
32 import java.awt.dnd.DropTargetEvent;
33 import java.awt.dnd.DropTargetListener;
34 import java.io.IOException;
35 import javax.swing.JTree;
36 import javax.swing.tree.DefaultTreeModel;
37 import javax.swing.tree.MutableTreeNode;
38 import javax.swing.tree.TreePath;
39 import org.jetbrains.annotations.NotNull;
56 public void dragEnter(@NotNull
final DropTargetDragEvent dtde) {
61 public void dragOver(@NotNull
final DropTargetDragEvent dtde) {
66 public void dropActionChanged(@NotNull
final DropTargetDragEvent dtde) {
71 public void dragExit(@NotNull
final DropTargetEvent dte) {
76 public void drop(@NotNull
final DropTargetDropEvent dtde) {
77 final Point location = dtde.getLocation();
78 final DropTargetContext dropTargetContext = dtde.getDropTargetContext();
79 final JTree tree = (JTree) dropTargetContext.getComponent();
80 final TreePath parentTreePath = tree.getClosestPathForLocation(location.x, location.y);
81 final MutableTreeNode parentTreeNode = (MutableTreeNode) parentTreePath.getLastPathComponent();
83 final int dropAction = dtde.getDropAction();
84 if (dropAction != DnDConstants.ACTION_COPY && dropAction != DnDConstants.ACTION_MOVE) {
90 final Transferable transferable = dtde.getTransferable();
91 final DataFlavor[] flavors = transferable.getTransferDataFlavors();
92 for (
final DataFlavor flavor : flavors) {
93 if (transferable.isDataFlavorSupported(flavor)) {
94 dtde.acceptDrop(dropAction);
95 final Rectangle parentRectangle = tree.getPathBounds(parentTreePath);
96 final int relativeY = location.y - parentRectangle.y;
97 final TreePath treePath = (TreePath) transferable.getTransferData(flavor);
98 final MutableTreeNode draggedTreeNode = (MutableTreeNode) treePath.getLastPathComponent();
99 final DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();
100 final MutableTreeNode parent;
102 if (parentTreeNode == treeModel.getRoot()) {
105 parent = parentTreeNode;
107 }
else if (!parentTreeNode.getAllowsChildren()) {
109 parent = (MutableTreeNode) parentTreeNode.getParent();
110 assert parent !=
null;
111 if (relativeY < parentRectangle.height / 2) {
113 index = treeModel.getIndexOfChild(parent, parentTreeNode);
116 index = treeModel.getIndexOfChild(parent, parentTreeNode) + 1;
118 }
else if (tree.isExpanded(parentTreePath)) {
120 if (relativeY < parentRectangle.height / 2) {
122 parent = (MutableTreeNode) parentTreeNode.getParent();
123 assert parent !=
null;
124 index = treeModel.getIndexOfChild(parent, parentTreeNode);
127 parent = parentTreeNode;
132 if (relativeY < parentRectangle.height / 4) {
134 parent = (MutableTreeNode) parentTreeNode.getParent();
135 assert parent !=
null;
136 index = treeModel.getIndexOfChild(parent, parentTreeNode);
137 }
else if (relativeY >= parentRectangle.height * 3 / 4) {
139 parent = (MutableTreeNode) parentTreeNode.getParent();
140 assert parent !=
null;
141 index = treeModel.getIndexOfChild(parent, parentTreeNode) + 1;
144 parent = parentTreeNode;
145 index = parent.getChildCount();
148 treeModel.insertNodeInto(draggedTreeNode, parent, index);
149 tree.setSelectionPath(
new TreePath(treeModel.getPathToRoot(draggedTreeNode)));
150 dtde.dropComplete(
true);
154 }
catch (
final IOException | UnsupportedFlavorException ignored) {
176 final int dragOperation = dtde.getDropAction();
177 switch (dragOperation) {
178 case DnDConstants.ACTION_COPY:
179 case DnDConstants.ACTION_MOVE:
180 dtde.acceptDrag(dragOperation);