| 1 package org.antlr.xjlib.appkit.swing; 2 3 import javax.swing.*; 4 import javax.swing.tree.DefaultMutableTreeNode ; 5 import javax.swing.tree.TreePath ; 6 import java.awt.*; 7 import java.awt.datatransfer.Transferable ; 8 import java.awt.dnd.*; 9 import java.awt.event.ActionEvent ; 10 import java.awt.event.ActionListener ; 11 import java.awt.event.MouseEvent ; 12 import java.awt.image.BufferedImage ; 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 46 47 53 54 public class XJTree extends JTree implements DragGestureListener, DropTargetListener, DragSourceListener, Autoscroll { 55 56 protected XJTreeDelegate delegate; 57 protected DragSource dragSource; 58 protected TreePath oldSelectedPath; 59 60 protected Timer autoExpandTimer; 61 protected TreePath lastPath; 62 protected Point lastPoint = new Point(); 63 protected Rectangle cueLine = new Rectangle(); 64 65 protected BufferedImage dragImage; 66 protected Point dragImageOffset = new Point(); 67 68 protected final int AUTOSCROLL_MARGIN = 12; 69 70 protected int dropLocation; 71 public static final int DROP_ABOVE = 0; 72 public static final int DROP_ONTO = 1; 73 public static final int DROP_BELOW = 2; 74 75 public XJTree() { 76 super(); 77 autoExpandTimer = new Timer(1000, new ActionListener () { 78 public void actionPerformed(ActionEvent e) { 79 if(isRootVisible() && getRowForPath(lastPath) == 0) { 80 return; 82 } 83 84 if(isExpanded(lastPath)) 85 collapsePath(lastPath); 86 else 87 expandPath(lastPath); 88 } 89 }); 90 autoExpandTimer.setRepeats(false); 91 } 92 93 public void setDelegate(XJTreeDelegate delegate) { 94 this.delegate = delegate; 95 } 96 97 public void setEnableDragAndDrop() { 98 dragSource = DragSource.getDefaultDragSource(); 99 dragSource.createDefaultDragGestureRecognizer(this, getDelegateConstants(), this); 100 new DropTarget(this, this); 101 } 102 103 public int getDelegateConstants() { 104 return delegate.xjTreeDragAndDropConstants(this); 105 } 106 107 public DefaultMutableTreeNode getOldSelectedNode() { 108 return (DefaultMutableTreeNode )oldSelectedPath.getLastPathComponent(); 109 } 110 111 public DefaultMutableTreeNode getSelectedNode() { 112 if(getSelectionPath() == null) 113 return null; 114 else 115 return (DefaultMutableTreeNode )getSelectionPath().getLastPathComponent(); 116 } 117 118 public List getSelectedNodes() { 119 List nodes = new ArrayList (); 120 if(getSelectionPaths() != null) { 121 for (int i = 0; i < getSelectionPaths().length; i++) { 122 TreePath treePath = getSelectionPaths()[i]; 123 nodes.add(treePath.getLastPathComponent()); 124 } 125 } 126 return nodes; 127 } 128 129 132 133 public void modifySelectionIfNecessary(MouseEvent me) { 134 boolean partOfSelection = false; 135 int row = getRowForLocation(me.getX(), me.getY()); 136 if(getSelectionRows() != null) { 137 for (int i = 0; i < getSelectionRows().length; i++) { 138 int selRow = getSelectionRows()[i]; 139 if(selRow == row) 140 partOfSelection = true; 141 } 142 } 143 144 if(!partOfSelection) 145 setSelectionRow(row); 146 } 147 148 protected void cleanUpAfterDrag() { 149 paintImmediately(cueLine); 150 } 151 152 154 public Insets getAutoscrollInsets() { 155 Rectangle outer = getBounds(); 156 Rectangle inner = getParent().getBounds(); 157 158 return new Insets(inner.y-outer.y+AUTOSCROLL_MARGIN, inner.x-outer.x+AUTOSCROLL_MARGIN, 159 outer.height-inner.height+AUTOSCROLL_MARGIN, 160 outer.width-inner.width+AUTOSCROLL_MARGIN); 161 } 162 163 public void autoscroll(Point point) { 164 int row = getRowForLocation(point.x, point.y); 165 if(row < 0) 166 return; 167 168 Rectangle outer = getBounds(); 169 if(point.y + outer.y <= AUTOSCROLL_MARGIN) 170 row = row <= 0 ? 0 : row - 1; 171 else 172 row = row < getRowCount() - 1 ? row + 1 : row; 173 174 scrollRowToVisible(row); 175 } 176 177 179 public void dragGestureRecognized(DragGestureEvent event) { 180 try { 181 createDragImage(event); 182 dragSource.startDrag(event, delegate.xjTreeDragSourceDefaultCursor(this), dragImage, new Point(5,5), (Transferable )getSelectedNode().getUserObject(), this); 183 } catch(Exception e) { 184 } 186 } 187 188 public void createDragImage(DragGestureEvent event) { 189 Point dragOrigin = event.getDragOrigin(); 190 TreePath path = getPathForLocation(dragOrigin.x, dragOrigin.y); 191 Rectangle r = getPathBounds(path); 192 dragImageOffset.setLocation(dragOrigin.x - r.x, dragOrigin.y - r.y); 193 194 JLabel label = (JLabel)getCellRenderer().getTreeCellRendererComponent(this, path.getLastPathComponent(), 195 false, isExpanded(path), getModel().isLeaf(path.getLastPathComponent()), 0, false); 196 label.setSize(r.width, r.height); 197 198 dragImage = new BufferedImage (r.width, r.height, BufferedImage.TYPE_INT_ARGB_PRE); 199 Graphics2D g2d = dragImage.createGraphics(); 200 g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.5f)); 201 label.paint(g2d); 202 g2d.dispose(); 203 } 204 205 207 public void dragEnter(DropTargetDragEvent event) { 208 oldSelectedPath = getSelectionPath(); 209 if(event.getDropAction() != getDelegateConstants()) { 210 cleanUpAfterDrag(); 211 event.rejectDrag(); 212 } else 213 event.acceptDrag(getDelegateConstants()); 214 } 215 216 public void dragOver(DropTargetDragEvent event) { 217 int x = event.getLocation().x; 218 int y = event.getLocation().y; 219 TreePath p = getClosestPathForLocation(x, y); 220 if(p != lastPath) { 221 lastPath = p; 222 autoExpandTimer.restart(); 223 } 224 225 if(p == null || event.getDropAction() != getDelegateConstants()) { 226 cleanUpAfterDrag(); 227 event.rejectDrag(); 228 } else { 229 event.acceptDrag(getDelegateConstants()); 230 231 Graphics2D g2d = (Graphics2D)getGraphics(); 232 Rectangle rpath = getPathBounds(lastPath); 233 Rectangle oldCueLine = (Rectangle) cueLine.clone(); 234 if(y < rpath.y + rpath.height/2) { 235 if(getRowForPath(lastPath) == 0) { 236 cueLine.setRect(0, rpath.y, getWidth(), 2); 237 } else { 238 cueLine.setRect(0, rpath.y - 1, getWidth(), 2); 239 } 240 dropLocation = DROP_ABOVE; 241 } else { 242 cueLine.setRect(0, rpath.y + rpath.height - 1, getWidth(), 2); 243 dropLocation = DROP_BELOW; 244 } 245 246 if(!oldCueLine.equals(cueLine)) { 247 paintImmediately(oldCueLine); 248 } 249 250 g2d.setColor(Color.black); 251 g2d.fill(cueLine); 252 } 253 } 254 255 public void dropActionChanged(DropTargetDragEvent event) { 256 if(event.getDropAction() != getDelegateConstants()) { 257 cleanUpAfterDrag(); 258 event.rejectDrag(); 259 } else 260 event.acceptDrag(getDelegateConstants()); 261 } 262 263 public void dragExit(DropTargetEvent dte) { 264 cleanUpAfterDrag(); 265 } 266 267 public void drop(DropTargetDropEvent event) { 268 autoExpandTimer.stop(); 269 270 int x = (int)event.getLocation().getX(); 271 int y = (int)event.getLocation().getY(); 272 int row = getRowForLocation(x, y); 273 if(row == -1) { 274 cleanUpAfterDrag(); 275 event.rejectDrop(); 276 return; 277 } 278 279 Object targetObject = ((DefaultMutableTreeNode )(getPathForRow(row).getLastPathComponent())).getUserObject(); 280 281 if(delegate.xjTreeDrop(this, getOldSelectedNode().getUserObject(), targetObject, dropLocation)) { 282 scrollPathToVisible(getPathForLocation(x, y)); 283 event.acceptDrop(getDelegateConstants()); 284 event.dropComplete(true); 285 } else 286 event.rejectDrop(); 287 cleanUpAfterDrag(); 288 } 289 290 292 public void dragEnter(DragSourceDragEvent dsde) { 293 } 294 295 public void dragOver(DragSourceDragEvent dsde) { 296 } 297 298 public void dropActionChanged(DragSourceDragEvent dsde) { 299 } 300 301 public void dragExit(DragSourceEvent dse) { 302 } 303 304 public void dragDropEnd(DragSourceDropEvent dsde) { 305 } 306 307 } 308 | Popular Tags |