View Javadoc

1   /*
2    * jcurl java curling software framework https://JCurl.mro.name
3    * Copyright (C) 2005-2009 M. Rohrmoser
4    * 
5    * This program is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License as published by the
7    * Free Software Foundation; either version 2 of the License, or (at your
8    * option) any later version.
9    * 
10   * This program is distributed in the hope that it will be useful, but
11   * WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13   * Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License along
16   * with this program; if not, write to the Free Software Foundation, Inc.,
17   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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   * http://forum.java.sun.com/thread.jspa?threadID=296255&start=0
48   * 
49   * @author <a href="http://forum.java.sun.com/profile.jspa?userID=82795">Deudeu</a>
50   * @version $Id: AbstractTreeTransferHandler.java 776 2008-03-16 10:17:28Z
51   *          mrohrmoser $
52   */
53  public abstract class AbstractTreeTransferHandler implements
54  		DragGestureListener, DragSourceListener, DropTargetListener {
55  
56  	private static DefaultMutableTreeNode draggedNode;
57  	private static BufferedImage image = null; // buff image
58  	private DefaultMutableTreeNode draggedNodeParent;
59  	private final DragSource dragSource; // dragsource
60  	private final boolean drawImage;
61  	private final DropTarget 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  	/* Methods for DragSourceListener */
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 	/* Methods for DropTargetListener */
116 	public final void dragExit(final DropTargetEvent dte) {
117 		if (drawImage)
118 			clearImage();
119 	}
120 
121 	/* Methods for DragGestureListener */
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); // getpathbounds
130 				// of
131 				// selectionpath
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);// returning the label
141 				lbl.setBounds(pathBounds);// setting bounds to lbl
142 				image = new BufferedImage(lbl.getWidth(), lbl.getHeight(),
143 						java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE);// buffered
144 				// image
145 				// reference
146 				// passing
147 				// the
148 				// label's
149 				// ht
150 				// and
151 				// width
152 				final Graphics2D graphics = image.createGraphics();// creating
153 				// the
154 				// graphics
155 				// for
156 				// buffered
157 				// image
158 				graphics.setComposite(AlphaComposite.getInstance(
159 						AlphaComposite.SRC_OVER, 0.5f)); // Sets the
160 				// Composite for the
161 				// Graphics2D
162 				// context
163 				lbl.setOpaque(false);
164 				lbl.paint(graphics); // painting the graphics to label
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 }