1 19 20 21 package org.netbeans.core.windows.view.dnd; 22 23 24 25 import java.awt.*; 26 import java.awt.datatransfer.*; 27 import java.awt.dnd.*; 28 import java.io.IOException ; 29 import java.lang.ref.*; 30 import java.util.*; 31 import java.util.logging.Level ; 32 import java.util.logging.Logger ; 33 import javax.swing.*; 34 import org.netbeans.core.windows.*; 35 import org.netbeans.core.windows.view.*; 36 import org.netbeans.core.windows.view.ui.*; 37 import org.openide.util.WeakSet; 38 import org.openide.windows.TopComponent; 39 40 41 52 public final class WindowDnDManager 53 implements DropTargetGlassPane.Observer, DropTargetGlassPane.Informer { 54 55 56 private final TopComponentDragSupport topComponentDragSupport = new TopComponentDragSupport(this); 57 58 59 private DragSource windowDragSource; 60 61 62 private boolean dragging; 63 64 68 private boolean dropSuccess; 69 70 71 private final Map<JRootPane,Component> root2glass = new HashMap<JRootPane, Component>(); 72 73 74 private final Set<Component> floatingFrames = new WeakSet<Component>(4); 75 76 77 private Reference<DropTargetGlassPane> lastTargetWRef = new WeakReference<DropTargetGlassPane>(null); 78 79 80 private final ViewAccessor viewAccessor; 81 82 private TopComponentDroppable startingDroppable; 84 private Point startingPoint; 85 private TopComponent startingTransfer; 87 88 private int draggedKind; 89 90 91 private MotionListener motionListener; 92 93 94 private static Reference<CenterPanelDroppable> centerDropWRef = 95 new WeakReference<CenterPanelDroppable>(null); 96 97 98 private static Reference<EditorAreaDroppable> editorDropWRef = 99 new WeakReference<EditorAreaDroppable>(null); 100 101 102 private static final boolean DEBUG = Debug.isLoggable(WindowDnDManager.class); 103 104 105 106 public WindowDnDManager(ViewAccessor viewAccessor) { 107 this.viewAccessor = viewAccessor; 108 109 Toolkit.getDefaultToolkit().addAWTEventListener( 111 topComponentDragSupport, 112 AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK 113 ); 114 } 115 116 117 118 119 public static boolean isDnDEnabled() { 120 return !Constants.SWITCH_DND_DISABLE; 121 } 122 123 125 public synchronized DragSource getWindowDragSource() { 126 if(windowDragSource == null) { 127 windowDragSource = new DragSource(); 128 windowDragSource.addDragSourceMotionListener(getMotionListener()); 129 } 130 return windowDragSource; 131 } 132 133 134 public MotionListener getMotionListener () { 135 if (motionListener == null) { 136 motionListener = new MotionListener(this, topComponentDragSupport); 137 }; 138 return motionListener; 139 } 140 141 142 public boolean isDragging() { 143 return dragging; 144 } 145 146 147 public void setDropSuccess(boolean dropSuccess) { 148 this.dropSuccess = dropSuccess; 149 } 150 151 152 public boolean isDropSuccess() { 153 return dropSuccess; 154 } 155 156 158 public void setLastDropTarget(DropTargetGlassPane target) { 159 if(target != lastTargetWRef.get()) { 160 lastTargetWRef = new WeakReference<DropTargetGlassPane>(target); 161 } 162 } 163 164 167 public void resetDragSource() { 168 dragFinished(); 169 } 170 171 public TopComponentDroppable getStartingDroppable() { 172 return startingDroppable; 173 } 174 175 public Point getStartingPoint() { 176 return startingPoint; 177 } 178 179 public TopComponent getStartingTransfer() { 180 return startingTransfer; 181 } 182 183 187 public void dragStarting(TopComponentDroppable startingDroppable, Point startingPoint, 188 TopComponent startingTransfer) { 189 if(DEBUG) { 190 debugLog(""); debugLog("dragStarting"); } 193 194 this.startingDroppable = startingDroppable; 195 this.startingPoint = startingPoint; 196 this.startingTransfer = startingTransfer; 197 ModeImpl mode = (ModeImpl)WindowManagerImpl.getInstance().findMode(startingTransfer); 198 this.draggedKind = mode != null ? mode.getKind() : Constants.MODE_KIND_EDITOR; 199 200 205 206 Map<JRootPane,Component> addedRoots = new HashMap<JRootPane, Component>(); 207 Set<Component> addedFrames = new HashSet<Component>(); 208 209 for(Component comp: viewAccessor.getModeComponents()) { 210 if(comp instanceof TopComponentDroppable) { 211 JRootPane root = null; 213 if(comp instanceof RootPaneContainer) { 214 root = ((RootPaneContainer)comp).getRootPane(); 215 } else { 216 RootPaneContainer rootContainer = (RootPaneContainer)SwingUtilities 217 .getAncestorOfClass(RootPaneContainer.class, comp); 218 if(rootContainer != null) { 219 root = rootContainer.getRootPane(); 220 } 221 } 222 223 if(root != null) { 224 Component originalGlass = setDropTargetGlassPane(root, this); 225 if(originalGlass != null) { 226 addedRoots.put(root, originalGlass); 227 } 228 } 229 } 230 } 231 for(Component w: viewAccessor.getSeparateModeFrames()) { 232 if(w != null) { 233 addedFrames.add(w); 234 } 235 } 236 237 if(!addedRoots.isEmpty()) { 238 synchronized(root2glass) { 239 root2glass.putAll(addedRoots); 240 } 241 } 242 243 if(!addedFrames.isEmpty()) { 244 synchronized(floatingFrames) { 245 floatingFrames.addAll(addedFrames); 246 } 247 } 248 249 dragging = true; 250 dropSuccess = false; 251 } 252 253 254 257 private static Component setDropTargetGlassPane( 258 JRootPane rootPane, WindowDnDManager windowDnDManager) { 259 Component glassPane = rootPane.getGlassPane(); 260 if(glassPane instanceof DropTargetGlassPane) { 261 return null; 263 } 264 265 DropTargetGlassPane dropGlass = new DropTargetGlassPane(windowDnDManager); 266 new DropTarget( 268 dropGlass, 269 DnDConstants.ACTION_COPY_OR_MOVE, 270 dropGlass 271 ); 272 273 rootPane.setGlassPane(dropGlass); 274 dropGlass.initialize(); 277 278 return glassPane; 279 } 280 281 284 public void dragFinished() { 285 if(DEBUG) { 286 debugLog(""); debugLog("dragFinished"); } 289 290 295 296 getMotionListener().dragFinished(); 298 299 startingDroppable = null; 301 startingPoint = null; 302 startingTransfer = null; 303 304 topComponentDragSupport.dragFinished(); 306 307 dragging = false; 308 309 Map<JRootPane, Component> removedRoots; 310 synchronized(root2glass) { 311 removedRoots = new HashMap<JRootPane, Component>(root2glass); 312 root2glass.clear(); 313 } 314 315 for(JRootPane root: removedRoots.keySet()) { 316 setOriginalGlassPane(root, removedRoots.get(root)); 317 } 318 } 319 320 321 private static void setOriginalGlassPane( 322 JRootPane rootPane, Component originalGlass) { 323 Component glass = rootPane.getGlassPane(); 324 325 if(glass instanceof DropTargetGlassPane) { 326 DropTargetGlassPane dropGlass = (DropTargetGlassPane)glass; 327 328 dropGlass.setDropTarget(null); 330 dropGlass.uninitialize(); 331 } 332 333 if(originalGlass != null) { 334 rootPane.setGlassPane(originalGlass); 335 } 336 337 JInternalFrame internalFrame = (JInternalFrame)SwingUtilities. 340 getAncestorOfClass(JInternalFrame.class, originalGlass); 341 if(internalFrame != null && !internalFrame.isSelected() 342 && !originalGlass.isVisible()) { 343 originalGlass.setVisible(true); 344 } 345 } 346 347 351 public void dragFinishedEx() { 352 synchronized(floatingFrames) { 353 floatingFrames.clear(); 354 } 355 } 356 357 358 359 public Set<Component> getFloatingFrames() { 360 synchronized(floatingFrames) { 361 return new HashSet<Component>(floatingFrames); 362 } 363 } 364 365 367 public boolean isInFloatingFrame(Point location) { 368 for(Component w: getFloatingFrames()) { 369 if(w.getBounds().contains(location)) { 370 return true; 371 } 372 } 373 374 return false; 375 } 376 377 378 public boolean isCopyOperationPossible() { 380 return topComponentDragSupport.isCopyOperationPossible(); 381 } 382 383 public Controller getController() { 384 return viewAccessor.getController(); 385 } 386 387 private static void debugLog(String message) { 388 Debug.log(WindowDnDManager.class, message); 389 } 390 391 394 static boolean isInMainWindow(Point location) { 395 return WindowManagerImpl.getInstance().getMainWindow().getBounds().contains(location); 396 } 397 398 400 private boolean isInMainWindowDroppable(Point location, int kind, TopComponent transfer) { 401 return findMainWindowDroppable(location, kind, transfer) != null; 402 } 403 404 406 private static boolean isInFloatingFrameDroppable(Set<Component> floatingFrames, Point location, int kind, TopComponent transfer) { 407 return findFloatingFrameDroppable(floatingFrames, location, kind, transfer) != null; 408 } 409 410 private static boolean isInFreeArea(Point location) { 411 Window mainWindow = WindowManagerImpl.getInstance().getMainWindow(); 413 Window[] owned = mainWindow.getOwnedWindows(); 414 Window[] frames = Frame.getFrames(); 415 Window[] windows = new Window[owned.length + frames.length]; 416 System.arraycopy(frames, 0, windows, 0, frames.length); 417 System.arraycopy(owned, 0, windows, frames.length, owned.length); 418 419 for(int i = 0; i < windows.length; i++) { 420 if(windows[i].isVisible() && windows[i].getBounds().contains(location.x, location.y)) { 423 return false; 424 } 425 } 426 427 return true; 428 } 429 430 431 private TopComponentDroppable findDroppableFromScreen( 432 Set<Component> floatingFrames, Point location, int kind, TopComponent transfer) { 433 434 TopComponentDroppable droppable = findMainWindowDroppable(location, kind, transfer); 435 if(droppable != null) { 436 return droppable; 437 } 438 439 droppable = findFloatingFrameDroppable(floatingFrames, location, kind, transfer); 440 if(droppable != null) { 441 return droppable; 442 } 443 444 449 if(isInFreeArea(location)) { 450 return getFreeAreaDroppable(location); 451 } 452 return null; 453 } 454 455 private CenterSlidingDroppable lastSlideDroppable; 456 457 459 private TopComponentDroppable findMainWindowDroppable( 460 Point location, int kind, TopComponent transfer) { 461 462 MainWindow mainWindow = (MainWindow)WindowManagerImpl.getInstance().getMainWindow(); 463 464 if (!ZOrderManager.getInstance().isOnTop(mainWindow, location)) { 465 return null; 466 } 467 468 Point p = new Point(location); 469 SwingUtilities.convertPointFromScreen(p, mainWindow.getContentPane()); 470 if (lastSlideDroppable != null) { 471 if (lastSlideDroppable.isWithinSlide(p)) { 472 return lastSlideDroppable; 473 } 474 } 475 TopComponentDroppable droppable = findSlideDroppable(viewAccessor.getSlidingModeComponent(Constants.LEFT)); 476 if (droppable != null) { 477 CenterSlidingDroppable drop = new CenterSlidingDroppable(viewAccessor, droppable, Constants.LEFT); 478 if (drop.isWithinSlide(p)) { 479 lastSlideDroppable = drop; 480 return drop; 481 } 482 } 483 droppable = findSlideDroppable(viewAccessor.getSlidingModeComponent(Constants.RIGHT)); 484 if (droppable != null) { 485 CenterSlidingDroppable drop = new CenterSlidingDroppable(viewAccessor, droppable, Constants.RIGHT); 486 if (drop.isWithinSlide(p)) { 487 lastSlideDroppable = drop; 488 return drop; 489 } 490 } 491 droppable = findSlideDroppable(viewAccessor.getSlidingModeComponent(Constants.BOTTOM)); 492 if (droppable != null) { 493 CenterSlidingDroppable drop = new CenterSlidingDroppable(viewAccessor, droppable, Constants.BOTTOM); 494 if (drop.isWithinSlide(p)) { 495 lastSlideDroppable = drop; 496 return drop; 497 } 498 } 499 lastSlideDroppable = null; 500 if (isNearEditorEdge(location, viewAccessor, kind)) { 501 return getEditorAreaDroppable(); 502 } 503 if (isNearEdge(location, viewAccessor)) { 504 return getCenterPanelDroppable(); 505 } 506 Point mainP = new Point(location); 507 SwingUtilities.convertPointFromScreen(mainP, mainWindow); 508 return findDroppable(mainWindow, mainP, kind, transfer); 509 } 510 511 private static TopComponentDroppable findSlideDroppable(Component comp) { 512 TopComponentDroppable droppable = null; 513 if(comp instanceof TopComponentDroppable) { 514 droppable = (TopComponentDroppable)comp; 515 } else { 516 droppable = (TopComponentDroppable)SwingUtilities.getAncestorOfClass(TopComponentDroppable.class, comp); 517 } 518 return droppable; 519 } 520 521 523 private static TopComponentDroppable findFloatingFrameDroppable( 524 Set<Component> floatingFrames, Point location, int kind, TopComponent transfer) { 525 for(Component comp: floatingFrames) { 526 Rectangle bounds = comp.getBounds(); 527 528 if(bounds.contains(location) && 529 ZOrderManager.getInstance().isOnTop((RootPaneContainer)comp, location)) { 530 TopComponentDroppable droppable = findDroppable(comp, 531 new Point(location.x - bounds.x, location.y - bounds.y), 532 kind, 533 transfer); 534 if(droppable != null) { 535 return droppable; 536 } 537 } 538 } 539 540 return null; 541 } 542 543 548 private static TopComponentDroppable findDroppable(Component comp, 549 Point location, int kind, TopComponent transfer) { 550 RootPaneContainer rpc; 551 if(comp instanceof RootPaneContainer) { 552 rpc = (RootPaneContainer)comp; 553 } else { 554 Window w = SwingUtilities.getWindowAncestor(comp); 555 if(w instanceof RootPaneContainer) { 556 rpc = (RootPaneContainer)w; 557 } else { 558 return null; 559 } 560 } 561 562 Component contentPane = rpc.getContentPane(); 563 location = SwingUtilities.convertPoint(comp, location, contentPane); 564 Component deepest = SwingUtilities.getDeepestComponentAt( 565 contentPane, location.x, location.y); 566 if(deepest instanceof TopComponentDroppable) { 567 TopComponentDroppable droppable = (TopComponentDroppable)deepest; 568 if(droppable.supportsKind(kind, transfer)) { 569 return droppable; 570 } 571 } 572 573 while(deepest != null) { 574 TopComponentDroppable nextDroppable = (TopComponentDroppable)SwingUtilities.getAncestorOfClass( 575 TopComponentDroppable.class, deepest); 576 if(nextDroppable != null && nextDroppable.supportsKind(kind, transfer)) { 577 return nextDroppable; 578 } 579 deepest = (Component)nextDroppable; 580 } 581 return null; 582 } 583 584 586 static boolean isAroundCenterPanel(Point location) { 587 Component desktop = ((MainWindow)WindowManagerImpl.getInstance().getMainWindow()).getDesktop(); 588 if(desktop == null) { 589 return false; 590 } 591 592 Point p = new Point(location); 593 SwingUtilities.convertPointFromScreen(p, desktop.getParent()); 594 Rectangle centerBounds = desktop.getBounds(); 595 596 if(!centerBounds.contains(p)) { 597 centerBounds.grow(Constants.DROP_AREA_SIZE, Constants.DROP_AREA_SIZE); 598 if(centerBounds.contains(p)) { 599 return true; 600 } 601 } 602 return false; 603 } 604 605 607 static boolean isNearEditorEdge(Point location, ViewAccessor viewAccessor, int kind) { 608 Component editor = WindowManagerImpl.getInstance().getEditorAreaComponent(); 609 if(editor == null) { 610 return false; 611 } 612 Point p = new Point(location); 613 SwingUtilities.convertPointFromScreen(p, editor.getParent()); 614 Rectangle editorBounds = editor.getBounds(); 615 editorBounds.y -= 10; 616 editorBounds.height += 10; 617 Rectangle shrinked = editor.getBounds(); 618 shrinked.grow(-10,0); 619 shrinked.height -= 10; 620 Component dr = viewAccessor.getSlidingModeComponent(Constants.RIGHT); 621 if (dr != null) { 622 shrinked.width = shrinked.width - dr.getBounds().width; 623 } 624 dr = viewAccessor.getSlidingModeComponent(Constants.BOTTOM); 625 if (dr != null) { 626 shrinked.height = shrinked.height - dr.getBounds().height; 627 } 628 return editorBounds.contains(p) && !shrinked.contains(p) && kind == Constants.MODE_KIND_EDITOR; 629 } 630 631 632 634 static boolean isNearEdge(Point location, ViewAccessor viewAccessor) { 635 Component desktop = ((MainWindow)WindowManagerImpl.getInstance().getMainWindow()).getDesktop(); 636 if(desktop == null) { 637 return false; 638 } 639 Point p = new Point(location); 640 SwingUtilities.convertPointFromScreen(p, desktop); 641 Rectangle centerBounds = desktop.getBounds(); 642 centerBounds.y -= 20; 643 centerBounds.height += 20; 644 Rectangle shrinked = desktop.getBounds(); 645 shrinked.grow(-10,0); 646 shrinked.height -= 10; 647 Component dr = viewAccessor.getSlidingModeComponent(Constants.LEFT); 648 if (dr != null) { 649 shrinked.x = shrinked.x + dr.getBounds().width; 650 shrinked.width = shrinked.width - dr.getBounds().width; 651 } 652 dr = viewAccessor.getSlidingModeComponent(Constants.RIGHT); 653 if (dr != null) { 654 shrinked.width = shrinked.width - dr.getBounds().width; 655 } 656 dr = viewAccessor.getSlidingModeComponent(Constants.BOTTOM); 657 if (dr != null) { 658 shrinked.height = shrinked.height - dr.getBounds().height; 659 } 660 boolean cont = centerBounds.contains(p) && !shrinked.contains(p); 661 662 return cont; 663 } 664 665 666 private TopComponentDroppable getCenterPanelDroppable() { 667 CenterPanelDroppable droppable = centerDropWRef.get(); 668 669 if(droppable == null) { 670 droppable = new CenterPanelDroppable(); 671 centerDropWRef = new WeakReference<CenterPanelDroppable>(droppable); 672 } 673 674 return droppable; 675 } 676 677 private static TopComponentDroppable getFreeAreaDroppable(Point location) { 678 return new FreeAreaDroppable(location); 679 } 680 681 682 private TopComponentDroppable getEditorAreaDroppable() { 683 EditorAreaDroppable droppable = editorDropWRef.get(); 684 685 if(droppable == null) { 686 droppable = new EditorAreaDroppable(); 687 editorDropWRef = new WeakReference<EditorAreaDroppable>(droppable); 688 } 689 690 return droppable; 691 } 692 693 694 697 boolean tryPerformDrop(Controller controller, Set<Component> floatingFrames, 698 Point location, int dropAction, Transferable transferable) { 699 TopComponent[] tcArray = extractTopComponent( 700 dropAction == DnDConstants.ACTION_COPY, 701 transferable 702 ); 703 704 if(tcArray == null || tcArray.length == 0) { 705 return false; 706 } 707 708 ModeImpl mode = (ModeImpl)WindowManagerImpl.getInstance().findMode(tcArray[0]); 709 int kind = mode != null ? mode.getKind() : Constants.MODE_KIND_EDITOR; 710 711 TopComponentDroppable droppable 712 = findDroppableFromScreen(floatingFrames, location, kind, tcArray[0]); 713 if(droppable == null) { 714 return false; 715 } 716 717 Component dropComponent = droppable.getDropComponent(); 718 if(dropComponent != null) { 719 SwingUtilities.convertPointFromScreen(location, dropComponent); 720 } 721 return performDrop(controller, droppable, dropAction, tcArray, location, draggedKind); 722 } 723 724 727 static TopComponent[] extractTopComponent(boolean clone, 728 Transferable tr) { 729 DataFlavor df = getDataFlavorForDropAction(clone); 730 731 if(df == null) { 732 return null; 734 } 735 736 if(tr.isDataFlavorSupported(df)) { 738 try { 739 TopComponent tc; 740 741 if(clone) { 742 TopComponent.Cloneable ctc = (TopComponent.Cloneable)tr 743 .getTransferData(df); 744 745 tc = ctc.cloneComponent(); 747 } else { 748 tc = (TopComponent)tr.getTransferData(df); 749 } 750 751 return new TopComponent[] {tc}; 752 } catch(UnsupportedFlavorException ufe) { 753 Logger.getLogger(WindowDnDManager.class.getName()).log(Level.WARNING, null, ufe); 754 } catch(IOException ioe) { 755 Logger.getLogger(WindowDnDManager.class.getName()).log(Level.WARNING, null, ioe); 756 } 757 } 758 759 df = new DataFlavor(TopComponentDragSupport.MIME_TOP_COMPONENT_ARRAY, null); 760 if(tr.isDataFlavorSupported(df)) { 761 try { 762 return (TopComponent[])tr.getTransferData(df); 763 } catch(UnsupportedFlavorException ufe) { 764 Logger.getLogger(WindowDnDManager.class.getName()).log(Level.WARNING, null, ufe); 765 } catch(IOException ioe) { 766 Logger.getLogger(WindowDnDManager.class.getName()).log(Level.WARNING, null, ioe); 767 } 768 } 769 770 return null; 771 } 772 773 775 private static DataFlavor getDataFlavorForDropAction(boolean clone) { 776 DataFlavor df; 778 if(clone) { 779 df = new DataFlavor(TopComponentDragSupport.MIME_TOP_COMPONENT_CLONEABLE, null); 780 } else { 781 df = new DataFlavor(TopComponentDragSupport.MIME_TOP_COMPONENT, null); 782 } 783 784 return df; 785 } 786 787 790 private static boolean performDrop(Controller controller, 791 TopComponentDroppable droppable, int dropAction, TopComponent[] tcArray, Point location, int draggedKind) { 792 if(DEBUG) { 793 debugLog(""); debugLog("performDrop"); debugLog("droppable=" + droppable); } 797 798 if(tcArray == null || tcArray.length == 0) { 799 return true; 800 } 801 802 if(!droppable.canDrop(tcArray[0], location)) { 803 return true; 804 } 805 806 ViewElement viewElement = droppable.getDropViewElement(); 807 Object constr = droppable.getConstraintForLocation(location); 808 809 if(viewElement instanceof EditorView) { 810 ModeImpl mode = (ModeImpl)WindowManagerImpl.getInstance().findMode(tcArray[0]); 811 int kind = mode != null ? mode.getKind() : Constants.MODE_KIND_EDITOR; 812 if(kind == Constants.MODE_KIND_EDITOR) { 813 controller.userDroppedTopComponentsIntoEmptyEditor(tcArray); 814 } else { 815 if(constr == Constants.TOP 816 || constr == Constants.LEFT 817 || constr == Constants.RIGHT 818 || constr == Constants.BOTTOM) { 819 controller.userDroppedTopComponentsAroundEditor(tcArray, (String )constr, kind); 820 } else if(Constants.SWITCH_MODE_ADD_NO_RESTRICT 821 || WindowManagerImpl.getInstance().isTopComponentAllowedToMoveAnywhere(tcArray[0])) { 822 controller.userDroppedTopComponentsIntoEmptyEditor(tcArray); 823 } 824 } 825 } else if(viewElement instanceof ModeView) { 826 ModeView modeView = (ModeView)viewElement; 827 if(constr == Constants.TOP 828 || constr == Constants.LEFT 829 || constr == Constants.RIGHT 830 || constr == Constants.BOTTOM) { 831 controller.userDroppedTopComponents(modeView, tcArray, (String )constr); 832 } else if(constr instanceof Integer ) { 833 controller.userDroppedTopComponents(modeView, tcArray, ((Integer )constr).intValue()); 834 } else { 835 controller.userDroppedTopComponents(modeView, tcArray); 836 } 837 } else if(viewElement == null) { if(constr == Constants.TOP 839 || constr == Constants.LEFT 840 || constr == Constants.RIGHT 841 || constr == Constants.BOTTOM) { if( droppable instanceof EditorAreaDroppable ) { 843 controller.userDroppedTopComponentsAroundEditor(tcArray, (String )constr, Constants.MODE_KIND_EDITOR); 844 } else { 845 controller.userDroppedTopComponentsAround(tcArray, (String )constr); 846 } 847 } else if(constr instanceof Rectangle) { Rectangle bounds = (Rectangle)constr; 849 Component modeComp = SwingUtilities.getAncestorOfClass(ModeComponent.class, tcArray[0]); 851 if(modeComp != null) { 852 bounds.setSize(modeComp.getWidth(), modeComp.getHeight()); 853 } 854 855 controller.userDroppedTopComponentsIntoFreeArea(tcArray, bounds, draggedKind); 856 } 857 } 858 859 return true; 860 } 861 863 864 866 private static class MotionListener implements DragSourceMotionListener { 867 868 private final WindowDnDManager windowDnDManager; 869 private final TopComponentDragSupport topComponentDragSupport; 870 871 private Point previousDragLoc; 872 873 874 private Window fakeWindow; 875 876 877 private boolean isSizeSet; 878 879 881 private MotionListener(WindowDnDManager windowDnDManager, 882 TopComponentDragSupport topComponentDragSupport) { 883 this.windowDnDManager = windowDnDManager; 884 this.topComponentDragSupport = topComponentDragSupport; 885 } 886 887 888 889 public void dragMouseMoved(DragSourceDragEvent evt) { 890 if(DEBUG) { 891 debugLog("dragMouseMoved evt=" + evt); } 893 894 Point location = evt.getLocation(); 895 if(location == null) { 896 return; 897 } 898 899 903 904 boolean isInMainDroppable 905 = windowDnDManager.isInMainWindowDroppable(location, windowDnDManager.draggedKind, windowDnDManager.startingTransfer); 906 boolean isInFrameDroppable 907 = isInFloatingFrameDroppable(windowDnDManager.getFloatingFrames(), location, windowDnDManager.draggedKind, windowDnDManager.startingTransfer); 908 boolean isAroundCenterPanel 909 = isAroundCenterPanel(location); 910 boolean shouldPaintFakeWindow = false; 911 912 if(isInMainDroppable || isInFrameDroppable || isAroundCenterPanel) { 913 TopComponentDroppable droppable 914 = windowDnDManager.findDroppableFromScreen(windowDnDManager.getFloatingFrames(), location, windowDnDManager.draggedKind, windowDnDManager.startingTransfer); 915 917 if (droppable instanceof FreeAreaDroppable) { 918 if(WindowManagerImpl.getInstance().getEditorAreaState() == Constants.EDITOR_AREA_SEPARATED 919 && droppable.canDrop(windowDnDManager.startingTransfer, location)) { 920 topComponentDragSupport.setSuccessCursor(true); 921 } else { 922 topComponentDragSupport.setUnsuccessCursor(); 923 } 924 } else if (droppable != null) { 926 927 JComponent cp = (JComponent)droppable.getDropComponent(); 929 Component glass = cp.getRootPane().getGlassPane(); 930 if (glass instanceof DropTargetGlassPane) { 931 windowDnDManager.setLastDropTarget((DropTargetGlassPane)glass); 932 } 933 Point p = new Point(location); 934 SwingUtilities.convertPointFromScreen(p, droppable.getDropComponent()); 935 if(droppable.canDrop(windowDnDManager.startingTransfer, p)) { 936 topComponentDragSupport.setSuccessCursor(false); 937 } else { 938 topComponentDragSupport.setUnsuccessCursor(); 939 } 940 dragOverDropTarget(location, droppable); 941 } 942 } else if(!isInMainWindow(location) 943 && windowDnDManager.isInFloatingFrame(location)) { 944 topComponentDragSupport.setSuccessCursor(false); 946 } else if(isInFreeArea(location) 947 && getFreeAreaDroppable(location).canDrop(windowDnDManager.startingTransfer, location)) { 948 topComponentDragSupport.setSuccessCursor(true); 949 shouldPaintFakeWindow = true; 951 } else { 952 topComponentDragSupport.setUnsuccessCursor(); 953 } 954 paintFakeWindow(shouldPaintFakeWindow, evt); 955 956 if(!isInMainDroppable && !isInFrameDroppable && !isAroundCenterPanel) { 957 clearExitedDropTarget(); 958 } 959 } 960 961 963 private void dragOverDropTarget(Point location, 964 TopComponentDroppable droppable) { 965 DropTargetGlassPane lastTarget 966 = windowDnDManager.lastTargetWRef.get(); 967 968 if(lastTarget != null) { 969 Point p = new Point(location); 970 SwingUtilities.convertPointFromScreen(p, lastTarget); 971 lastTarget.dragOver(p, droppable); 972 } 973 } 974 975 979 private void clearExitedDropTarget() { 980 DropTargetGlassPane lastTarget 981 = windowDnDManager.lastTargetWRef.get(); 982 983 if(lastTarget != null) { 984 lastTarget.clearIndications(); 985 windowDnDManager.lastTargetWRef = new WeakReference<DropTargetGlassPane>(null); 986 } 987 } 988 989 990 private static DropTargetGlassPane getMainDropTargetGlassPane() { 991 Component glass = ((JFrame)WindowManagerImpl.getInstance().getMainWindow()).getGlassPane(); 992 if(glass instanceof DropTargetGlassPane) { 993 return (DropTargetGlassPane)glass; 994 } else { 995 return null; 996 } 997 } 998 999 void dragFinished () { 1000 previousDragLoc = null; 1001 if (fakeWindow != null) { 1002 fakeWindow.dispose(); 1003 fakeWindow = null; 1004 } 1005 } 1006 1007 1009 private void handleWindowMove (ModeImpl mode, TopComponent tc, DragSourceDragEvent evt) { 1010 Point dragLoc = evt.getLocation(); 1011 Window w = SwingUtilities.getWindowAncestor(tc); 1013 if (previousDragLoc == null) { 1014 previousDragLoc = windowDnDManager.getStartingPoint(); 1015 SwingUtilities.convertPointToScreen(previousDragLoc, w); 1016 } 1017 Point newLoc = w.getLocation(); 1018 newLoc.translate(dragLoc.x - previousDragLoc.x, dragLoc.y - previousDragLoc.y); 1019 w.setLocation(newLoc); 1020 1021 previousDragLoc = dragLoc; 1022 } 1023 1024 1026 private void paintFakeWindow (boolean visible, DragSourceDragEvent evt) { 1027 Point loc = evt.getLocation(); 1028 if (loc == null) { 1030 return; 1031 } 1032 if (fakeWindow == null) { 1033 fakeWindow = createFakeWindow(); 1034 isSizeSet = false; 1035 } 1036 fakeWindow.setLocation(loc); 1037 fakeWindow.setVisible(visible); 1038 if (visible && !isSizeSet) { 1040 Dimension size = windowDnDManager.startingTransfer.getSize(); 1041 Insets insets = fakeWindow.getInsets(); 1042 size.width += insets.left + insets.right; 1043 size.height += insets.top + insets.bottom; 1044 fakeWindow.setSize(size); 1045 isSizeSet = true; 1046 } 1047 } 1048 1049 1050 private Window createFakeWindow () { 1051 Window result; 1052 if (windowDnDManager.draggedKind == Constants.MODE_KIND_EDITOR) { 1053 result = new JFrame(); 1054 } else { 1055 result = new JDialog((JFrame) null); 1056 } 1057 result.setAlwaysOnTop(true); 1058 return result; 1059 } 1060 1061 } 1063 1064 1066 public interface ViewAccessor { 1067 public Set<Component> getModeComponents(); 1068 public Set<Component> getSeparateModeFrames(); 1069 public Controller getController(); 1070 public Component getSlidingModeComponent(String side); 1071 } 1073 1074 private class CenterPanelDroppable implements TopComponentDroppable { 1075 1076 1077 public java.awt.Shape getIndicationForLocation(Point p) { 1078 Rectangle bounds = getDropComponent().getBounds(); 1079 Rectangle res = null; 1080 double ratio = Constants.DROP_AROUND_RATIO; 1081 Object constraint = getConstraintForLocation(p); 1082 if(constraint == JSplitPane.LEFT) { 1083 res = new Rectangle(0, 0, (int)(bounds.width * ratio) - 1, bounds.height - 1); 1084 } else if(constraint == JSplitPane.TOP) { 1085 res = new Rectangle(0, 0, bounds.width - 1, (int)(bounds.height * ratio) - 1); 1086 } else if(constraint == JSplitPane.RIGHT) { 1087 res = new Rectangle(bounds.width - (int)(bounds.width * ratio), 0, 1088 (int)(bounds.width * ratio) - 1, bounds.height - 1); 1089 } else if(constraint == JSplitPane.BOTTOM) { 1090 res = new Rectangle(0, bounds.height - (int)(bounds.height * ratio), bounds.width - 1, 1091 (int)(bounds.height * ratio) - 1); 1092 } 1093 1094 return res; 1095 } 1096 1097 1098 public Object getConstraintForLocation(Point p) { 1099 Rectangle bounds = getDropComponent().getBounds(); 1100 Component leftSlide = viewAccessor.getSlidingModeComponent(Constants.LEFT); 1101 Component rightSlide = viewAccessor.getSlidingModeComponent(Constants.RIGHT); 1102 Component bottomSlide = viewAccessor.getSlidingModeComponent(Constants.BOTTOM); 1103 if(null != leftSlide && p.x < leftSlide.getBounds().width + 10) { 1104 return javax.swing.JSplitPane.LEFT; 1105 } else if(p.y < bounds.y) { 1106 return javax.swing.JSplitPane.TOP; 1107 } else if(null !=rightSlide && null != leftSlide 1108 && p.x > bounds.width - 10 - rightSlide.getBounds().width - leftSlide.getBounds().width) { 1109 return javax.swing.JSplitPane.RIGHT; 1110 } else if(null != bottomSlide && p.y > bounds.height - 10 - bottomSlide.getBounds().height) { 1111 return javax.swing.JSplitPane.BOTTOM; 1112 } 1113 1114 return null; 1115 } 1116 1117 1118 public Component getDropComponent() { 1119 return ((MainWindow)WindowManagerImpl.getInstance().getMainWindow()).getDesktop(); 1120 } 1121 1122 1123 public ViewElement getDropViewElement() { 1124 return null; 1125 } 1126 1127 public boolean canDrop(TopComponent transfer, Point location) { 1128 if(Constants.SWITCH_MODE_ADD_NO_RESTRICT 1129 || WindowManagerImpl.getInstance().isTopComponentAllowedToMoveAnywhere(transfer)) { 1130 return true; 1131 } 1132 1133 ModeImpl mode = (ModeImpl)WindowManagerImpl.getInstance().findMode(transfer); 1134 return mode != null && (mode.getKind() == Constants.MODE_KIND_VIEW || mode.getKind() == Constants.MODE_KIND_SLIDING); 1135 } 1136 1137 public boolean supportsKind(int kind, TopComponent transfer) { 1138 if(Constants.SWITCH_MODE_ADD_NO_RESTRICT 1139 || WindowManagerImpl.getInstance().isTopComponentAllowedToMoveAnywhere(transfer)) { 1140 return true; 1141 } 1142 1143 return kind == Constants.MODE_KIND_VIEW || kind == Constants.MODE_KIND_SLIDING; 1144 } 1145 1146 1147 } 1149 1150 private class EditorAreaDroppable implements TopComponentDroppable { 1151 1152 1153 public java.awt.Shape getIndicationForLocation(Point p) { 1154 Rectangle bounds = getDropComponent().getBounds(); 1155 Rectangle res = null; 1156 double ratio = Constants.DROP_AROUND_RATIO; 1157 Object constraint = getConstraintForLocation(p); 1158 if(constraint == JSplitPane.LEFT) { 1159 res = new Rectangle(0, 0, (int)(bounds.width * ratio) - 1, bounds.height - 1); 1160 } else if(constraint == JSplitPane.TOP) { 1161 res = new Rectangle(0, 0, bounds.width - 1, (int)(bounds.height * ratio) - 1); 1162 } else if(constraint == JSplitPane.RIGHT) { 1163 res = new Rectangle(bounds.width - (int)(bounds.width * ratio), 0, 1164 (int)(bounds.width * ratio) - 1, bounds.height - 1); 1165 } else if(constraint == JSplitPane.BOTTOM) { 1166 res = new Rectangle(0, bounds.height - (int)(bounds.height * ratio), bounds.width - 1, 1167 (int)(bounds.height * ratio) - 1); 1168 } 1169 1170 return res; 1171 } 1172 1173 1174 public Object getConstraintForLocation(Point p) { 1175 Rectangle bounds = getDropComponent().getBounds(); 1176 Component leftSlide = viewAccessor.getSlidingModeComponent(Constants.LEFT); 1177 Component rightSlide = viewAccessor.getSlidingModeComponent(Constants.RIGHT); 1178 Component bottomSlide = viewAccessor.getSlidingModeComponent(Constants.BOTTOM); 1179 if(null != leftSlide && p.x < leftSlide.getBounds().width + 10) { 1180 return javax.swing.JSplitPane.LEFT; 1181 } else if(p.y < bounds.y) { 1182 return javax.swing.JSplitPane.TOP; 1183 } else if(null !=rightSlide && null != leftSlide 1184 && p.x > bounds.width - 10 - rightSlide.getBounds().width - leftSlide.getBounds().width) { 1185 return javax.swing.JSplitPane.RIGHT; 1186 } else if(null != bottomSlide && p.y > bounds.height - 10 - bottomSlide.getBounds().height) { 1187 return javax.swing.JSplitPane.BOTTOM; 1188 } 1189 1190 return null; 1191 } 1192 1193 1194 public Component getDropComponent() { 1195 return WindowManagerImpl.getInstance().getEditorAreaComponent(); 1196 } 1197 1198 1199 public ViewElement getDropViewElement() { 1200 return null; 1201 } 1202 1203 public boolean canDrop(TopComponent transfer, Point location) { 1204 if(Constants.SWITCH_MODE_ADD_NO_RESTRICT 1205 || WindowManagerImpl.getInstance().isTopComponentAllowedToMoveAnywhere(transfer)) { 1206 return true; 1207 } 1208 1209 ModeImpl mode = (ModeImpl)WindowManagerImpl.getInstance().findMode(transfer); 1210 return mode != null && mode.getKind() == Constants.MODE_KIND_EDITOR; 1211 } 1212 1213 public boolean supportsKind(int kind, TopComponent transfer) { 1214 if(Constants.SWITCH_MODE_ADD_NO_RESTRICT 1215 || WindowManagerImpl.getInstance().isTopComponentAllowedToMoveAnywhere(transfer)) { 1216 return true; 1217 } 1218 1219 return kind == Constants.MODE_KIND_EDITOR; 1220 } 1221 1222 1223 } 1225 1226 1227 private static class FreeAreaDroppable implements TopComponentDroppable { 1228 1229 private Point location; 1230 1231 public FreeAreaDroppable(Point location) { 1232 this.location = location; 1233 } 1234 1235 1236 public java.awt.Shape getIndicationForLocation(Point p) { 1237 return null; 1238 } 1239 1240 1241 public Object getConstraintForLocation(Point p) { 1242 return new Rectangle(location.x, location.y, 1243 Constants.DROP_NEW_MODE_SIZE.width, Constants.DROP_NEW_MODE_SIZE.height); 1244 } 1245 1246 1247 public Component getDropComponent() { 1248 return null; 1249 } 1250 1251 1252 public ViewElement getDropViewElement() { 1253 return null; 1254 } 1255 1256 public boolean canDrop(TopComponent transfer, Point location) { 1257 ModeImpl mode = (ModeImpl)WindowManagerImpl.getInstance().findMode(transfer); 1258 if (mode == null) { 1259 return false; 1260 } 1261 if (Constants.SWITCH_MODE_ADD_NO_RESTRICT || 1262 WindowManagerImpl.getInstance().isTopComponentAllowedToMoveAnywhere(transfer)) { 1263 return true; 1264 } 1265 1266 if (mode.getState() == Constants.MODE_STATE_SEPARATED && 1270 mode.getOpenedTopComponents().size() == 1) { 1271 return false; 1272 } 1273 1274 return true; 1275 } 1276 1277 public boolean supportsKind(int kind, TopComponent transfer) { 1278 return true; 1279 } 1280 1281 } 1283 1287 private static class CenterSlidingDroppable implements TopComponentDroppable, EnhancedDragPainter { 1288 1289 private ViewAccessor accesor; 1290 private TopComponentDroppable original; 1291 private String side; 1292 JPanel pan; 1293 private boolean isShowing; 1294 1295 public CenterSlidingDroppable(ViewAccessor viewAccesor, TopComponentDroppable slidingBarDelegate, 1296 String side) { 1297 original = slidingBarDelegate; 1298 accesor = viewAccesor; 1299 this.side = side; 1300 pan = new JPanel(); 1301 isShowing = false; 1302 } 1303 1304 public boolean canDrop(TopComponent transfer, Point location) { 1305 return original.canDrop(transfer, location); 1306 } 1307 1308 public Object getConstraintForLocation(Point location) { 1309 return original.getConstraintForLocation(location); 1310 } 1311 1312 public Component getDropComponent() { 1313 return original.getDropComponent(); 1314 } 1315 1316 public ViewElement getDropViewElement() { 1317 return original.getDropViewElement(); 1318 } 1319 1320 public Shape getIndicationForLocation(Point location) { 1321 Shape toReturn = original.getIndicationForLocation(location); 1322 Rectangle dim = original.getDropComponent().getBounds(); 1323 if (dim.width < 10 || dim.height < 10) { 1324 Rectangle rect = toReturn.getBounds(); 1325 if (Constants.LEFT.equals(side)) { 1326 toReturn = new Rectangle(0, 0, Math.max(rect.width, Constants.DROP_AREA_SIZE), 1327 Math.max(rect.height, Constants.DROP_AREA_SIZE)); 1328 } else if (Constants.RIGHT.equals(side)) { 1329 toReturn = new Rectangle(- Constants.DROP_AREA_SIZE, 0, Math.max(rect.width, Constants.DROP_AREA_SIZE), 1330 Math.max(rect.height, Constants.DROP_AREA_SIZE)); 1331 } else if (Constants.BOTTOM.equals(side)) { 1332 toReturn = new Rectangle(0, - Constants.DROP_AREA_SIZE, Math.max(rect.width, Constants.DROP_AREA_SIZE), 1333 Math.max(rect.height, Constants.DROP_AREA_SIZE)); 1334 } 1335 } 1336 return toReturn; 1337 } 1338 1339 public boolean isWithinSlide(Point location) { 1340 Component root = SwingUtilities.getRootPane(original.getDropComponent()); 1341 Point barLoc = SwingUtilities.convertPoint(root, location, original.getDropComponent()); 1342 if (original.getDropComponent().contains(barLoc)) { 1343 return true; 1344 } 1345 Dimension dim = original.getDropComponent().getSize(); 1346 if (Constants.LEFT.equals(side)) { 1347 int abs = Math.abs(barLoc.x); 1348 if (barLoc.y > - Constants.DROP_AREA_SIZE && barLoc.y < dim.height + Constants.DROP_AREA_SIZE) { 1349 if (isShowing && abs < Constants.DROP_AREA_SIZE) { 1350 return true; 1351 } 1352 if (!isShowing && barLoc.x <= 0 && barLoc.x > - Constants.DROP_AREA_SIZE) { 1353 return true; 1354 } 1355 } 1356 } 1357 else if (Constants.RIGHT.equals(side)) { 1358 if (barLoc.y > - Constants.DROP_AREA_SIZE && barLoc.y < dim.height + Constants.DROP_AREA_SIZE) { 1359 if (isShowing && ((barLoc.x < 0 && barLoc.x > - Constants.DROP_AREA_SIZE) 1360 || barLoc.x > 0 && barLoc.x - dim.width < Constants.DROP_AREA_SIZE)) { 1361 return true; 1362 } 1363 if (!isShowing && barLoc.x >= 0 && barLoc.x < Constants.DROP_AREA_SIZE + dim.width) { 1364 return true; 1365 } 1366 } 1367 } 1368 else if (Constants.BOTTOM.equals(side)) { 1369 if (barLoc.x > - Constants.DROP_AREA_SIZE && barLoc.x < dim.width + Constants.DROP_AREA_SIZE) { 1370 if (isShowing && ((barLoc.y < 0 && barLoc.y > - Constants.DROP_AREA_SIZE) 1371 || barLoc.y > 0 && barLoc.y - dim.height < Constants.DROP_AREA_SIZE)) { 1372 return true; 1373 } 1374 if (!isShowing && barLoc.y >= 0 && barLoc.y < Constants.DROP_AREA_SIZE + dim.height) { 1375 return true; 1376 } 1377 } 1378 } 1379 return false; 1380 1381 } 1382 1383 public boolean supportsKind(int kind, TopComponent transfer) { 1384 return original.supportsKind(kind, transfer); 1385 } 1386 1387 public void additionalDragPaint(Graphics2D g) { 1388 Rectangle dim = original.getDropComponent().getBounds(); 1389 if (dim.width > 10 && dim.height > 10) { 1390 return; 1391 } 1392 isShowing = true; 1393 Component glassPane = ((JComponent)original.getDropComponent()).getRootPane().getGlassPane(); 1394 Point leftTop = SwingUtilities.convertPoint(original.getDropComponent(), 0, 0, glassPane); 1395 Point firstDivider; 1396 Point secondDevider; 1397 1398 if (Constants.RIGHT.equals(side)) { 1399 leftTop = new Point(leftTop.x - 24, leftTop.y); 1400 firstDivider = new Point(leftTop); 1401 secondDevider = new Point(leftTop.x, leftTop.y + dim.height); 1402 } 1403 else if (Constants.BOTTOM.equals(side)) { 1404 leftTop = new Point(0, leftTop.y - 24); 1405 firstDivider = new Point(leftTop); 1406 secondDevider = new Point(leftTop.x + glassPane.getBounds().width, leftTop.y); 1407 } else { 1408 firstDivider = new Point(leftTop.x + 25, leftTop.y); 1409 secondDevider = new Point(leftTop.x + 25, leftTop.y + dim.height); 1410 } 1411 Rectangle rect = new Rectangle(leftTop.x, leftTop.y, Math.max(25, dim.width), Math.max(25, dim.height)); 1412 if (Constants.BOTTOM.equals(side)) { 1413 rect.width = glassPane.getBounds().width; 1415 } 1416 1417 Color col = g.getColor(); 1418 g.setColor(pan.getBackground()); 1419 g.fill(rect); 1420 g.setColor(pan.getBackground().darker()); 1421 g.drawLine(firstDivider.x, firstDivider.y, secondDevider.x, secondDevider.y); 1422 g.setColor(col); 1423 } 1424 1425 } 1426 1427} 1428 1429 | Popular Tags |