001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.client.util.bookmark;
019:
020: import java.awt.AlphaComposite;
021: import java.awt.Graphics2D;
022: import java.awt.Point;
023: import java.awt.Rectangle;
024: import java.awt.datatransfer.Transferable;
025: import java.awt.dnd.DnDConstants;
026: import java.awt.dnd.DragGestureEvent;
027: import java.awt.dnd.DragGestureListener;
028: import java.awt.dnd.DragSource;
029: import java.awt.dnd.DragSourceDragEvent;
030: import java.awt.dnd.DragSourceDropEvent;
031: import java.awt.dnd.DragSourceEvent;
032: import java.awt.dnd.DragSourceListener;
033: import java.awt.dnd.DropTarget;
034: import java.awt.dnd.DropTargetDragEvent;
035: import java.awt.dnd.DropTargetDropEvent;
036: import java.awt.dnd.DropTargetEvent;
037: import java.awt.dnd.DropTargetListener;
038: import java.awt.image.BufferedImage;
039:
040: import javax.swing.JComponent;
041: import javax.swing.tree.DefaultMutableTreeNode;
042: import javax.swing.tree.DefaultTreeModel;
043: import javax.swing.tree.TreePath;
044:
045: public abstract class AbstractTreeTransferHandler implements
046: DragGestureListener, DragSourceListener, DropTargetListener {
047:
048: private BookmarkTree tree;
049:
050: private DragSource dragSource; // dragsource
051:
052: private DropTarget dropTarget; // droptarget
053:
054: private static DefaultMutableTreeNode draggedNode;
055:
056: private DefaultMutableTreeNode draggedNodeParent;
057:
058: private static BufferedImage image = null; // buff image
059:
060: private Rectangle rect2D = new Rectangle();
061:
062: private boolean drawImage;
063:
064: // TODO benötigt ? :
065: // This flavor is used internally to transfer a ContelligentComponent[] that
066: // we dont want to be recognized by the usual drop targets for it.
067: //private static final DataFlavor concealedFlavor = new DataFlavor(AbstractTreeTransferHandler.class, "Concealed components");
068:
069: protected AbstractTreeTransferHandler(BookmarkTree tree,
070: int action, boolean drawIcon) {
071:
072: this .tree = tree;
073:
074: drawImage = drawIcon;
075: dragSource = new DragSource();
076: dragSource.createDefaultDragGestureRecognizer(tree, action,
077: this );
078: dropTarget = new DropTarget(tree, action, this );
079: }
080:
081: /* Methods for DragSourceListener */
082: public void dragDropEnd(DragSourceDropEvent dsde) {
083:
084: if (dsde.getDropSuccess()
085: && dsde.getDropAction() == DnDConstants.ACTION_MOVE
086: && draggedNodeParent != null) {
087:
088: ((DefaultTreeModel) tree.getModel())
089: .nodeStructureChanged(draggedNodeParent);
090:
091: tree.expandPath(new TreePath(draggedNodeParent.getPath()));
092: tree.expandPath(new TreePath(draggedNode.getPath()));
093: }
094: }
095:
096: public final void dragEnter(DragSourceDragEvent dsde) {
097:
098: int action = dsde.getDropAction();
099:
100: if (action == DnDConstants.ACTION_COPY) {
101: dsde.getDragSourceContext().setCursor(
102: DragSource.DefaultCopyDrop);
103: } else {
104: if (action == DnDConstants.ACTION_MOVE) {
105: dsde.getDragSourceContext().setCursor(
106: DragSource.DefaultMoveDrop);
107: } else {
108: dsde.getDragSourceContext().setCursor(
109: DragSource.DefaultMoveNoDrop);
110: }
111: }
112: }
113:
114: public final void dragOver(DragSourceDragEvent dsde) {
115:
116: int action = dsde.getDropAction();
117:
118: if (action == DnDConstants.ACTION_COPY) {
119: dsde.getDragSourceContext().setCursor(
120: DragSource.DefaultCopyDrop);
121: } else {
122: if (action == DnDConstants.ACTION_MOVE) {
123: dsde.getDragSourceContext().setCursor(
124: DragSource.DefaultMoveDrop);
125: } else {
126: dsde.getDragSourceContext().setCursor(
127: DragSource.DefaultMoveNoDrop);
128: }
129: }
130: }
131:
132: public final void dropActionChanged(DragSourceDragEvent dsde) {
133:
134: int action = dsde.getDropAction();
135:
136: if (action == DnDConstants.ACTION_COPY) {
137: dsde.getDragSourceContext().setCursor(
138: DragSource.DefaultCopyDrop);
139: } else {
140: if (action == DnDConstants.ACTION_MOVE) {
141: dsde.getDragSourceContext().setCursor(
142: DragSource.DefaultMoveDrop);
143: } else {
144: dsde.getDragSourceContext().setCursor(
145: DragSource.DefaultMoveNoDrop);
146: }
147: }
148: }
149:
150: public final void dragExit(DragSourceEvent dse) {
151: dse.getDragSourceContext().setCursor(
152: DragSource.DefaultMoveNoDrop);
153: }
154:
155: /* Methods for DragGestureListener */
156: public final void dragGestureRecognized(DragGestureEvent dge) {
157:
158: TreePath path = tree.getSelectionPath();
159:
160: if (path != null) {
161: draggedNode = (DefaultMutableTreeNode) path
162: .getLastPathComponent();
163: draggedNodeParent = (DefaultMutableTreeNode) draggedNode
164: .getParent();
165:
166: if (drawImage) {
167: Rectangle pathBounds = tree.getPathBounds(path); // getpathbounds of selectionpath
168:
169: JComponent lbl = (JComponent) tree
170: .getCellRenderer()
171: .getTreeCellRendererComponent(
172: tree,
173: draggedNode,
174: false,
175: tree.isExpanded(path),
176: ((DefaultTreeModel) tree.getModel())
177: .isLeaf(path
178: .getLastPathComponent()),
179: 0, false);// returning the label
180: lbl.setBounds(pathBounds);// setting bounds to lbl
181:
182: image = new BufferedImage(lbl.getWidth(), lbl
183: .getHeight(),
184: java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE);// buffered image reference passing the label's ht and width
185:
186: Graphics2D graphics = image.createGraphics();// creating the graphics for buffered image
187: graphics.setComposite(AlphaComposite.getInstance(
188: AlphaComposite.SRC_OVER, 0.5f)); // Sets the Composite for the Graphics2D context
189:
190: lbl.setOpaque(false);
191: lbl.paint(graphics); // painting the graphics to label
192:
193: graphics.dispose();
194: }
195: dragSource.startDrag(dge, DragSource.DefaultMoveNoDrop,
196: image, new Point(0, 0), new TransferableNode(
197: draggedNode), this );
198: }
199: }
200:
201: /* Methods for DropTargetListener */
202: public final void dragEnter(DropTargetDragEvent dtde) {
203:
204: Point pt = dtde.getLocation();
205: int action = dtde.getDropAction();
206:
207: if (drawImage) {
208: paintImage(pt);
209: }
210: if (canPerformAction(tree, draggedNode, action, pt)) {
211: dtde.acceptDrag(action);
212: } else {
213: dtde.rejectDrag();
214: }
215: }
216:
217: public final void dragExit(DropTargetEvent dte) {
218:
219: if (drawImage) {
220: clearImage();
221: }
222: }
223:
224: public final void dragOver(DropTargetDragEvent dtde) {
225:
226: Point pt = dtde.getLocation();
227: int action = dtde.getDropAction();
228: tree.autoscroll(pt);
229:
230: if (drawImage) {
231: paintImage(pt);
232: }
233: if (canPerformAction(tree, draggedNode, action, pt)) {
234:
235: //A////////////////////////////////////////////
236: // Point p = dtde.getLocation();
237: // int scrollSpeed = 20;
238: // Rectangle r = new Rectangle(p.x, p.y - scrollSpeed, 1, scrollSpeed * 2);
239: // tree.scrollRectToVisible(r);
240: // int dropRow = tree.getRowForLocation(p.x, p.y);
241: // int firstDragged = 0;
242: // if (tree.getSelectionCount() == 1) {
243: // firstDragged = tree.getSelectionRows()[0];
244: // } else if (tree.getSelectionCount() > 1) {
245: //
246: // int[] selectedRows = tree.getSelectionRows();
247: // firstDragged = selectedRows[0];
248: // }
249: // tree.setHighlightedRow(dropRow, (dropRow > firstDragged));
250: //
251: // //dtde.acceptDrag(sourceActions);
252: //E////////////////////////////////////////////
253:
254: dtde.acceptDrag(action);
255:
256: } else {
257:
258: //A////////////////////////////////////////////
259: // tree.setHighlightedRow(-1, false);
260: //E////////////////////////////////////////////
261:
262: dtde.rejectDrag();
263: }
264:
265: //A////////////////////////////////////////////
266: // TODO
267:
268: // if (isDragOK(dtde)) {
269: // Point p = dtde.getLocation();
270: // int scrollSpeed = 20;
271: // Rectangle r = new Rectangle(p.x, p.y - scrollSpeed, 1, scrollSpeed * 2);
272: // folderTable.scrollRectToVisible(r);
273: // int dropRow = folderTable.rowAtPoint(p);
274: // int firstDragged = 0;
275: // if (folderTable.getSelectedRowCount() == 1) {
276: // firstDragged = folderTable.getSelectedRow();
277: // } else if (folderTable.getSelectedRowCount() > 1) {
278: // int[] selectedRows = folderTable.getSelectedRows();
279: // firstDragged = selectedRows[0];
280: // }
281: // folderTable.setHighlightedRow(dropRow, (dropRow > firstDragged));
282: // dtde.acceptDrag(sourceActions);
283: // } else {
284: // folderTable.setHighlightedRow(-1, false);
285: // dtde.rejectDrag();
286: // }
287:
288: //E////////////////////////////////////////////
289: }
290:
291: public final void dropActionChanged(DropTargetDragEvent dtde) {
292:
293: Point pt = dtde.getLocation();
294: int action = dtde.getDropAction();
295:
296: if (drawImage) {
297: paintImage(pt);
298: }
299: if (canPerformAction(tree, draggedNode, action, pt)) {
300: dtde.acceptDrag(action);
301: } else {
302: dtde.rejectDrag();
303: }
304: }
305:
306: public final void drop(DropTargetDropEvent dtde) {
307: try {
308: if (drawImage) {
309: clearImage();
310: }
311:
312: int action = dtde.getDropAction();
313: Transferable transferable = dtde.getTransferable();
314: Point pt = dtde.getLocation();
315:
316: if (transferable
317: .isDataFlavorSupported(TransferableNode.NODE_FLAVOR)
318: && canPerformAction(tree, draggedNode, action, pt)) {
319:
320: TreePath pathTarget = tree.getPathForLocation(pt.x,
321: pt.y);
322: DefaultMutableTreeNode node = (DefaultMutableTreeNode) transferable
323: .getTransferData(TransferableNode.NODE_FLAVOR);
324:
325: DefaultMutableTreeNode newParentNode = (DefaultMutableTreeNode) pathTarget
326: .getLastPathComponent();
327: if (executeDrop(tree, node, newParentNode, action)) {
328: dtde.acceptDrop(action);
329: dtde.dropComplete(true);
330:
331: return;
332: }
333: }
334: dtde.rejectDrop();
335: dtde.dropComplete(false);
336:
337: } catch (Exception e) {
338: dtde.rejectDrop();
339: dtde.dropComplete(false);
340: }
341: }
342:
343: private final void paintImage(Point pt) {
344: tree.paintImmediately(rect2D.getBounds());
345: rect2D.setRect((int) pt.getX(), (int) pt.getY(), image
346: .getWidth(), image.getHeight());
347: tree.getGraphics().drawImage(image, (int) pt.getX(),
348: (int) pt.getY(), tree);
349: }
350:
351: private final void clearImage() {
352: tree.paintImmediately(rect2D.getBounds());
353: }
354:
355: public abstract boolean canPerformAction(BookmarkTree target,
356: DefaultMutableTreeNode draggedNode, int action,
357: Point location);
358:
359: public abstract boolean executeDrop(BookmarkTree tree,
360: DefaultMutableTreeNode draggedNode,
361: DefaultMutableTreeNode newParentNode, int action);
362: }
|