1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.jcurl.demo.jtree;
20
21 import java.awt.AlphaComposite;
22 import java.awt.Graphics2D;
23 import java.awt.Point;
24 import java.awt.Rectangle;
25 import java.awt.datatransfer.Transferable;
26 import java.awt.dnd.DnDConstants;
27 import java.awt.dnd.DragGestureEvent;
28 import java.awt.dnd.DragGestureListener;
29 import java.awt.dnd.DragSource;
30 import java.awt.dnd.DragSourceDragEvent;
31 import java.awt.dnd.DragSourceDropEvent;
32 import java.awt.dnd.DragSourceEvent;
33 import java.awt.dnd.DragSourceListener;
34 import java.awt.dnd.DropTarget;
35 import java.awt.dnd.DropTargetDragEvent;
36 import java.awt.dnd.DropTargetDropEvent;
37 import java.awt.dnd.DropTargetEvent;
38 import java.awt.dnd.DropTargetListener;
39 import java.awt.image.BufferedImage;
40
41 import javax.swing.JComponent;
42 import javax.swing.tree.DefaultMutableTreeNode;
43 import javax.swing.tree.DefaultTreeModel;
44 import javax.swing.tree.TreePath;
45
46
47
48
49
50
51
52
53 public abstract class AbstractTreeTransferHandler implements
54 DragGestureListener, DragSourceListener, DropTargetListener {
55
56 private static DefaultMutableTreeNode draggedNode;
57 private static BufferedImage image = null;
58 private DefaultMutableTreeNode draggedNodeParent;
59 private final DragSource dragSource;
60 private final boolean drawImage;
61 private final DropTarget dropTarget;
62 private final Rectangle rect2D = new Rectangle();
63 private final DNDTree tree;
64
65 protected AbstractTreeTransferHandler(final DNDTree tree, final int action,
66 final boolean drawIcon) {
67 this.tree = tree;
68 drawImage = drawIcon;
69 dragSource = new DragSource();
70 dragSource.createDefaultDragGestureRecognizer(tree, action, this);
71 dropTarget = new DropTarget(tree, action, this);
72 }
73
74 public abstract boolean canPerformAction(DNDTree target,
75 DefaultMutableTreeNode draggedNode, int action, Point location);
76
77 private final void clearImage() {
78 tree.paintImmediately(rect2D.getBounds());
79 }
80
81
82 public void dragDropEnd(final DragSourceDropEvent dsde) {
83 if (dsde.getDropSuccess()
84 && dsde.getDropAction() == DnDConstants.ACTION_MOVE
85 && draggedNodeParent != null)
86 ((DefaultTreeModel) tree.getModel())
87 .nodeStructureChanged(draggedNodeParent);
88 }
89
90 public final void dragEnter(final DragSourceDragEvent dsde) {
91 final int action = dsde.getDropAction();
92 if (action == DnDConstants.ACTION_COPY)
93 dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop);
94 else if (action == DnDConstants.ACTION_MOVE)
95 dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop);
96 else
97 dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
98 }
99
100 public final void dragEnter(final DropTargetDragEvent dtde) {
101 final Point pt = dtde.getLocation();
102 final int action = dtde.getDropAction();
103 if (drawImage)
104 paintImage(pt);
105 if (canPerformAction(tree, draggedNode, action, pt))
106 dtde.acceptDrag(action);
107 else
108 dtde.rejectDrag();
109 }
110
111 public final void dragExit(final DragSourceEvent dse) {
112 dse.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
113 }
114
115
116 public final void dragExit(final DropTargetEvent dte) {
117 if (drawImage)
118 clearImage();
119 }
120
121
122 public final void dragGestureRecognized(final DragGestureEvent dge) {
123 final TreePath path = tree.getSelectionPath();
124 if (path != null) {
125 draggedNode = (DefaultMutableTreeNode) path.getLastPathComponent();
126 draggedNodeParent = (DefaultMutableTreeNode) draggedNode
127 .getParent();
128 if (drawImage) {
129 final Rectangle pathBounds = tree.getPathBounds(path);
130
131
132 final JComponent lbl = (JComponent) tree.getCellRenderer()
133 .getTreeCellRendererComponent(
134 tree,
135 draggedNode,
136 false,
137 tree.isExpanded(path),
138 ((DefaultTreeModel) tree.getModel())
139 .isLeaf(path.getLastPathComponent()),
140 0, false);
141 lbl.setBounds(pathBounds);
142 image = new BufferedImage(lbl.getWidth(), lbl.getHeight(),
143 java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE);
144
145
146
147
148
149
150
151
152 final Graphics2D graphics = image.createGraphics();
153
154
155
156
157
158 graphics.setComposite(AlphaComposite.getInstance(
159 AlphaComposite.SRC_OVER, 0.5f));
160
161
162
163 lbl.setOpaque(false);
164 lbl.paint(graphics);
165 graphics.dispose();
166 }
167 dragSource.startDrag(dge, DragSource.DefaultMoveNoDrop, image,
168 new Point(0, 0), new TransferableNode(draggedNode), this);
169 }
170 }
171
172 public final void dragOver(final DragSourceDragEvent dsde) {
173 final int action = dsde.getDropAction();
174 if (action == DnDConstants.ACTION_COPY)
175 dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop);
176 else if (action == DnDConstants.ACTION_MOVE)
177 dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop);
178 else
179 dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
180 }
181
182 public final void dragOver(final DropTargetDragEvent dtde) {
183 final Point pt = dtde.getLocation();
184 final int action = dtde.getDropAction();
185 tree.autoscroll(pt);
186 if (drawImage)
187 paintImage(pt);
188 if (canPerformAction(tree, draggedNode, action, pt))
189 dtde.acceptDrag(action);
190 else
191 dtde.rejectDrag();
192 }
193
194 public final void drop(final DropTargetDropEvent dtde) {
195 try {
196 if (drawImage)
197 clearImage();
198 final int action = dtde.getDropAction();
199 final Transferable transferable = dtde.getTransferable();
200 final Point pt = dtde.getLocation();
201 if (transferable
202 .isDataFlavorSupported(TransferableNode.NODE_FLAVOR)
203 && canPerformAction(tree, draggedNode, action, pt)) {
204 final TreePath pathTarget = tree.getPathForLocation(pt.x, pt.y);
205 final DefaultMutableTreeNode node = (DefaultMutableTreeNode) transferable
206 .getTransferData(TransferableNode.NODE_FLAVOR);
207 final DefaultMutableTreeNode newParentNode = (DefaultMutableTreeNode) pathTarget
208 .getLastPathComponent();
209 if (executeDrop(tree, node, newParentNode, action)) {
210 dtde.acceptDrop(action);
211 dtde.dropComplete(true);
212 return;
213 }
214 }
215 dtde.rejectDrop();
216 dtde.dropComplete(false);
217 } catch (final Exception e) {
218 System.out.println(e);
219 dtde.rejectDrop();
220 dtde.dropComplete(false);
221 }
222 }
223
224 public final void dropActionChanged(final DragSourceDragEvent dsde) {
225 final int action = dsde.getDropAction();
226 if (action == DnDConstants.ACTION_COPY)
227 dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop);
228 else if (action == DnDConstants.ACTION_MOVE)
229 dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop);
230 else
231 dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
232 }
233
234 public final void dropActionChanged(final DropTargetDragEvent dtde) {
235 final Point pt = dtde.getLocation();
236 final int action = dtde.getDropAction();
237 if (drawImage)
238 paintImage(pt);
239 if (canPerformAction(tree, draggedNode, action, pt))
240 dtde.acceptDrag(action);
241 else
242 dtde.rejectDrag();
243 }
244
245 public abstract boolean executeDrop(DNDTree tree,
246 DefaultMutableTreeNode draggedNode,
247 DefaultMutableTreeNode newParentNode, int action);
248
249 private final void paintImage(final Point pt) {
250 tree.paintImmediately(rect2D.getBounds());
251 rect2D.setRect((int) pt.getX(), (int) pt.getY(), image.getWidth(),
252 image.getHeight());
253 tree.getGraphics().drawImage(image, (int) pt.getX(), (int) pt.getY(),
254 tree);
255 }
256 }