1 19 20 package org.netbeans.modules.apisupport.project.ui.customizer; 21 22 import java.awt.BasicStroke ; 23 import java.awt.Color ; 24 import java.awt.Cursor ; 25 import java.awt.Dimension ; 26 import java.awt.Graphics ; 27 import java.awt.Graphics2D ; 28 import java.awt.Point ; 29 import java.awt.Rectangle ; 30 import java.awt.Stroke ; 31 import java.awt.datatransfer.DataFlavor ; 32 import java.awt.datatransfer.StringSelection ; 33 import java.awt.dnd.DnDConstants ; 34 import java.awt.dnd.DragGestureEvent ; 35 import java.awt.dnd.DragGestureListener ; 36 import java.awt.dnd.DragGestureRecognizer ; 37 import java.awt.dnd.DragSource ; 38 import java.awt.dnd.DragSourceDragEvent ; 39 import java.awt.dnd.DragSourceDropEvent ; 40 import java.awt.dnd.DragSourceEvent ; 41 import java.awt.dnd.DragSourceListener ; 42 import java.awt.dnd.DropTarget ; 43 import java.awt.dnd.DropTargetDragEvent ; 44 import java.awt.dnd.DropTargetDropEvent ; 45 import java.awt.dnd.DropTargetEvent ; 46 import java.awt.dnd.DropTargetListener ; 47 import java.awt.event.MouseEvent ; 48 import java.awt.event.MouseMotionListener ; 49 import java.awt.geom.Line2D ; 50 import java.awt.geom.Rectangle2D ; 51 import java.util.ArrayList ; 52 import java.util.Iterator ; 53 import java.util.List ; 54 import javax.swing.JComponent ; 55 56 60 final class DragManager implements DragGestureListener , DragSourceListener , 61 DropTargetListener , MouseMotionListener { 62 63 private JComponent component; 64 65 private DragGestureRecognizer dRecognizer; 67 private DragSource dSource; 68 private DropTarget dTarget; 70 71 private int translateX; 72 private int translateY; 73 74 private final Cursor oCursor; 75 76 List allItems = new ArrayList (); 77 private DragItem activeDragItem = null; 78 79 80 DragManager(JComponent component) { 81 this.component = component; 82 dSource = new DragSource (); 83 dRecognizer = dSource.createDefaultDragGestureRecognizer(this.component,DnDConstants.ACTION_MOVE,this); 84 dTarget = new DropTarget (this.component,DnDConstants.ACTION_MOVE,this); 85 component.addMouseMotionListener(this); 86 oCursor = component.getCursor(); 87 } 88 89 DragItem createNewItem() { 90 DragItem retval = new DragItem(); 91 allItems.add(retval); 92 return retval; 93 } 94 95 void setTranslate(int translateX, int translateY) { 96 this.translateX = -translateX; 97 this.translateY = -translateY; 98 99 SplashComponentPreview scomp = (SplashComponentPreview)component; 100 Rectangle bounds = new Rectangle (new Dimension (scomp.image.getWidth(null),scomp.image.getHeight(null))); 101 for (Iterator it = allItems.iterator(); it.hasNext();) { 102 DragItem elem = (DragItem) it.next(); 103 elem.setBounds(bounds); 104 } 105 } 106 107 public void paint(Graphics g) { 108 g.setXORMode(Color.white); 110 for (Iterator it = allItems.iterator(); it.hasNext();) { 111 DragItem elem = (DragItem) it.next(); 112 elem.paint(g); 113 } 114 } 115 116 public void dragGestureRecognized(DragGestureEvent dge) { 117 Point gesturePoint = dge.getDragOrigin(); 118 DragItem item = getDragItem(transformMousePoint(gesturePoint)); 119 if (item != null) { 120 activeDragItem = item; 121 activeDragItem.setGesturePoint(gesturePoint); 122 Cursor curs = activeDragItem.getCursor(); 123 assert curs != null; 124 dge.startDrag(curs,new StringSelection (""),this); 125 component.repaint(); 126 } 127 128 } 129 130 private Point transformMousePoint(Point mousePoint) { 131 return new Point (mousePoint.x+translateX, mousePoint.y + translateY); 132 } 133 134 public void dragEnter(DragSourceDragEvent dsde) { 135 } 136 137 public void dragOver(DragSourceDragEvent dsde) { 138 } 139 140 public void dropActionChanged(DragSourceDragEvent dsde) { 141 } 142 143 public void dragExit(DragSourceEvent dse) { 144 } 145 146 public void dragDropEnd(DragSourceDropEvent dsde) { 147 if (!dsde.getDropSuccess() && activeDragItem != null) { 148 activeDragItem.dragAccepted(); 149 } 150 151 } 152 153 public void dragEnter(DropTargetDragEvent dtde) { 154 } 155 156 public void dragOver(DropTargetDragEvent dtde) { 157 dragOverImpl(dtde.getLocation()); 158 } 159 160 private void dragOverImpl(final Point p) { 161 if (activeDragItem != null) { 162 activeDragItem.recalculateSize(p); 163 activeDragItem.updateSize(); 164 activeDragItem.scroll(component); 165 component.repaint(); 166 } 167 } 168 169 public void dropActionChanged(DropTargetDragEvent dtde) { 170 } 171 172 public void dragExit(DropTargetEvent dte) { 173 } 174 175 public void drop(DropTargetDropEvent dtde) { 176 if (dtde.isDataFlavorSupported(DataFlavor.stringFlavor)) { 177 dtde.dropComplete(true); 178 if (activeDragItem != null) { 179 activeDragItem.dragAccepted(); 180 } 181 } else { 182 dtde.rejectDrop(); 183 } 184 component.setCursor(oCursor); 185 activeDragItem = null; 186 component.repaint(); 187 } 188 189 public void mouseDragged(MouseEvent e) {} 190 191 public void mouseMoved(MouseEvent e) { 192 activeDragItem = null; 193 DragItem item = null; 194 for (Iterator it = allItems.iterator(); it.hasNext();) { 195 DragItem elem = (DragItem) it.next(); 196 if (elem.contains(transformMousePoint(e.getPoint()))) { 197 item = elem; 198 break; 199 } 200 } 201 if (item != null) { 202 Cursor c = item.getCursor(); 203 component.setCursor(c); 204 } else { 205 component.setCursor(oCursor); 206 } 207 } 208 209 DragItem getDragItem(Point p2Compare) { 210 DragItem retval = null; 211 for (Iterator it = allItems.iterator(); it.hasNext();) { 212 DragItem elem = (DragItem) it.next(); 213 if (elem.contains(p2Compare)) { 214 retval = elem; 215 break; 216 } 217 } 218 return retval; 219 } 220 221 interface DropHandler { 222 void dragAccepted(Rectangle original, Rectangle afterDrag); 223 } 224 225 static class DragItem implements Mode{ 226 private Point gesturePoint = new Point (); 227 private Rectangle rectangle = new Rectangle (); 228 private Rectangle currentDragRect = new Rectangle (); 229 private Mode dragMode; private DropHandler dHandler; 231 private Rectangle bounds; 232 private Mode[] allmodes = new Mode[9]; 233 private boolean enabled = true; 234 DragItem(){ 235 allmodes[0] = new OneSideScaleMode(OneSideScaleMode.N_RESIZE_MODE); 236 allmodes[1] = new OneSideScaleMode(OneSideScaleMode.S_RESIZE_MODE); 237 allmodes[2] = new OneSideScaleMode(OneSideScaleMode.W_RESIZE_MODE); 238 allmodes[3] = new OneSideScaleMode(OneSideScaleMode.E_RESIZE_MODE); 239 allmodes[4] = new ScaleMode(ScaleMode.NW_RESIZE_MODE); 240 allmodes[5] = new ScaleMode(ScaleMode.NE_RESIZE_MODE); 241 allmodes[6] = new ScaleMode(ScaleMode.SW_RESIZE_MODE); 242 allmodes[7] = new ScaleMode(ScaleMode.SE_RESIZE_MODE); 243 allmodes[8] = new MoveMode(); 244 } 245 246 void setDropHandler(DropHandler dHandler) { 247 this.dHandler = dHandler; 248 } 249 250 public void dragAccepted() { 251 if (dHandler != null) { 252 dHandler.dragAccepted(rectangle,currentDragRect); 253 } 254 } 255 256 void setRectangle(Rectangle rectangle) { 257 this.rectangle.setBounds(rectangle); 258 this.currentDragRect.setBounds(rectangle); 259 updateSize(rectangle); 260 } 261 void setGesturePoint(Point gesturePoint) { 262 this.gesturePoint = gesturePoint; 263 } 264 265 Point getGesturePoint() { 266 return this.gesturePoint; 267 } 268 269 public boolean contains(Point point) { 270 Mode mode = null; 271 if (isEnabled()) { 272 for (int i = 0; i < allmodes.length; i++) { 273 if (allmodes[i].contains(point)) { 274 mode = allmodes[i]; 275 break; 276 } 277 } 278 } 279 dragMode = mode; 280 return mode != null; 281 } 282 283 public void updateSize() { 284 updateSize(currentDragRect); 285 } 286 287 288 public void updateSize(Rectangle rec) { 289 for (int i = 0; i < allmodes.length; i++) { 290 allmodes[i].updateSize(rec); 291 } 292 } 293 294 public void recalculateSize(Point p) { 295 if (dragMode != null && !p.equals(gesturePoint)) { 296 Rectangle oldtDragRect = new Rectangle (); 297 oldtDragRect.setBounds(currentDragRect); 298 dragMode.recalculateSize(p); 299 int x = currentDragRect.x; 300 int y = currentDragRect.y; 301 int w = currentDragRect.width; 302 int h = currentDragRect.height; 303 304 if (bounds != null && !bounds.contains(currentDragRect)) { 305 if (h + y > bounds.height + bounds.y) { 306 if (y == oldtDragRect.y) { 307 h = (bounds.height + bounds.y) - y; 308 } else { 309 y = (bounds.height + bounds.y) - h; 310 } 311 } 312 if (w + x > bounds.width + bounds.x ) { 313 if (x == oldtDragRect.x) { 314 w = (bounds.width + bounds.x) - x; 315 } else { 316 x = (bounds.width + bounds.x) - w; 317 } 318 } 319 if (x < bounds.x) { 320 x = bounds.x; 321 } 322 if (y < bounds.y) { 323 y = bounds.y; 324 } 325 currentDragRect.setBounds(x,y,w,h); 326 } 327 if (w <= 3 || h <= 3 && !(dragMode instanceof MoveMode)) { 328 currentDragRect.setBounds(oldtDragRect); 329 } 330 } 331 332 } 333 334 public void scroll(JComponent component) { 335 component.scrollRectToVisible(currentDragRect); 336 } 337 338 void setBounds(Rectangle bounds) { 339 this.bounds = bounds; 340 } 341 342 public void paint(Graphics g) { 343 if (isEnabled()) { 344 for (int i = 0; i < allmodes.length; i++) { 345 allmodes[i].paint(g); 346 } 347 } 348 } 349 350 public Cursor getCursor() { 351 return (dragMode != null) ? dragMode.getCursor() : null; 352 } 353 354 private class MoveMode implements Mode { 355 public boolean contains(Point point) { 356 return (currentDragRect != null && currentDragRect.contains(point)); 357 } 358 359 public void updateSize(Rectangle rec) {} 360 361 public void paint(Graphics g) {} 362 363 public Cursor getCursor() { 364 return Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR); 365 } 366 367 public void recalculateSize(Point p) { 368 currentDragRect.setBounds((p.x-gesturePoint.x)+rectangle.x,(p.y-gesturePoint.y)+rectangle.y,rectangle.width, rectangle.height); 369 } 370 } 371 372 private class ScaleMode implements Mode { 373 static final int NW_RESIZE_MODE = 0; 374 static final int NE_RESIZE_MODE = 1; 375 static final int SW_RESIZE_MODE = 2; 376 static final int SE_RESIZE_MODE = 3; 377 379 private int resizeMode = -1; 380 private Rectangle rec; 381 382 ScaleMode(int resizeMode) { 383 this.resizeMode = resizeMode; 384 } 385 386 public boolean contains(Point point) { 387 assert resizeMode != -1; 388 assert rec != null; 389 return rec.contains(point); 390 } 391 392 public void updateSize(Rectangle currentDragRect) { 393 assert resizeMode != -1; 394 int inset = Math.min(Math.min(5, currentDragRect.width/5), Math.min(5, currentDragRect.height/5)); 395 Dimension d = new Dimension (inset*2,inset*2); 396 Point origin = new Point (currentDragRect.x-inset, currentDragRect.y-inset); 397 switch(resizeMode) { 398 case ScaleMode.NW_RESIZE_MODE: 399 rec = new Rectangle (origin,d); 400 break; 401 case ScaleMode.NE_RESIZE_MODE: 402 rec = new Rectangle (new Point (origin.x+currentDragRect.width, origin.y),d); 403 break; 404 case ScaleMode.SW_RESIZE_MODE: 405 rec = new Rectangle (new Point (origin.x, origin.y+currentDragRect.height),d); 406 break; 407 case ScaleMode.SE_RESIZE_MODE: 408 rec = new Rectangle (new Point (origin.x+currentDragRect.width, origin.y+currentDragRect.height),d); 409 break; 410 } 411 } 412 413 public void paint(Graphics g) { 414 assert resizeMode != -1; 415 assert rec != null; 416 417 g.fillRect(rec.x, rec.y, rec.width, rec.height); 418 } 419 420 public Cursor getCursor() { 421 assert resizeMode != -1; 422 assert rec != null; 423 424 Cursor retval = null; 425 switch(resizeMode) { 426 case ScaleMode.NW_RESIZE_MODE: 427 retval = Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR); 428 break; 429 case ScaleMode.NE_RESIZE_MODE: 430 retval = Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR); 431 break; 432 case ScaleMode.SW_RESIZE_MODE: 433 retval = Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR); 434 break; 435 case ScaleMode.SE_RESIZE_MODE: 436 retval = Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR); 437 break; 438 } 439 assert retval != null; 440 return retval; 441 } 442 443 public void recalculateSize(Point p) { 444 int xDelta = (p.x-gesturePoint.x); 445 int yDelta = (p.y-gesturePoint.y); 446 switch(resizeMode) { 447 case ScaleMode.NW_RESIZE_MODE: 448 currentDragRect.setBounds(rectangle.x+xDelta,rectangle.y+yDelta,rectangle.width-xDelta, rectangle.height-yDelta); 449 break; 450 case ScaleMode.NE_RESIZE_MODE: 451 currentDragRect.setBounds(rectangle.x,rectangle.y+yDelta,rectangle.width+xDelta, rectangle.height-yDelta); 452 break; 453 case ScaleMode.SW_RESIZE_MODE: 454 currentDragRect.setBounds(rectangle.x+xDelta,rectangle.y,rectangle.width-xDelta, rectangle.height+yDelta); 455 break; 456 case ScaleMode.SE_RESIZE_MODE: 457 currentDragRect.setBounds(rectangle.x,rectangle.y,rectangle.width+xDelta, rectangle.height+yDelta); 458 break; 459 } 460 } 461 } 462 463 private class OneSideScaleMode implements Mode { 464 static final int N_RESIZE_MODE = 5; 465 static final int E_RESIZE_MODE = 6; 466 static final int S_RESIZE_MODE = 7; 467 static final int W_RESIZE_MODE = 8; 468 469 private int resizeMode = -1; 470 private Rectangle rec; 471 472 OneSideScaleMode(int resizeMode) { 473 this.resizeMode = resizeMode; 474 } 475 476 public boolean contains(Point point) { 477 assert resizeMode != -1; 478 assert rec != null; 479 return rec.contains(point); 480 } 481 482 public void updateSize(Rectangle currentDragRect) { 483 assert resizeMode != -1; 484 int inset = 5; 485 switch(resizeMode) { 486 case OneSideScaleMode.N_RESIZE_MODE: 487 rec = new Rectangle (currentDragRect.x+inset,currentDragRect.y-2*inset,currentDragRect.width-inset,2*inset); 488 break; 489 case OneSideScaleMode.E_RESIZE_MODE: 490 rec = new Rectangle (currentDragRect.x+currentDragRect.width,currentDragRect.y+inset,2*inset,currentDragRect.height-inset); 491 break; 492 case OneSideScaleMode.S_RESIZE_MODE: 493 rec = new Rectangle (currentDragRect.x+inset,currentDragRect.y+currentDragRect.height,currentDragRect.width-inset,2*inset); 494 break; 495 case OneSideScaleMode.W_RESIZE_MODE: 496 rec = new Rectangle (currentDragRect.x-2*inset,currentDragRect.y+inset,2*inset,currentDragRect.height-inset); 497 break; 498 } 499 500 } 501 502 public void paint(Graphics g) { 503 assert resizeMode != -1; 504 assert rec != null; 505 int inset = 5; 506 Graphics2D g2d = (Graphics2D )g; 507 Stroke oStroke = g2d.getStroke(); 508 g2d.setStroke(new BasicStroke (1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[]{3.0f}, 0.0f)); 509 Rectangle2D rec2d = rec.getBounds2D(); 510 Line2D line = null; 511 switch(resizeMode) { 512 case OneSideScaleMode.N_RESIZE_MODE: 513 line = new Line2D.Double (rec2d.getMinX(),rec2d.getMaxY(),rec2d.getMaxX()-inset,rec2d.getMaxY()); 514 break; 515 case OneSideScaleMode.E_RESIZE_MODE: 516 line = new Line2D.Double (rec2d.getMinX(),rec2d.getMinY(),rec2d.getMinX(),rec2d.getMaxY()-inset); 517 break; 518 case OneSideScaleMode.S_RESIZE_MODE: 519 line = new Line2D.Double (rec2d.getMinX(),rec2d.getMinY(),rec2d.getMaxX()-inset,rec2d.getMinY()); 520 break; 521 case OneSideScaleMode.W_RESIZE_MODE: 522 line = new Line2D.Double (rec2d.getMaxX(),rec2d.getMinY(),rec2d.getMaxX(),rec2d.getMaxY()-inset); 523 break; 524 } 525 g2d.draw(line); 526 g2d.setStroke(oStroke); 527 } 528 529 public Cursor getCursor() { 530 assert resizeMode != -1; 531 assert rec != null; 532 Cursor retval = null; 533 switch(resizeMode) { 534 case OneSideScaleMode.N_RESIZE_MODE: 535 retval = Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR); 536 break; 537 case OneSideScaleMode.E_RESIZE_MODE: 538 retval = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); 539 break; 540 case OneSideScaleMode.S_RESIZE_MODE: 541 retval = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR); 542 break; 543 case OneSideScaleMode.W_RESIZE_MODE: 544 retval = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR); 545 break; 546 } 547 assert retval != null; 548 return retval; 549 } 550 551 public void recalculateSize(Point p) { 552 int xDelta = (p.x-gesturePoint.x); 553 int yDelta = (p.y-gesturePoint.y); 554 switch(resizeMode) { 555 case OneSideScaleMode.N_RESIZE_MODE: 556 currentDragRect.setBounds(rectangle.x,rectangle.y+yDelta,rectangle.width, rectangle.height-yDelta); 557 break; 558 case OneSideScaleMode.E_RESIZE_MODE: 559 currentDragRect.setBounds(rectangle.x,rectangle.y,rectangle.width+xDelta, rectangle.height); 560 break; 561 case OneSideScaleMode.S_RESIZE_MODE: 562 currentDragRect.setBounds(rectangle.x,rectangle.y,rectangle.width, rectangle.height+yDelta); 563 break; 564 case OneSideScaleMode.W_RESIZE_MODE: 565 currentDragRect.setBounds(rectangle.x+xDelta,rectangle.y,rectangle.width-xDelta, rectangle.height); 566 break; 567 } 568 } 569 } 570 571 boolean isEnabled() { 572 return enabled; 573 } 574 575 void setEnabled(boolean enabled) { 576 this.enabled = enabled; 577 } 578 579 } 580 581 private interface Mode { 582 boolean contains(Point point); 583 void updateSize(Rectangle rec); 584 void recalculateSize(Point p); 585 void paint(Graphics g); 586 Cursor getCursor(); 587 } 588 } 589 | Popular Tags |