1 19 20 package org.netbeans.core.windows.view.dnd; 21 22 23 import java.awt.TexturePaint ; 24 import java.awt.image.BufferedImage ; 25 import org.netbeans.core.windows.Constants; 26 import org.netbeans.core.windows.Debug; 27 import org.netbeans.core.windows.view.Controller; 28 import org.netbeans.swing.tabcontrol.plaf.EqualPolygon; 29 30 import javax.swing.*; 31 import java.awt.*; 32 import java.awt.dnd.*; 33 import java.awt.geom.AffineTransform ; 34 import java.awt.geom.Area ; 35 import java.awt.geom.GeneralPath ; 36 import java.util.Set ; 37 38 39 50 public final class DropTargetGlassPane extends JPanel implements DropTargetListener { 51 52 private final Observer observer; 54 private final Informer informer; 56 57 private WindowDnDManager windowDragAndDrop; 58 59 private static boolean isHardwareDoubleBuffer = false; 60 61 64 private Point location; 65 66 68 private TopComponentDroppable droppable; 69 70 71 private static final boolean DEBUG = Debug.isLoggable(DropTargetGlassPane.class); 72 73 74 75 76 public DropTargetGlassPane(WindowDnDManager wdnd) { 77 this.observer = wdnd; 78 this.informer = wdnd; 79 windowDragAndDrop = wdnd; 80 isHardwareDoubleBuffer = !RepaintManager.currentManager(this).isDoubleBufferingEnabled(); 81 82 setOpaque(false); 83 } 84 85 86 87 public void initialize() { 88 if(isVisible()) { 89 revalidate(); 92 } else { 93 setVisible(true); 94 } 95 } 96 97 98 public void uninitialize() { 99 if(location != null) { 100 dragFinished(); 102 } 103 104 setVisible(false); 105 } 106 107 108 void dragOver(Point location, TopComponentDroppable droppable) { 109 this.droppable = droppable; 110 if (dragRepaintManager == null) { 111 setDragRepaintManager (new DragRepaintManager(this)); 112 } 113 setDragLocation (location); 114 } 115 116 117 private Point dragLocation = null; 118 private void setDragLocation (Point p) { 119 Point old = dragLocation; 120 dragLocation = p; 121 if (p != null && p.equals(old)) { 122 return; 123 } else if (p == null) { 124 return; 126 } 127 128 if (droppable != null) { 129 Component c = droppable.getDropComponent(); 130 131 Shape s = droppable.getIndicationForLocation ( 132 SwingUtilities.convertPoint(this, p, c)); 133 134 EnhancedDragPainter painter = null; 135 if (droppable instanceof EnhancedDragPainter) { 136 painter = (EnhancedDragPainter)droppable; 137 } 138 dragRepaintManager.setShapeAndTarget(s, c, painter); 139 } else { 140 dragRepaintManager.eraseLastIndication(null); 141 } 142 143 } 144 145 146 147 148 private void dragExited() { 149 clear(); 150 } 151 152 private boolean guidedPaint = false; 153 154 158 private void setGuidedPaint (boolean val) { 159 guidedPaint = val; 160 } 161 162 164 private boolean isGuidedPaint () { 165 return guidedPaint; 166 } 167 168 172 public void clearIndications() { 173 clear(); 174 } 175 176 177 private void dragActionChanged(Point location) { 178 setDragLocation(location); 179 } 180 181 182 private void dragFinished() { 183 clear(); 184 setDragRepaintManager(null); 185 } 186 187 private void setDragRepaintManager (DragRepaintManager drm) { 188 this.dragRepaintManager = drm; 189 } 190 191 private DragRepaintManager dragRepaintManager = null; 192 193 194 private void clear() { 195 this.droppable = null; 196 197 if (dragRepaintManager != null) { 198 dragRepaintManager.setShapeAndTarget(null, null, null); 199 } 200 setDragLocation(null); 201 } 202 203 206 public void paintComponent(Graphics g) { 207 super.paintComponent(g); 208 209 if (!isGuidedPaint() && dragRepaintManager != null) { 210 dragRepaintManager.paintCurrentIndication ((Graphics2D) g); 211 } 212 } 213 214 private static final Color FILL_COLOR = new Color( 200, 200, 200, 120 ); 216 217 218 222 public void dragEnter(DropTargetDragEvent evt) { 223 if(DEBUG) { 224 debugLog(""); debugLog("dragEnter"); } 227 228 int dropAction = evt.getDropAction(); 229 if(dropAction == DnDConstants.ACTION_NONE) { 231 dropAction = DnDConstants.ACTION_MOVE; 232 } 233 234 if((dropAction & DnDConstants.ACTION_COPY_OR_MOVE) > 0) { 235 evt.acceptDrag(dropAction); 236 } else { 237 evt.rejectDrag(); 238 } 239 } 240 241 243 public void dragExit(DropTargetEvent evt) { 244 if(DEBUG) { 245 debugLog(""); debugLog("dragExit"); } 248 249 Component c = evt.getDropTargetContext().getComponent(); 250 if(c == this) { 251 this.dragExited(); 252 } 253 } 254 255 258 public void dragOver(DropTargetDragEvent evt) { 259 if(DEBUG) { 260 debugLog(""); debugLog("dragOver"); } 263 264 if (dragRepaintManager == null) { 265 setDragRepaintManager (new DragRepaintManager(this)); 266 } 267 268 observer.setLastDropTarget(this); 270 } 271 272 275 public void dropActionChanged(DropTargetDragEvent evt) { 276 if(DEBUG) { 277 debugLog(""); debugLog("dropActionChanged"); } 280 281 int dropAction = evt.getDropAction(); 282 boolean acceptDrag; 283 284 if((dropAction == DnDConstants.ACTION_MOVE) 285 || (dropAction == DnDConstants.ACTION_COPY 286 && informer.isCopyOperationPossible())) { 287 288 acceptDrag = true; 289 } else { 290 acceptDrag = false; 291 } 292 293 if(acceptDrag) { 294 evt.acceptDrag(dropAction); 295 } else { 296 evt.rejectDrag(); 297 } 298 299 Component c = evt.getDropTargetContext().getComponent(); 300 if(c == this) { 301 this.dragActionChanged(acceptDrag ? evt.getLocation() : null); 302 } 303 } 304 305 307 public void drop(DropTargetDropEvent evt) { 308 if(DEBUG) { 309 debugLog(""); debugLog("drop"); } 312 313 Component c = evt.getDropTargetContext().getComponent(); 315 if(c == this) { 316 this.dragFinished(); 317 } 318 319 int dropAction = evt.getDropAction(); 320 if(dropAction != DnDConstants.ACTION_MOVE 321 && dropAction != DnDConstants.ACTION_COPY) { 322 evt.rejectDrop(); 324 return; 325 } 326 327 evt.acceptDrop(dropAction); 329 330 boolean success = false; 331 332 try { 333 Point location = evt.getLocation(); 334 335 SwingUtilities.convertPointToScreen(location, c); 339 if(WindowDnDManager.isAroundCenterPanel(location)) { 340 return; 341 } 342 343 success = windowDragAndDrop.tryPerformDrop( 344 informer.getController(), informer.getFloatingFrames(), 345 location, dropAction, evt.getTransferable()); 346 } finally { 347 observer.setDropSuccess(success); 350 evt.dropComplete(false); 351 } 353 } 354 356 357 358 private static void debugLog(String message) { 359 Debug.log(DropTargetGlassPane.class, message); 360 } 361 362 363 365 interface Observer { 366 public void setDropSuccess(boolean success); 367 public void setLastDropTarget(DropTargetGlassPane glassPane); 368 } 370 interface Informer { 372 public boolean isCopyOperationPossible(); 373 public Controller getController(); 374 public Set <Component> getFloatingFrames(); 375 } 376 377 379 private static final Rectangle scratch = new Rectangle(); 380 387 private static class DragRepaintManager { 388 private Shape shape = null; 389 private Component lastDropComponent; 390 private EnhancedDragPainter lastEnhanced; 391 DropTargetGlassPane pane; 392 private Graphics2D g = null; 393 394 public DragRepaintManager (DropTargetGlassPane pane) { 395 this.pane = pane; 396 if (isHardwareDoubleBuffer && !Boolean.getBoolean("nb.winsys.mac.no.double.buffer")) { RepaintManager.currentManager(pane).setDoubleBufferingEnabled(true); 399 } 400 } 401 402 protected void finalize() { 403 if (g != null) g.dispose(); 404 if (isHardwareDoubleBuffer && !Boolean.getBoolean("nb.winsys.mac.no.double.buffer")) { RepaintManager.currentManager(pane).setDoubleBufferingEnabled(false); 406 } 407 } 408 409 private Graphics2D getGraphics() { 410 if (g == null) { 411 g = (Graphics2D) pane.getGraphics(); 412 } 413 return g; 414 } 415 416 public void clear() { 417 lastDropComponent = null; 418 lastEnhanced = null; 419 } 420 421 public void setShapeAndTarget (Shape s, Component c, EnhancedDragPainter enh) { 422 Shape old = shape; 423 if (old != null && s != null) { 424 if (!shape.equals(s)) { 425 shape = s; 426 shapeChange (old, shape, c, enh); 427 } 428 } else if ((old == null) != (s == null)) { 429 shape = s; 430 shapeChange (old, s, c, enh); 431 } 432 } 433 434 public void paintCurrentIndication (Graphics2D g) { 435 if (shape != null) { 436 paintShapeOnGlassPane (shape, g); 437 } 438 } 439 440 public void eraseLastIndication (Graphics2D g) { 441 if (shape == null) { 442 return; 443 } 444 eraseShape(g); 445 } 446 447 private void shapeChange (Shape old, Shape nue, Component c, EnhancedDragPainter enhanced) { 448 if (old != null) { 449 eraseShape(g); 450 } 451 lastDropComponent = c; 452 lastEnhanced = enhanced; 453 if (nue != null) { 454 paintShapeOnGlassPane (nue, g); 455 } 456 } 457 458 private void eraseShape(Graphics2D g) { 459 if (g == null) { 460 g = getGraphics(); 461 } 462 if (g == null) { 463 return; 464 } 465 pane.setGuidedPaint(true); 466 try { 467 JComponent toPaint; 468 toPaint = (JComponent) ((JComponent)lastDropComponent).getRootPane(); 469 toPaint.paint (g); 470 g.setClip (null); 473 } finally { 474 pane.setGuidedPaint(false); 475 } 476 if (isHardwareDoubleBuffer) { 477 Toolkit.getDefaultToolkit().sync(); 478 } 479 } 480 481 private void paintShapeOnGlassPane (Shape s, Graphics2D g) { 482 if (g == null) { 483 g = getGraphics(); 484 } 485 if (g == null) { 486 return; 487 } 488 pane.setGuidedPaint(true); 489 try { 490 JComponent toPaint; 491 toPaint = (JComponent) lastDropComponent; 494 if (lastEnhanced != null) { 496 lastEnhanced.additionalDragPaint(g); 497 } 498 Shape clip = getClipForIndication (s, true, lastDropComponent); 499 g.setClip (clip); 500 paintShape (s, g); 501 502 g.setClip (null); 505 } finally { 506 pane.setGuidedPaint(false); 507 } 508 if (isHardwareDoubleBuffer) { 509 Toolkit.getDefaultToolkit().sync(); 510 } 511 } 512 513 private void paintShape (Shape s, Graphics2D g) { 514 Color oldColor = g.getColor(); 515 Stroke oldStroke = g.getStroke(); 516 Paint oldPaint = g.getPaint(); 517 g.setColor(Color.red); 518 519 g.setStroke(createIndicationStroke()); 520 g.setPaint(createPaint()); 521 Color fillColor = Constants.SWITCH_DROP_INDICATION_FADE ? FILL_COLOR : null; 522 if(s instanceof Rectangle) { 523 drawIndicationRectangle(g, (Rectangle)s, lastDropComponent, fillColor); 524 } else if(s instanceof GeneralPath ) { 525 drawIndicationGeneralPath(g, (GeneralPath )s, lastDropComponent, fillColor); 526 } else if (s instanceof Polygon) { 527 drawIndicationPolygon (g, (Polygon) s, lastDropComponent, fillColor); 528 } 529 g.setColor(oldColor); 530 g.setStroke(oldStroke); 531 g.setPaint(oldPaint); 532 } 533 534 535 private Stroke createIndicationStroke() { 536 return new BasicStroke(3); 537 } 538 539 540 541 542 private Shape getClipForIndication (Shape indication, boolean translate, Component target) { 543 Shape clip; 544 if (indication instanceof Rectangle) { 545 scratch.setBounds((Rectangle) indication); 546 scratch.x -= 3; 547 scratch.y -= 3; 548 scratch.width +=6; 549 scratch.height +=6; 550 Area a = new Area (scratch); 551 scratch.setBounds ((Rectangle) indication); 552 scratch.x += 4; 553 scratch.y += 4; 554 scratch.width -=8; 555 scratch.height -= 8; 556 a.subtract(new Area (scratch)); 557 if (translate) { 558 Point p = new Point (0,0); 559 560 p = SwingUtilities.convertPoint(lastDropComponent, p, 561 pane); 562 AffineTransform at = AffineTransform.getTranslateInstance(p.x, p.y); 563 a.transform(at); 564 } 565 clip = a; 566 } else { 567 if (indication instanceof Polygon) { 568 if (translate) { 569 indication = getTransformedPath ((Polygon) indication, target); 570 } 571 } else if (indication instanceof GeneralPath ) { 572 if (translate) { 573 indication = getTransformedPath ((GeneralPath )indication, target); 574 } 575 } else { 576 return null; 578 } 579 clip = new BasicStroke (5).createStrokedShape(indication); 580 } 581 return clip; 582 } 583 584 private Polygon getTransformedPath (Polygon path, Component source) { 585 Polygon result = new EqualPolygon (path.xpoints, path.ypoints, path.npoints); 586 Point point = new Point(0, 0); 588 point = SwingUtilities.convertPoint(source, point, pane); 589 result.translate (point.x, point.y); 590 return result; 591 } 592 593 596 private GeneralPath getTransformedPath (GeneralPath path, Component source) { 597 Point point = new Point(0, 0); 598 point = SwingUtilities.convertPoint(source, point, pane); 599 path = (GeneralPath ) ((GeneralPath ) path).clone(); 600 path.transform(new AffineTransform (1D, 0D, 0D, 1D, point.x, point.y)); 601 return path; 602 } 603 604 private void drawIndicationPolygon(Graphics2D g, Polygon p, Component source, Color fillColor ) { 605 if (g == null) { 606 g = getGraphics(); 607 } 608 Point point = new Point (0,0); 609 point = SwingUtilities.convertPoint(source, point, pane); 610 p = new EqualPolygon (p.xpoints, p.ypoints, p.npoints); 611 p.translate (point.x, point.y); 612 g.drawPolygon (p); 613 if ( fillColor != null ) { 614 g.setColor( fillColor ); 615 g.fillPolygon (p); 616 } 617 } 618 619 private void drawIndicationRectangle(Graphics2D g, Rectangle r, Component source, Color fillColor ) { 620 if (g == null) { 621 g = getGraphics(); 622 } 623 r = SwingUtilities.convertRectangle(source, r, pane); 624 626 g.drawRect(r.x+1, r.y+1, r.width-2, r.height-2); 627 if ( fillColor != null ) { 628 g.setColor(fillColor); 629 g.fillRect(r.x+1, r.y+1, r.width-2, r.height-2); 630 } 631 } 632 633 private void drawIndicationGeneralPath(Graphics2D g, GeneralPath path, Component source, Color fillColor ) { 634 if (g == null) { 635 g = getGraphics(); 636 } 637 path = getTransformedPath (path, source); 639 640 g.draw(path); 641 if ( fillColor != null ) { 642 g.setColor( fillColor ); 643 g.fill(path); 644 } 645 } 646 647 private TexturePaint createPaint() { 648 BufferedImage image = new BufferedImage (2,2,BufferedImage.TYPE_INT_ARGB); 649 Graphics2D g2 = image.createGraphics(); 650 g2.setColor(new Color(255, 90, 0)); 651 g2.fillRect(0,0,1,1); 652 g2.fillRect(1,1,1,1); 653 g2.setColor(new Color(255, 90, 0, 0)); 654 g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f)); 655 g2.fillRect(1,0,1,1); 656 g2.fillRect(0,1,1,1); 657 return new TexturePaint (image, new Rectangle(0,0,2,2)); 658 } 659 } 660 661 } 662 | Popular Tags |