PageRenderTime 26ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/com/atlassian/uwc/ui/organizer/DNDTreeTargetListener.java

https://bitbucket.org/atlassianlabs/universal-wiki-connector
Java | 298 lines | 224 code | 72 blank | 2 comment | 23 complexity | f4b4ca3702e950da1461e7254ca2964e MD5 | raw file
  1. package com.atlassian.uwc.ui.organizer;
  2. import java.awt.AlphaComposite;
  3. import java.awt.Color;
  4. import java.awt.Graphics;
  5. import java.awt.Graphics2D;
  6. import java.awt.Insets;
  7. import java.awt.Point;
  8. import java.awt.Rectangle;
  9. import java.awt.dnd.DnDConstants;
  10. import java.awt.dnd.DropTarget;
  11. import java.awt.dnd.DropTargetDragEvent;
  12. import java.awt.dnd.DropTargetDropEvent;
  13. import java.awt.image.BufferedImage;
  14. import javax.swing.JComponent;
  15. import javax.swing.JTree;
  16. import javax.swing.tree.DefaultMutableTreeNode;
  17. import javax.swing.tree.DefaultTreeModel;
  18. import javax.swing.tree.MutableTreeNode;
  19. import javax.swing.tree.TreeCellRenderer;
  20. import javax.swing.tree.TreePath;
  21. public class DNDTreeTargetListener extends DropTarget {
  22. private TreePath sourceNodePath;
  23. private Rectangle lastDragOverRowBounds;
  24. private Rectangle lastDragImageArea;
  25. private Point lastDragLocation;
  26. public DNDTreeTargetListener() {
  27. super();
  28. }
  29. private TreePath getSourceNodePath() {
  30. return sourceNodePath;
  31. }
  32. public void setSourceNodePath(TreePath aPath) {
  33. sourceNodePath = aPath;
  34. }
  35. private DefaultMutableTreeNode getTargetParentNode(JTree aTree) {
  36. if (aTree.getSelectionPath() != null) {
  37. return (DefaultMutableTreeNode)aTree.getSelectionPath().getLastPathComponent();
  38. }
  39. Point location = ((DNDTreeTargetListener)aTree.getDropTarget()).getLastDragLocation();
  40. TreePath path = aTree.getClosestPathForLocation(location.x, location.y);
  41. MutableTreeNode targetNode = (MutableTreeNode)path.getLastPathComponent();
  42. return (DefaultMutableTreeNode)targetNode.getParent();
  43. }
  44. public void dragOver(DropTargetDragEvent anEvent) {
  45. JTree tree = (JTree)anEvent.getDropTargetContext().getComponent();
  46. Point eventLocation = anEvent.getLocation();
  47. DefaultMutableTreeNode targetParentNode = getTargetParentNode(tree);
  48. DefaultMutableTreeNode sourceNode =
  49. (DefaultMutableTreeNode)getSourceNodePath().getLastPathComponent();
  50. // Check if source node is a child of target
  51. if (sourceNode.isNodeDescendant(targetParentNode)) {
  52. anEvent.rejectDrag();
  53. clearImage(tree);
  54. } else {
  55. anEvent.acceptDrag(DnDConstants.ACTION_MOVE);
  56. updateDragImage(tree, eventLocation);
  57. }
  58. updateScrolling(tree, eventLocation);
  59. updateDragMarker(tree, eventLocation);
  60. super.dragOver(anEvent);
  61. }
  62. private void updateDragImage(JTree aTree, Point aPoint) {
  63. BufferedImage dragImage = getDragImage(aTree, getSourceNodePath());
  64. if (dragImage == null) {
  65. return;
  66. }
  67. //Clear the last drag image.
  68. aTree.paintImmediately(getLastDragImageArea().getBounds());
  69. getLastDragImageArea().setRect(
  70. (int)aPoint.getX(),
  71. (int)aPoint.getY() - 17,
  72. dragImage.getWidth(),
  73. dragImage.getHeight());
  74. aTree.getGraphics().drawImage(
  75. dragImage,
  76. (int)aPoint.getX(),
  77. (int)aPoint.getY() - 17,
  78. aTree);
  79. }
  80. public BufferedImage getDragImage(JTree aTree, TreePath aNodeToDraw) {
  81. BufferedImage image = null;
  82. try {
  83. Rectangle nodeBounds = aTree.getPathBounds(aNodeToDraw);
  84. TreeCellRenderer treeRenderer = aTree.getCellRenderer();
  85. DefaultTreeModel treeModel = (DefaultTreeModel)aTree.getModel();
  86. boolean nIsLeaf = treeModel.isLeaf(aNodeToDraw.getLastPathComponent());
  87. JComponent node = (JComponent)treeRenderer.getTreeCellRendererComponent(
  88. aTree,
  89. aNodeToDraw.getLastPathComponent(),
  90. false,
  91. aTree.isExpanded(aNodeToDraw),
  92. nIsLeaf,
  93. 0,
  94. false);
  95. node.setBounds(nodeBounds);
  96. image = new BufferedImage(
  97. node.getWidth(),
  98. node.getHeight(),
  99. java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE);
  100. Graphics2D graphics = image.createGraphics();
  101. graphics.setComposite(AlphaComposite.getInstance(
  102. AlphaComposite.SRC_OVER, 0.75f));
  103. node.setOpaque(false);
  104. node.paint(graphics);
  105. graphics.dispose();
  106. } catch (RuntimeException re) {
  107. return null;
  108. }
  109. return image;
  110. }
  111. private Rectangle getLastDragImageArea() {
  112. if (lastDragImageArea == null) {
  113. lastDragImageArea = new Rectangle();
  114. }
  115. return lastDragImageArea;
  116. }
  117. private void updateScrolling(JTree aTree, Point aCursorLocation) {
  118. Insets autoScrollInsets = new Insets(20, 20, 20, 20);
  119. Rectangle outer = aTree.getVisibleRect();
  120. Rectangle inner = new Rectangle(
  121. outer.x + autoScrollInsets.left,
  122. outer.y + autoScrollInsets.top,
  123. outer.width - (autoScrollInsets.left + autoScrollInsets.right),
  124. outer.height - (autoScrollInsets.top + autoScrollInsets.bottom));
  125. if (!inner.contains(aCursorLocation)) {
  126. Rectangle scrollRect = new Rectangle(
  127. aCursorLocation.x - autoScrollInsets.left,
  128. aCursorLocation.y - autoScrollInsets.top,
  129. autoScrollInsets.left + autoScrollInsets.right,
  130. autoScrollInsets.top + autoScrollInsets.bottom);
  131. aTree.scrollRectToVisible(scrollRect);
  132. }
  133. }
  134. public void updateDragMarker(JTree aTree, Point aLocation) {
  135. setLastDragLocation(aLocation);
  136. int row = aTree.getRowForPath(
  137. aTree.getClosestPathForLocation(
  138. aLocation.x,
  139. aLocation.y));
  140. TreePath path = aTree.getPathForRow(row);
  141. if (path == null) {
  142. return;
  143. }
  144. Rectangle rowBounds = aTree.getPathBounds(path);
  145. int rby = rowBounds.y;
  146. int topBottomDist = 6;
  147. Point topBottom = new Point(
  148. rby - topBottomDist,
  149. rby + topBottomDist);
  150. if (topBottom.x <= aLocation.y &&
  151. topBottom.y >= aLocation.y) {
  152. paintInsertMarker(aTree, aLocation);
  153. } else {
  154. markNode(aTree, aLocation);
  155. }
  156. }
  157. private void markNode(JTree aTree, Point aLocation) {
  158. TreePath path = aTree.getClosestPathForLocation(aLocation.x, aLocation.y);
  159. if (path == null) {
  160. return;
  161. }
  162. if (getLastDragOverRowBounds() != null) {
  163. Graphics g = aTree.getGraphics();
  164. g.setColor(Color.white);
  165. g.drawLine(
  166. getLastDragOverRowBounds().x,
  167. getLastDragOverRowBounds().y,
  168. getLastDragOverRowBounds().x + getLastDragOverRowBounds().width,
  169. getLastDragOverRowBounds().y);
  170. }
  171. aTree.setSelectionPath(path);
  172. aTree.expandPath(path);
  173. }
  174. private void paintInsertMarker(JTree aTree, Point aLocation) {
  175. Graphics g = aTree.getGraphics();
  176. aTree.clearSelection();
  177. int row = aTree.getRowForPath(aTree.getClosestPathForLocation(
  178. aLocation.x,
  179. aLocation.y));
  180. TreePath path = aTree.getPathForRow(row);
  181. if (path == null) {
  182. return;
  183. }
  184. Rectangle rowBounds = aTree.getPathBounds(path);
  185. if (getLastDragOverRowBounds() != null) {
  186. g.setColor(Color.white);
  187. g.drawLine(
  188. getLastDragOverRowBounds().x,
  189. getLastDragOverRowBounds().y,
  190. getLastDragOverRowBounds().x + getLastDragOverRowBounds().width,
  191. getLastDragOverRowBounds().y);
  192. }
  193. if (rowBounds != null) {
  194. g.setColor(Color.black);
  195. g.drawLine(
  196. rowBounds.x,
  197. rowBounds.y,
  198. rowBounds.x + rowBounds.width,
  199. rowBounds.y);
  200. }
  201. setLastDragOverRowBounds(rowBounds);
  202. }
  203. private Rectangle getLastDragOverRowBounds() {
  204. return lastDragOverRowBounds;
  205. }
  206. private void setLastDragOverRowBounds(Rectangle aRowBounds) {
  207. lastDragOverRowBounds = aRowBounds;
  208. }
  209. public Point getLastDragLocation() {
  210. return lastDragLocation;
  211. }
  212. private void setLastDragLocation(Point aLocation) {
  213. lastDragLocation = aLocation;
  214. }
  215. public void dragExit(DropTargetDragEvent anEvent) {
  216. clearImage((JTree)anEvent.getDropTargetContext().getComponent());
  217. super.dragExit(anEvent);
  218. }
  219. public void drop(DropTargetDropEvent anEvent) {
  220. clearImage((JTree)anEvent.getDropTargetContext().getComponent());
  221. super.drop(anEvent);
  222. }
  223. private final void clearImage(JTree tree) {
  224. tree.paintImmediately(getLastDragImageArea().getBounds());
  225. }
  226. }