Source Code Cross Referenced for WindowDnDManager.java in  » IDE-Netbeans » core » org » netbeans » core » windows » view » dnd » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » core » org.netbeans.core.windows.view.dnd 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.core.windows.view.dnd;
0043:
0044:        import java.awt.*;
0045:        import java.awt.datatransfer.*;
0046:        import java.awt.dnd.*;
0047:        import java.io.IOException;
0048:        import java.lang.ref.*;
0049:        import java.util.*;
0050:        import java.util.logging.Level;
0051:        import java.util.logging.Logger;
0052:        import javax.swing.*;
0053:        import org.netbeans.core.windows.*;
0054:        import org.netbeans.core.windows.view.*;
0055:        import org.netbeans.core.windows.view.ui.*;
0056:        import org.openide.util.WeakSet;
0057:        import org.openide.windows.TopComponent;
0058:
0059:        /**
0060:         * Manager for window DnD. Manages notifying all opened
0061:         * <code>ModeContainer</code>'s to be notified about starting
0062:         * and finishe window drag operation.
0063:         *
0064:         *
0065:         * @author  Peter Zavadsky
0066:         *
0067:         * @see TopComponentDragSupport
0068:         * @see DropTargetGlassPane
0069:         */
0070:        public final class WindowDnDManager implements 
0071:                DropTargetGlassPane.Observer, DropTargetGlassPane.Informer {
0072:
0073:            private final TopComponentDragSupport topComponentDragSupport = new TopComponentDragSupport(
0074:                    this );
0075:
0076:            /** Only instance of drag source used for window system DnD. */
0077:            private DragSource windowDragSource;
0078:
0079:            /** Flag indicating the drag operation is in progress. */
0080:            private boolean dragging;
0081:
0082:            // XXX #21917. The flag is not correct in jdk dnd framework,
0083:            // this field is used to workaround the problem. Be aware is 
0084:            // valisd only for DnD of window component.
0085:            /** Flag keeping info about last drop operation. */
0086:            private boolean dropSuccess;
0087:
0088:            /** Maps root panes to original glass panes. */
0089:            private final Map<JRootPane, Component> root2glass = new HashMap<JRootPane, Component>();
0090:
0091:            /** Set of floating frame types, i.e. separate windows. */
0092:            private final Set<Component> floatingFrames = new WeakSet<Component>(
0093:                    4);
0094:
0095:            /** Used to hack the last Drop target to clear its indication. */
0096:            private Reference<DropTargetGlassPane> lastTargetWRef = new WeakReference<DropTargetGlassPane>(
0097:                    null);
0098:
0099:            /** Accesses view. */
0100:            private final ViewAccessor viewAccessor;
0101:
0102:            // Helpers
0103:            private TopComponentDroppable startingDroppable;
0104:            private Point startingPoint;
0105:            // XXX Normal way it should be possible to retrieve from DnD events.
0106:            private TopComponent startingTransfer;
0107:            /** kind of mode into which belonged last dragged TopComponent at that time */
0108:            private int draggedKind;
0109:
0110:            /** drag feedback handler, listen to the mouse pointer motion during the drag */
0111:            private MotionListener motionListener;
0112:
0113:            /** Keeps ref to fake center panel droppable. */
0114:            private static Reference<CenterPanelDroppable> centerDropWRef = new WeakReference<CenterPanelDroppable>(
0115:                    null);
0116:
0117:            /** Keeps ref to fake editor area droppable. */
0118:            private static Reference<EditorAreaDroppable> editorDropWRef = new WeakReference<EditorAreaDroppable>(
0119:                    null);
0120:
0121:            /** Debugging flag. */
0122:            private static final boolean DEBUG = Debug
0123:                    .isLoggable(WindowDnDManager.class);
0124:
0125:            /** Creates a new instance of <code>WindowsDnDManager</code>. */
0126:            public WindowDnDManager(ViewAccessor viewAccessor) {
0127:                this .viewAccessor = viewAccessor;
0128:
0129:                // PENDING Be aware it is added only once.
0130:                Toolkit.getDefaultToolkit().addAWTEventListener(
0131:                        topComponentDragSupport,
0132:                        AWTEvent.MOUSE_EVENT_MASK
0133:                                | AWTEvent.MOUSE_MOTION_EVENT_MASK);
0134:            }
0135:
0136:            /** Indicates whether the window drag and drop is enabled. */
0137:            public static boolean isDnDEnabled() {
0138:                return !Constants.SWITCH_DND_DISABLE;
0139:            }
0140:
0141:            /** Gets the only current instance of <code>DragSource</code> used in 
0142:             * window system DnD. */
0143:            public synchronized DragSource getWindowDragSource() {
0144:                if (windowDragSource == null) {
0145:                    windowDragSource = new DragSource();
0146:                    windowDragSource
0147:                            .addDragSourceMotionListener(getMotionListener());
0148:                }
0149:                return windowDragSource;
0150:            }
0151:
0152:            /** Accessor for mouse motion listener */
0153:            MotionListener getMotionListener() {
0154:                if (motionListener == null) {
0155:                    motionListener = new MotionListener(this ,
0156:                            topComponentDragSupport);
0157:                }
0158:                return motionListener;
0159:            }
0160:
0161:            /** Indicates whether the drag is in progress or not. */
0162:            public boolean isDragging() {
0163:                return dragging;
0164:            }
0165:
0166:            /** Sets the <code>dropSuccess</code> flag. */
0167:            public void setDropSuccess(boolean dropSuccess) {
0168:                this .dropSuccess = dropSuccess;
0169:            }
0170:
0171:            /** Indicates whether the last drop operation was successful. */
0172:            public boolean isDropSuccess() {
0173:                return dropSuccess;
0174:            }
0175:
0176:            /**Sets the last drop target compoent over which hovered the mouse.
0177:             * Hacking purpose only. */
0178:            public void setLastDropTarget(DropTargetGlassPane target) {
0179:                if (target != lastTargetWRef.get()) {
0180:                    lastTargetWRef = new WeakReference<DropTargetGlassPane>(
0181:                            target);
0182:                }
0183:            }
0184:
0185:            // XXX try out to recover the DnD,
0186:            // currently impossible no API see #21791, no such API.
0187:            /** Tries to reset window DnD system in case some DnD problem occured. */
0188:            public void resetDragSource() {
0189:                dragFinished();
0190:            }
0191:
0192:            public TopComponentDroppable getStartingDroppable() {
0193:                return startingDroppable;
0194:            }
0195:
0196:            public Point getStartingPoint() {
0197:                return startingPoint;
0198:            }
0199:
0200:            public TopComponent getStartingTransfer() {
0201:                return startingTransfer;
0202:            }
0203:
0204:            /** Called when there is pending drag operation to be started.
0205:             * Informs all currently opened <code>ModeContainer</code>'s implementing
0206:             * <code>ModeContainer.DropInidicator</code> interface about
0207:             * starting drag operation. */
0208:            public void dragStarting(TopComponentDroppable startingDroppable,
0209:                    Point startingPoint, TopComponent startingTransfer) {
0210:                if (DEBUG) {
0211:                    debugLog(""); // NOI18N
0212:                    debugLog("dragStarting"); // NOI18N
0213:                }
0214:
0215:                this .startingDroppable = startingDroppable;
0216:                this .startingPoint = startingPoint;
0217:                this .startingTransfer = startingTransfer;
0218:                ModeImpl mode = (ModeImpl) WindowManagerImpl.getInstance()
0219:                        .findMode(startingTransfer);
0220:                this .draggedKind = mode != null ? mode.getKind()
0221:                        : Constants.MODE_KIND_EDITOR;
0222:
0223:                // exclude dragged separate view
0224:                /*Window rpc = SwingUtilities.getWindowAncestor(startingTransfer);
0225:                if (rpc != null && !WindowManagerImpl.getInstance().getMainWindow().equals(rpc)) {
0226:                    ZOrderManager.getInstance().setExcludeFromOrder((RootPaneContainer)rpc, true);
0227:                }*/
0228:
0229:                Map<JRootPane, Component> addedRoots = new HashMap<JRootPane, Component>();
0230:                Set<Component> addedFrames = new HashSet<Component>();
0231:
0232:                for (Component comp : viewAccessor.getModeComponents()) {
0233:                    if (comp instanceof  TopComponentDroppable) {
0234:                        // Find root pane.
0235:                        JRootPane root = null;
0236:                        if (comp instanceof  RootPaneContainer) {
0237:                            root = ((RootPaneContainer) comp).getRootPane();
0238:                        } else {
0239:                            RootPaneContainer rootContainer = (RootPaneContainer) SwingUtilities
0240:                                    .getAncestorOfClass(
0241:                                            RootPaneContainer.class, comp);
0242:                            if (rootContainer != null) {
0243:                                root = rootContainer.getRootPane();
0244:                            }
0245:                        }
0246:
0247:                        if (root != null) {
0248:                            Component originalGlass = setDropTargetGlassPane(
0249:                                    root, this );
0250:                            if (originalGlass != null) {
0251:                                addedRoots.put(root, originalGlass);
0252:                            }
0253:                        }
0254:                    }
0255:                }
0256:                for (Component w : viewAccessor.getSeparateModeFrames()) {
0257:                    if (w != null) {
0258:                        addedFrames.add(w);
0259:                    }
0260:                }
0261:
0262:                if (!addedRoots.isEmpty()) {
0263:                    synchronized (root2glass) {
0264:                        root2glass.putAll(addedRoots);
0265:                    }
0266:                }
0267:
0268:                if (!addedFrames.isEmpty()) {
0269:                    synchronized (floatingFrames) {
0270:                        floatingFrames.addAll(addedFrames);
0271:                    }
0272:                }
0273:
0274:                dragging = true;
0275:                dropSuccess = false;
0276:            }
0277:
0278:            /** Sets <code>DropTargetGlassPane<code> for specified JRootPane.
0279:             * @return original glass pane or null if there was already set drop target
0280:             *      glass pane */
0281:            private static Component setDropTargetGlassPane(JRootPane rootPane,
0282:                    WindowDnDManager windowDnDManager) {
0283:                Component glassPane = rootPane.getGlassPane();
0284:                if (glassPane instanceof  DropTargetGlassPane) {
0285:                    // There is already our glass pane.
0286:                    return null;
0287:                }
0288:
0289:                DropTargetGlassPane dropGlass = new DropTargetGlassPane(
0290:                        windowDnDManager);
0291:                // Associate with new drop target, and initialize.
0292:                new DropTarget(dropGlass, DnDConstants.ACTION_COPY_OR_MOVE,
0293:                        dropGlass);
0294:
0295:                rootPane.setGlassPane(dropGlass);
0296:                // !!! Necessary to initialize it after setGlassPane(..),
0297:                // i.e. the visibility state.
0298:                dropGlass.initialize();
0299:
0300:                return glassPane;
0301:            }
0302:
0303:            /** Called when there finished drag operation.
0304:             * Informs all turned on <code>TopComponentDroppable</code>'s
0305:             * about fininshed drag and drop. */
0306:            public void dragFinished() {
0307:                if (DEBUG) {
0308:                    debugLog(""); // NOI18N
0309:                    debugLog("dragFinished"); // NOI18N
0310:                }
0311:
0312:                // include dragged separate view back
0313:                /*Window w = SwingUtilities.getWindowAncestor(startingTransfer);
0314:                if (w != null && !WindowManagerImpl.getInstance().getMainWindow().equals(w)) {
0315:                    ZOrderManager.getInstance().setExcludeFromOrder((RootPaneContainer)w, false);
0316:                }*/
0317:
0318:                // notify motion handler
0319:                getMotionListener().dragFinished();
0320:
0321:                // PENDING
0322:                startingDroppable = null;
0323:                startingPoint = null;
0324:                startingTransfer = null;
0325:
0326:                // Inform the drag support instance about finishing of the DnD.
0327:                topComponentDragSupport.dragFinished();
0328:
0329:                dragging = false;
0330:
0331:                Map<JRootPane, Component> removedRoots;
0332:                synchronized (root2glass) {
0333:                    removedRoots = new HashMap<JRootPane, Component>(root2glass);
0334:                    root2glass.clear();
0335:                }
0336:
0337:                for (JRootPane root : removedRoots.keySet()) {
0338:                    setOriginalGlassPane(root, removedRoots.get(root));
0339:                }
0340:            }
0341:
0342:            /** Sets orgiginal glass pane to specified root pane. */
0343:            private static void setOriginalGlassPane(JRootPane rootPane,
0344:                    Component originalGlass) {
0345:                Component glass = rootPane.getGlassPane();
0346:
0347:                if (glass instanceof  DropTargetGlassPane) {
0348:                    DropTargetGlassPane dropGlass = (DropTargetGlassPane) glass;
0349:
0350:                    // Release the drop target, and unititialize.
0351:                    dropGlass.setDropTarget(null);
0352:                    dropGlass.uninitialize();
0353:                }
0354:
0355:                if (originalGlass != null) {
0356:                    rootPane.setGlassPane(originalGlass);
0357:                }
0358:
0359:                // #22962. Not selected JInternalFrame needs to have its glass pane
0360:                // switched on to work properly, ensure it is so.
0361:                JInternalFrame internalFrame = (JInternalFrame) SwingUtilities
0362:                        .getAncestorOfClass(JInternalFrame.class, originalGlass);
0363:                if (internalFrame != null && !internalFrame.isSelected()
0364:                        && !originalGlass.isVisible()) {
0365:                    originalGlass.setVisible(true);
0366:                }
0367:            }
0368:
0369:            // PENDING Better design of this issue, it needs to be performed
0370:            // later than dragFinished.
0371:            /** Maked post drag finished cleaning. Clears references to separated
0372:             * modes */
0373:            public void dragFinishedEx() {
0374:                synchronized (floatingFrames) {
0375:                    floatingFrames.clear();
0376:                }
0377:            }
0378:
0379:            /** Gets set of floating frames. */
0380:            public Set<Component> getFloatingFrames() {
0381:                synchronized (floatingFrames) {
0382:                    return new HashSet<Component>(floatingFrames);
0383:                }
0384:            }
0385:
0386:            /** Checks whether the point is inside separated (floating) frame
0387:             * droppable area. The point is relative to screen. */
0388:            public boolean isInFloatingFrame(Point location) {
0389:                for (Component w : getFloatingFrames()) {
0390:                    if (w.getBounds().contains(location)) {
0391:                        return true;
0392:                    }
0393:                }
0394:
0395:                return false;
0396:            }
0397:
0398:            // XXX
0399:            public boolean isCopyOperationPossible() {
0400:                return topComponentDragSupport.isCopyOperationPossible();
0401:            }
0402:
0403:            public Controller getController() {
0404:                return viewAccessor.getController();
0405:            }
0406:
0407:            private static void debugLog(String message) {
0408:                Debug.log(WindowDnDManager.class, message);
0409:            }
0410:
0411:            // Helpers>>
0412:            /** Checks whether the point is inside main window droppable area. 
0413:             * The point is relative to screen. */
0414:            static boolean isInMainWindow(Point location) {
0415:                return WindowManagerImpl.getInstance().getMainWindow()
0416:                        .getBounds().contains(location);
0417:            }
0418:
0419:            /** Indicates whether there is a droppable in main window, specified
0420:             * by screen location. */
0421:            private boolean isInMainWindowDroppable(Point location, int kind,
0422:                    TopComponent transfer) {
0423:                return findMainWindowDroppable(location, kind, transfer) != null;
0424:            }
0425:
0426:            /** Checks whetner the point is inside one of floating window,
0427:             * i.e. separated modes, droppable area. The point is relative to screen. */
0428:            private static boolean isInFloatingFrameDroppable(
0429:                    Set<Component> floatingFrames, Point location, int kind,
0430:                    TopComponent transfer) {
0431:                return findFloatingFrameDroppable(floatingFrames, location,
0432:                        kind, transfer) != null;
0433:            }
0434:
0435:            /** 
0436:             * Tests if given location is in free area or not.
0437:             * @param location the location to test
0438:             * @param exclude Window to exclude from test (used for fake drag-under effect window)
0439:             * @return true when location point is on free screen, not contained in any 
0440:             * frames or windows of the system, false otherwise
0441:             */
0442:            private static boolean isInFreeArea(Point location, Window exclude) {
0443:                // prepare array of all our windows
0444:                Window mainWindow = WindowManagerImpl.getInstance()
0445:                        .getMainWindow();
0446:                Window[] owned = mainWindow.getOwnedWindows();
0447:                Window[] frames = Frame.getFrames();
0448:                Window[] windows = new Window[owned.length + frames.length];
0449:                System.arraycopy(frames, 0, windows, 0, frames.length);
0450:                System
0451:                        .arraycopy(owned, 0, windows, frames.length,
0452:                                owned.length);
0453:
0454:                for (int i = 0; i < windows.length; i++) {
0455:                    // #114064: exclude fake drar under effect window from the test
0456:                    if (windows[i] == exclude) {
0457:                        continue;
0458:                    }
0459:                    //#40782 fix. don't take the invisible frames into account when deciding what is
0460:                    // free space.
0461:                    if (windows[i].isVisible()
0462:                            && windows[i].getBounds().contains(location.x,
0463:                                    location.y)) {
0464:                        return false;
0465:                    }
0466:                }
0467:
0468:                return true;
0469:            }
0470:
0471:            /** Finds <code>TopComponentDroppable</code> from specified screen location. */
0472:            private TopComponentDroppable findDroppableFromScreen(
0473:                    Set<Component> floatingFrames, Point location, int kind,
0474:                    TopComponent transfer) {
0475:
0476:                TopComponentDroppable droppable = findMainWindowDroppable(
0477:                        location, kind, transfer);
0478:                if (droppable != null) {
0479:                    return droppable;
0480:                }
0481:
0482:                droppable = findFloatingFrameDroppable(floatingFrames,
0483:                        location, kind, transfer);
0484:                if (droppable != null) {
0485:                    return droppable;
0486:                }
0487:
0488:                //        // PENDING center panel area. Maybe editor empty area -> revise later.
0489:                //        if(isAroundCenterPanel(location)) {
0490:                //            return getCenterPanelDroppable();
0491:                //        }
0492:
0493:                if (isInFreeArea(location, motionListener.fakeWindow)) {
0494:                    return getFreeAreaDroppable(location);
0495:                }
0496:                return null;
0497:            }
0498:
0499:            private CenterSlidingDroppable lastSlideDroppable;
0500:
0501:            /** Gets droppable from main window, specified by screen location.
0502:             * Helper method. */
0503:            private TopComponentDroppable findMainWindowDroppable(
0504:                    Point location, int kind, TopComponent transfer) {
0505:
0506:                MainWindow mainWindow = (MainWindow) WindowManagerImpl
0507:                        .getInstance().getMainWindow();
0508:
0509:                if (!ZOrderManager.getInstance().isOnTop(mainWindow, location)) {
0510:                    return null;
0511:                }
0512:
0513:                Point p = new Point(location);
0514:                SwingUtilities.convertPointFromScreen(p, mainWindow
0515:                        .getContentPane());
0516:                if (lastSlideDroppable != null) {
0517:                    if (lastSlideDroppable.isWithinSlide(p)) {
0518:                        return lastSlideDroppable;
0519:                    }
0520:                }
0521:                TopComponentDroppable droppable = findSlideDroppable(viewAccessor
0522:                        .getSlidingModeComponent(Constants.LEFT));
0523:                if (droppable != null) {
0524:                    CenterSlidingDroppable drop = new CenterSlidingDroppable(
0525:                            viewAccessor, droppable, Constants.LEFT);
0526:                    if (drop.isWithinSlide(p)) {
0527:                        lastSlideDroppable = drop;
0528:                        return drop;
0529:                    }
0530:                }
0531:                droppable = findSlideDroppable(viewAccessor
0532:                        .getSlidingModeComponent(Constants.RIGHT));
0533:                if (droppable != null) {
0534:                    CenterSlidingDroppable drop = new CenterSlidingDroppable(
0535:                            viewAccessor, droppable, Constants.RIGHT);
0536:                    if (drop.isWithinSlide(p)) {
0537:                        lastSlideDroppable = drop;
0538:                        return drop;
0539:                    }
0540:                }
0541:                droppable = findSlideDroppable(viewAccessor
0542:                        .getSlidingModeComponent(Constants.BOTTOM));
0543:                if (droppable != null) {
0544:                    CenterSlidingDroppable drop = new CenterSlidingDroppable(
0545:                            viewAccessor, droppable, Constants.BOTTOM);
0546:                    if (drop.isWithinSlide(p)) {
0547:                        lastSlideDroppable = drop;
0548:                        return drop;
0549:                    }
0550:                }
0551:                lastSlideDroppable = null;
0552:                if (isNearEditorEdge(location, viewAccessor, kind)) {
0553:                    return getEditorAreaDroppable();
0554:                }
0555:                if (isNearEdge(location, viewAccessor)) {
0556:                    return getCenterPanelDroppable();
0557:                }
0558:                Point mainP = new Point(location);
0559:                SwingUtilities.convertPointFromScreen(mainP, mainWindow);
0560:                return findDroppable(mainWindow, mainP, kind, transfer);
0561:            }
0562:
0563:            private static TopComponentDroppable findSlideDroppable(
0564:                    Component comp) {
0565:                TopComponentDroppable droppable = null;
0566:                if (comp instanceof  TopComponentDroppable) {
0567:                    droppable = (TopComponentDroppable) comp;
0568:                } else {
0569:                    droppable = (TopComponentDroppable) SwingUtilities
0570:                            .getAncestorOfClass(TopComponentDroppable.class,
0571:                                    comp);
0572:                }
0573:                return droppable;
0574:            }
0575:
0576:            /** Gets droppable from separated (floating) window, specified
0577:             * by screen location. Helper method. */
0578:            private static TopComponentDroppable findFloatingFrameDroppable(
0579:                    Set<Component> floatingFrames, Point location, int kind,
0580:                    TopComponent transfer) {
0581:                for (Component comp : floatingFrames) {
0582:                    Rectangle bounds = comp.getBounds();
0583:
0584:                    if (bounds.contains(location)
0585:                            && ZOrderManager.getInstance().isOnTop(
0586:                                    (RootPaneContainer) comp, location)) {
0587:                        TopComponentDroppable droppable = findDroppable(comp,
0588:                                new Point(location.x - bounds.x, location.y
0589:                                        - bounds.y), kind, transfer);
0590:                        if (droppable != null) {
0591:                            return droppable;
0592:                        }
0593:                    }
0594:                }
0595:
0596:                return null;
0597:            }
0598:
0599:            /** Finds <code>TopComponentDroppable</code> for the location in component.
0600:             * The location has to be relative to the specified component. Then the
0601:             * method finds if there is a droppable component in the hierarchy, which
0602:             * also contains the specified location.
0603:             * Utilitity method. */
0604:            private static TopComponentDroppable findDroppable(Component comp,
0605:                    Point location, int kind, TopComponent transfer) {
0606:                RootPaneContainer rpc;
0607:                if (comp instanceof  RootPaneContainer) {
0608:                    rpc = (RootPaneContainer) comp;
0609:                } else {
0610:                    Window w = SwingUtilities.getWindowAncestor(comp);
0611:                    if (w instanceof  RootPaneContainer) {
0612:                        rpc = (RootPaneContainer) w;
0613:                    } else {
0614:                        return null;
0615:                    }
0616:                }
0617:
0618:                Component contentPane = rpc.getContentPane();
0619:                location = SwingUtilities.convertPoint(comp, location,
0620:                        contentPane);
0621:                Component deepest = SwingUtilities.getDeepestComponentAt(
0622:                        contentPane, location.x, location.y);
0623:
0624:                if (deepest instanceof  MultiSplitPane) {
0625:                    MultiSplitPane splitPane = (MultiSplitPane) deepest;
0626:                    int dx = 0, dy = 0;
0627:                    if (splitPane.isHorizontalSplit())
0628:                        dx = splitPane.getDividerSize() + 1;
0629:                    else
0630:                        dy = splitPane.getDividerSize() + 1;
0631:                    Point pt = SwingUtilities.convertPoint(contentPane,
0632:                            location, deepest);
0633:                    deepest = SwingUtilities.getDeepestComponentAt(deepest,
0634:                            pt.x + dx, pt.y + dy);
0635:                }
0636:
0637:                if (deepest instanceof  TopComponentDroppable) {
0638:                    TopComponentDroppable droppable = (TopComponentDroppable) deepest;
0639:                    if (droppable.supportsKind(kind, transfer)) {
0640:                        return droppable;
0641:                    }
0642:                }
0643:
0644:                while (deepest != null) {
0645:                    TopComponentDroppable nextDroppable = (TopComponentDroppable) SwingUtilities
0646:                            .getAncestorOfClass(TopComponentDroppable.class,
0647:                                    deepest);
0648:                    if (nextDroppable != null
0649:                            && nextDroppable.supportsKind(kind, transfer)) {
0650:                        return nextDroppable;
0651:                    }
0652:                    deepest = (Component) nextDroppable;
0653:                }
0654:                return null;
0655:            }
0656:
0657:            /** Indicates whether the cursor is around center panel of main window.
0658:             * In that case is needed also to provide a drop. */
0659:            static boolean isAroundCenterPanel(Point location) {
0660:                Component desktop = ((MainWindow) WindowManagerImpl
0661:                        .getInstance().getMainWindow()).getDesktop();
0662:                if (desktop == null) {
0663:                    return false;
0664:                }
0665:
0666:                Point p = new Point(location);
0667:                SwingUtilities.convertPointFromScreen(p, desktop.getParent());
0668:                Rectangle centerBounds = desktop.getBounds();
0669:
0670:                if (!centerBounds.contains(p)) {
0671:                    centerBounds.grow(Constants.DROP_AREA_SIZE,
0672:                            Constants.DROP_AREA_SIZE);
0673:                    if (centerBounds.contains(p)) {
0674:                        return true;
0675:                    }
0676:                }
0677:                return false;
0678:            }
0679:
0680:            /** Indicates whether the cursor is around the editor area of the main window.
0681:             * In that case is needed also to provide a drop. */
0682:            static boolean isNearEditorEdge(Point location,
0683:                    ViewAccessor viewAccessor, int kind) {
0684:                Component editor = WindowManagerImpl.getInstance()
0685:                        .getEditorAreaComponent();
0686:                if (editor == null) {
0687:                    return false;
0688:                }
0689:                Point p = new Point(location);
0690:                SwingUtilities.convertPointFromScreen(p, editor.getParent());
0691:                Rectangle editorBounds = editor.getBounds();
0692:                editorBounds.y -= 10;
0693:                editorBounds.height += 10;
0694:                Rectangle shrinked = editor.getBounds();
0695:                shrinked.grow(-10, 0);
0696:                shrinked.height -= 10;
0697:                Component dr = viewAccessor
0698:                        .getSlidingModeComponent(Constants.RIGHT);
0699:                if (dr != null) {
0700:                    shrinked.width = shrinked.width - dr.getBounds().width;
0701:                }
0702:                dr = viewAccessor.getSlidingModeComponent(Constants.BOTTOM);
0703:                if (dr != null) {
0704:                    shrinked.height = shrinked.height - dr.getBounds().height;
0705:                }
0706:                return editorBounds.contains(p) && !shrinked.contains(p)
0707:                        && kind == Constants.MODE_KIND_EDITOR;
0708:            }
0709:
0710:            /** Indicates whether the cursor is around center panel of main window.
0711:             * In that case is needed also to provide a drop. */
0712:            static boolean isNearEdge(Point location, ViewAccessor viewAccessor) {
0713:                Component desktop = ((MainWindow) WindowManagerImpl
0714:                        .getInstance().getMainWindow()).getDesktop();
0715:                if (desktop == null) {
0716:                    return false;
0717:                }
0718:                Point p = new Point(location);
0719:                SwingUtilities.convertPointFromScreen(p, desktop);
0720:                Rectangle centerBounds = desktop.getBounds();
0721:                centerBounds.y -= 20;
0722:                centerBounds.height += 20;
0723:                Rectangle shrinked = desktop.getBounds();
0724:                shrinked.grow(-10, 0);
0725:                shrinked.height -= 10;
0726:                Component dr = viewAccessor
0727:                        .getSlidingModeComponent(Constants.LEFT);
0728:                if (dr != null) {
0729:                    shrinked.x = shrinked.x + dr.getBounds().width;
0730:                    shrinked.width = shrinked.width - dr.getBounds().width;
0731:                }
0732:                dr = viewAccessor.getSlidingModeComponent(Constants.RIGHT);
0733:                if (dr != null) {
0734:                    shrinked.width = shrinked.width - dr.getBounds().width;
0735:                }
0736:                dr = viewAccessor.getSlidingModeComponent(Constants.BOTTOM);
0737:                if (dr != null) {
0738:                    shrinked.height = shrinked.height - dr.getBounds().height;
0739:                }
0740:                boolean cont = centerBounds.contains(p)
0741:                        && !shrinked.contains(p);
0742:
0743:                return cont;
0744:            }
0745:
0746:            /** Creates fake droppable for center panel. */
0747:            private TopComponentDroppable getCenterPanelDroppable() {
0748:                CenterPanelDroppable droppable = centerDropWRef.get();
0749:
0750:                if (droppable == null) {
0751:                    droppable = new CenterPanelDroppable();
0752:                    centerDropWRef = new WeakReference<CenterPanelDroppable>(
0753:                            droppable);
0754:                }
0755:
0756:                return droppable;
0757:            }
0758:
0759:            private static TopComponentDroppable getFreeAreaDroppable(
0760:                    Point location) {
0761:                return new FreeAreaDroppable(location);
0762:            }
0763:
0764:            /** Creates fake droppable for editor area. */
0765:            private TopComponentDroppable getEditorAreaDroppable() {
0766:                EditorAreaDroppable droppable = editorDropWRef.get();
0767:
0768:                if (droppable == null) {
0769:                    droppable = new EditorAreaDroppable();
0770:                    editorDropWRef = new WeakReference<EditorAreaDroppable>(
0771:                            droppable);
0772:                }
0773:
0774:                return droppable;
0775:            }
0776:
0777:            /** 
0778:             * Tries to perform actual drop.
0779:             * @param location screen location */
0780:            boolean tryPerformDrop(Controller controller,
0781:                    Set<Component> floatingFrames, Point location,
0782:                    int dropAction, Transferable transferable) {
0783:                TopComponent[] tcArray = extractTopComponent(
0784:                        dropAction == DnDConstants.ACTION_COPY, transferable);
0785:
0786:                if (tcArray == null || tcArray.length == 0) {
0787:                    return false;
0788:                }
0789:
0790:                ModeImpl mode = (ModeImpl) WindowManagerImpl.getInstance()
0791:                        .findMode(tcArray[0]);
0792:                int kind = mode != null ? mode.getKind()
0793:                        : Constants.MODE_KIND_EDITOR;
0794:
0795:                TopComponentDroppable droppable = findDroppableFromScreen(
0796:                        floatingFrames, location, kind, tcArray[0]);
0797:                if (droppable == null) {
0798:                    return false;
0799:                }
0800:
0801:                Component dropComponent = droppable.getDropComponent();
0802:                if (dropComponent != null) {
0803:                    SwingUtilities.convertPointFromScreen(location,
0804:                            dropComponent);
0805:                }
0806:                return performDrop(controller, droppable, dropAction, tcArray,
0807:                        location, draggedKind);
0808:            }
0809:
0810:            /** Extracts <code>TopComponent</code> instance from
0811:             * <code>Transferable</code> according the <code>dropAction</code>.
0812:             * Utility method. */
0813:            static TopComponent[] extractTopComponent(boolean clone,
0814:                    Transferable tr) {
0815:                DataFlavor df = getDataFlavorForDropAction(clone);
0816:
0817:                if (df == null) {
0818:                    // No data flavor -> unsupported drop action.
0819:                    return null;
0820:                }
0821:
0822:                // Test whether the requested dataflavor is supported by transferable.
0823:                if (tr.isDataFlavorSupported(df)) {
0824:                    try {
0825:                        TopComponent tc;
0826:
0827:                        if (clone) {
0828:                            TopComponent.Cloneable ctc = (TopComponent.Cloneable) tr
0829:                                    .getTransferData(df);
0830:
0831:                            // "Copy" the top component.
0832:                            tc = ctc.cloneComponent();
0833:                        } else {
0834:                            tc = (TopComponent) tr.getTransferData(df);
0835:                        }
0836:
0837:                        return new TopComponent[] { tc };
0838:                    } catch (UnsupportedFlavorException ufe) {
0839:                        Logger.getLogger(WindowDnDManager.class.getName()).log(
0840:                                Level.WARNING, null, ufe);
0841:                    } catch (IOException ioe) {
0842:                        Logger.getLogger(WindowDnDManager.class.getName()).log(
0843:                                Level.WARNING, null, ioe);
0844:                    }
0845:                }
0846:
0847:                df = new DataFlavor(
0848:                        TopComponentDragSupport.MIME_TOP_COMPONENT_ARRAY, null);
0849:                if (tr.isDataFlavorSupported(df)) {
0850:                    try {
0851:                        return (TopComponent[]) tr.getTransferData(df);
0852:                    } catch (UnsupportedFlavorException ufe) {
0853:                        Logger.getLogger(WindowDnDManager.class.getName()).log(
0854:                                Level.WARNING, null, ufe);
0855:                    } catch (IOException ioe) {
0856:                        Logger.getLogger(WindowDnDManager.class.getName()).log(
0857:                                Level.WARNING, null, ioe);
0858:                    }
0859:                }
0860:
0861:                return null;
0862:            }
0863:
0864:            /** Gets <code>DataFlavor</code> for specific drop action type.
0865:             * Helper utility method. */
0866:            private static DataFlavor getDataFlavorForDropAction(boolean clone) {
0867:                // Create needed dataflavor.
0868:                DataFlavor df;
0869:                if (clone) {
0870:                    df = new DataFlavor(
0871:                            TopComponentDragSupport.MIME_TOP_COMPONENT_CLONEABLE,
0872:                            null);
0873:                } else {
0874:                    df = new DataFlavor(
0875:                            TopComponentDragSupport.MIME_TOP_COMPONENT, null);
0876:                }
0877:
0878:                return df;
0879:            }
0880:
0881:            /**
0882:             * Performs actual drop operation. Called from DropTargetListener.
0883:             * @return <code>true</code> if the drop was successful */
0884:            private static boolean performDrop(Controller controller,
0885:                    TopComponentDroppable droppable, int dropAction,
0886:                    TopComponent[] tcArray, Point location, int draggedKind) {
0887:                if (DEBUG) {
0888:                    debugLog(""); // NOI18N
0889:                    debugLog("performDrop"); // NOI18N
0890:                    debugLog("droppable=" + droppable); // NOI18N
0891:                }
0892:
0893:                if (tcArray == null || tcArray.length == 0) {
0894:                    return true;
0895:                }
0896:
0897:                if (!droppable.canDrop(tcArray[0], location)) {
0898:                    return true;
0899:                }
0900:
0901:                ViewElement viewElement = droppable.getDropViewElement();
0902:                Object constr = droppable.getConstraintForLocation(location);
0903:
0904:                if (viewElement instanceof  EditorView) {
0905:                    ModeImpl mode = (ModeImpl) WindowManagerImpl.getInstance()
0906:                            .findMode(tcArray[0]);
0907:                    int kind = mode != null ? mode.getKind()
0908:                            : Constants.MODE_KIND_EDITOR;
0909:                    if (kind == Constants.MODE_KIND_EDITOR) {
0910:                        controller
0911:                                .userDroppedTopComponentsIntoEmptyEditor(tcArray);
0912:                    } else {
0913:                        if (constr == Constants.TOP || constr == Constants.LEFT
0914:                                || constr == Constants.RIGHT
0915:                                || constr == Constants.BOTTOM) {
0916:                            controller.userDroppedTopComponentsAroundEditor(
0917:                                    tcArray, (String) constr, kind);
0918:                        } else if (Constants.SWITCH_MODE_ADD_NO_RESTRICT
0919:                                || WindowManagerImpl.getInstance()
0920:                                        .isTopComponentAllowedToMoveAnywhere(
0921:                                                tcArray[0])) {
0922:                            controller
0923:                                    .userDroppedTopComponentsIntoEmptyEditor(tcArray);
0924:                        }
0925:                    }
0926:                } else if (viewElement instanceof  ModeView) {
0927:                    ModeView modeView = (ModeView) viewElement;
0928:                    if (constr == Constants.TOP || constr == Constants.LEFT
0929:                            || constr == Constants.RIGHT
0930:                            || constr == Constants.BOTTOM) {
0931:                        controller.userDroppedTopComponents(modeView, tcArray,
0932:                                (String) constr);
0933:                    } else if (constr instanceof  Integer) {
0934:                        controller.userDroppedTopComponents(modeView, tcArray,
0935:                                ((Integer) constr).intValue());
0936:                    } else {
0937:                        controller.userDroppedTopComponents(modeView, tcArray);
0938:                    }
0939:                } else if (viewElement == null) { // XXX around area or free area
0940:                    if (constr == Constants.TOP || constr == Constants.LEFT
0941:                            || constr == Constants.RIGHT
0942:                            || constr == Constants.BOTTOM) { // XXX around area
0943:                        if (droppable instanceof  EditorAreaDroppable) {
0944:                            controller.userDroppedTopComponentsAroundEditor(
0945:                                    tcArray, (String) constr,
0946:                                    Constants.MODE_KIND_EDITOR);
0947:                        } else {
0948:                            controller.userDroppedTopComponentsAround(tcArray,
0949:                                    (String) constr);
0950:                        }
0951:                    } else if (constr instanceof  Rectangle) { // XXX free area
0952:                        Rectangle bounds = (Rectangle) constr;
0953:                        // #38657 Refine bounds.
0954:                        Component modeComp = SwingUtilities.getAncestorOfClass(
0955:                                ModeComponent.class, tcArray[0]);
0956:                        if (modeComp != null) {
0957:                            bounds.setSize(modeComp.getWidth(), modeComp
0958:                                    .getHeight());
0959:                        }
0960:
0961:                        controller.userDroppedTopComponentsIntoFreeArea(
0962:                                tcArray, bounds, draggedKind);
0963:                    }
0964:                }
0965:
0966:                return true;
0967:            }
0968:
0969:            // Helpers<<
0970:
0971:            /** Handles mouse cursors shapes and drag-under feedback during the drag.
0972:             */
0973:            private static class MotionListener implements 
0974:                    DragSourceMotionListener {
0975:
0976:                private final WindowDnDManager windowDnDManager;
0977:                private final TopComponentDragSupport topComponentDragSupport;
0978:
0979:                private Point previousDragLoc;
0980:
0981:                /** window used to simulate drag under effect when dropping to free screen area */
0982:                private Window fakeWindow;
0983:
0984:                /** helper; true when size of fake window set and known, false otherwise */
0985:                private boolean isSizeSet;
0986:
0987:                /** Constrtucts the instance.
0988:                 * Adds the listener to the window dnd <code>DragSource</code>. */
0989:                private MotionListener(WindowDnDManager windowDnDManager,
0990:                        TopComponentDragSupport topComponentDragSupport) {
0991:                    this .windowDnDManager = windowDnDManager;
0992:                    this .topComponentDragSupport = topComponentDragSupport;
0993:                }
0994:
0995:                /** Implements <code>DragSourceMotionListener</code>. */
0996:                public void dragMouseMoved(DragSourceDragEvent evt) {
0997:                    if (DEBUG) {
0998:                        debugLog("dragMouseMoved evt=" + evt); // NOI18N
0999:                    }
1000:
1001:                    Point location = evt.getLocation();
1002:                    if (location == null) {
1003:                        return;
1004:                    }
1005:
1006:                    // move separate windows along with the mouse
1007:                    /*if (Constants.MODE_STATE_SEPARATED == mode.getState()) {
1008:                        handleWindowMove(mode, windowDnDManager.startingTransfer, evt);
1009:                    }*/
1010:                    boolean isInMainDroppable = windowDnDManager
1011:                            .isInMainWindowDroppable(location,
1012:                                    windowDnDManager.draggedKind,
1013:                                    windowDnDManager.startingTransfer);
1014:                    boolean isInFrameDroppable = isInFloatingFrameDroppable(
1015:                            windowDnDManager.getFloatingFrames(), location,
1016:                            windowDnDManager.draggedKind,
1017:                            windowDnDManager.startingTransfer);
1018:                    boolean isAroundCenterPanel = isAroundCenterPanel(location);
1019:                    boolean shouldPaintFakeWindow = false;
1020:
1021:                    if (isInMainDroppable || isInFrameDroppable
1022:                            || isAroundCenterPanel) {
1023:                        TopComponentDroppable droppable = windowDnDManager
1024:                                .findDroppableFromScreen(windowDnDManager
1025:                                        .getFloatingFrames(), location,
1026:                                        windowDnDManager.draggedKind,
1027:                                        windowDnDManager.startingTransfer);
1028:                        //hack - can't get the bounds correctly, sometimes freearedroppable gets here..
1029:
1030:                        if (droppable instanceof  FreeAreaDroppable) {
1031:                            if (WindowManagerImpl.getInstance()
1032:                                    .getEditorAreaState() == Constants.EDITOR_AREA_SEPARATED
1033:                                    && droppable.canDrop(
1034:                                            windowDnDManager.startingTransfer,
1035:                                            location)) {
1036:                                topComponentDragSupport.setSuccessCursor(true);
1037:                            } else {
1038:                                topComponentDragSupport.setUnsuccessCursor();
1039:                            }
1040:                            // for the status bar it's null somehow, workarounding by checking for null.. should go away..
1041:                        } else if (droppable != null) {
1042:
1043:                            // was probably forgotten to set the lastdrop target, was causing strange repaint side effects when 2 frames overlapped.
1044:                            JComponent cp = (JComponent) droppable
1045:                                    .getDropComponent();
1046:                            Component glass = cp.getRootPane().getGlassPane();
1047:                            if (glass instanceof  DropTargetGlassPane) {
1048:                                windowDnDManager
1049:                                        .setLastDropTarget((DropTargetGlassPane) glass);
1050:                            }
1051:                            Point p = new Point(location);
1052:                            SwingUtilities.convertPointFromScreen(p, droppable
1053:                                    .getDropComponent());
1054:                            if (droppable.canDrop(
1055:                                    windowDnDManager.startingTransfer, p)) {
1056:                                topComponentDragSupport.setSuccessCursor(false);
1057:                            } else {
1058:                                topComponentDragSupport.setUnsuccessCursor();
1059:                            }
1060:                            dragOverDropTarget(location, droppable);
1061:                        }
1062:                    } else if (!isInMainWindow(location)
1063:                            && windowDnDManager.isInFloatingFrame(location)) {
1064:                        // Simulates success drop in free area.
1065:                        topComponentDragSupport.setSuccessCursor(false);
1066:                    } else if (isInFreeArea(location, fakeWindow)
1067:                            && getFreeAreaDroppable(location)
1068:                                    .canDrop(windowDnDManager.startingTransfer,
1069:                                            location)) {
1070:                        topComponentDragSupport.setSuccessCursor(true);
1071:                        // paint fake window during move over free area
1072:                        //                shouldPaintFakeWindow = true;
1073:                    } else {
1074:                        topComponentDragSupport.setUnsuccessCursor();
1075:                    }
1076:                    paintFakeWindow(shouldPaintFakeWindow, evt);
1077:
1078:                    if (!isInMainDroppable && !isInFrameDroppable
1079:                            && !isAroundCenterPanel) {
1080:                        clearExitedDropTarget();
1081:                    }
1082:                }
1083:
1084:                /** Simulates dropOver event, for glass pane to indicate possible drop
1085:                 * operation. */
1086:                private/*static*/void dragOverDropTarget(Point location,
1087:                        TopComponentDroppable droppable) {
1088:                    DropTargetGlassPane lastTarget = windowDnDManager.lastTargetWRef
1089:                            .get();
1090:
1091:                    if (lastTarget != null) {
1092:                        Point p = new Point(location);
1093:                        SwingUtilities.convertPointFromScreen(p, lastTarget);
1094:                        lastTarget.dragOver(p, droppable);
1095:                    }
1096:                }
1097:
1098:                /** Hacks drag exit from drop target (glass pane).
1099:                 * Eliminates bug, where remained drop indicator drawed
1100:                 * even for cases the cursor was away from drop target. Missing
1101:                 * drag exit event. */
1102:                private/*static*/void clearExitedDropTarget() {
1103:                    DropTargetGlassPane lastTarget = windowDnDManager.lastTargetWRef
1104:                            .get();
1105:
1106:                    if (lastTarget != null) {
1107:                        lastTarget.clearIndications();
1108:                        windowDnDManager.lastTargetWRef = new WeakReference<DropTargetGlassPane>(
1109:                                null);
1110:                    }
1111:                }
1112:
1113:                /** Gets main drop target glass pane.*/
1114:                private static DropTargetGlassPane getMainDropTargetGlassPane() {
1115:                    Component glass = ((JFrame) WindowManagerImpl.getInstance()
1116:                            .getMainWindow()).getGlassPane();
1117:                    if (glass instanceof  DropTargetGlassPane) {
1118:                        return (DropTargetGlassPane) glass;
1119:                    } else {
1120:                        return null;
1121:                    }
1122:                }
1123:
1124:                void dragFinished() {
1125:                    previousDragLoc = null;
1126:                    if (fakeWindow != null) {
1127:                        fakeWindow.dispose();
1128:                        fakeWindow = null;
1129:                    }
1130:                }
1131:
1132:                /** Shows or hides fake window as drag under effect
1133:                 */
1134:                private void paintFakeWindow(boolean visible,
1135:                        DragSourceDragEvent evt) {
1136:                    //            Point loc = evt.getLocation();
1137:                    //            // no window if location is unknown
1138:                    //            if (loc == null) {
1139:                    //                return;
1140:                    //            }
1141:                    //            if (fakeWindow == null) {
1142:                    //                fakeWindow = createFakeWindow();
1143:                    //                isSizeSet = false;
1144:                    //            }
1145:                    //            fakeWindow.setLocation(loc);
1146:                    //            fakeWindow.setVisible(visible);
1147:                    //            // calculate space for window with decorations (title, border...)
1148:                    //            if (visible && !isSizeSet) {
1149:                    //                Dimension size = windowDnDManager.startingTransfer.getSize();
1150:                    //                Insets insets = fakeWindow.getInsets();
1151:                    //                size.width += insets.left + insets.right;
1152:                    //                size.height += insets.top + insets.bottom;
1153:                    //                fakeWindow.setSize(size);
1154:                    //                isSizeSet = true;
1155:                    //            }
1156:                }
1157:
1158:                /** Creates and returns fake window as drag under effect */
1159:                private Window createFakeWindow() {
1160:                    Window result;
1161:                    if (windowDnDManager.draggedKind == Constants.MODE_KIND_EDITOR) {
1162:                        result = new JFrame();
1163:                    } else {
1164:                        result = new JDialog((JFrame) null);
1165:                    }
1166:                    result.setAlwaysOnTop(true);
1167:                    return result;
1168:                }
1169:
1170:            } // End of class MotionListener.
1171:
1172:            // XXX
1173:            /** Interface for accessing   */
1174:            public interface ViewAccessor {
1175:                public Set<Component> getModeComponents();
1176:
1177:                public Set<Component> getSeparateModeFrames();
1178:
1179:                public Controller getController();
1180:
1181:                public Component getSlidingModeComponent(String side);
1182:            } // End of ViewState.
1183:
1184:            /** Fake helper droppable used when used around  */
1185:            private class CenterPanelDroppable implements  TopComponentDroppable {
1186:
1187:                /** Implements <code>TopComponentDroppable</code>. */
1188:                public java.awt.Shape getIndicationForLocation(Point p) {
1189:                    Rectangle bounds = getDropComponent().getBounds();
1190:                    Rectangle res = null;
1191:                    double ratio = Constants.DROP_AROUND_RATIO;
1192:                    Object constraint = getConstraintForLocation(p);
1193:                    if (constraint == JSplitPane.LEFT) {
1194:                        res = new Rectangle(0, 0,
1195:                                (int) (bounds.width * ratio) - 1,
1196:                                bounds.height - 1);
1197:                    } else if (constraint == JSplitPane.TOP) {
1198:                        res = new Rectangle(0, 0, bounds.width - 1,
1199:                                (int) (bounds.height * ratio) - 1);
1200:                    } else if (constraint == JSplitPane.RIGHT) {
1201:                        res = new Rectangle(bounds.width
1202:                                - (int) (bounds.width * ratio), 0,
1203:                                (int) (bounds.width * ratio) - 1,
1204:                                bounds.height - 1);
1205:                    } else if (constraint == JSplitPane.BOTTOM) {
1206:                        res = new Rectangle(0, bounds.height
1207:                                - (int) (bounds.height * ratio),
1208:                                bounds.width - 1,
1209:                                (int) (bounds.height * ratio) - 1);
1210:                    }
1211:
1212:                    return res;
1213:                }
1214:
1215:                /** Implements <code>TopComponentDroppable</code>. */
1216:                public Object getConstraintForLocation(Point p) {
1217:                    Rectangle bounds = getDropComponent().getBounds();
1218:                    Component leftSlide = viewAccessor
1219:                            .getSlidingModeComponent(Constants.LEFT);
1220:                    Component rightSlide = viewAccessor
1221:                            .getSlidingModeComponent(Constants.RIGHT);
1222:                    Component bottomSlide = viewAccessor
1223:                            .getSlidingModeComponent(Constants.BOTTOM);
1224:                    if (null != leftSlide
1225:                            && p.x < leftSlide.getBounds().width + 10) {
1226:                        return javax.swing.JSplitPane.LEFT;
1227:                    } else if (p.y < bounds.y) {
1228:                        return javax.swing.JSplitPane.TOP;
1229:                    } else if (null != rightSlide
1230:                            && null != leftSlide
1231:                            && p.x > bounds.width - 10
1232:                                    - rightSlide.getBounds().width
1233:                                    - leftSlide.getBounds().width) {
1234:                        return javax.swing.JSplitPane.RIGHT;
1235:                    } else if (null != bottomSlide
1236:                            && p.y > bounds.height - 10
1237:                                    - bottomSlide.getBounds().height) {
1238:                        return javax.swing.JSplitPane.BOTTOM;
1239:                    }
1240:
1241:                    return null;
1242:                }
1243:
1244:                /** Implements <code>TopComponentDroppable</code>. */
1245:                public Component getDropComponent() {
1246:                    return ((MainWindow) WindowManagerImpl.getInstance()
1247:                            .getMainWindow()).getDesktop();
1248:                }
1249:
1250:                /** Implements <code>TopComponentDroppable</code>. */
1251:                public ViewElement getDropViewElement() {
1252:                    return null;
1253:                }
1254:
1255:                public boolean canDrop(TopComponent transfer, Point location) {
1256:                    if (Constants.SWITCH_MODE_ADD_NO_RESTRICT
1257:                            || WindowManagerImpl.getInstance()
1258:                                    .isTopComponentAllowedToMoveAnywhere(
1259:                                            transfer)) {
1260:                        return true;
1261:                    }
1262:
1263:                    ModeImpl mode = (ModeImpl) WindowManagerImpl.getInstance()
1264:                            .findMode(transfer);
1265:                    return mode != null
1266:                            && (mode.getKind() == Constants.MODE_KIND_VIEW || mode
1267:                                    .getKind() == Constants.MODE_KIND_SLIDING);
1268:                }
1269:
1270:                public boolean supportsKind(int kind, TopComponent transfer) {
1271:                    if (Constants.SWITCH_MODE_ADD_NO_RESTRICT
1272:                            || WindowManagerImpl.getInstance()
1273:                                    .isTopComponentAllowedToMoveAnywhere(
1274:                                            transfer)) {
1275:                        return true;
1276:                    }
1277:
1278:                    return kind == Constants.MODE_KIND_VIEW
1279:                            || kind == Constants.MODE_KIND_SLIDING;
1280:                }
1281:
1282:            } // End of class CenterPanelDroppable.
1283:
1284:            /** Fake helper droppable used when used around  */
1285:            private class EditorAreaDroppable implements  TopComponentDroppable {
1286:
1287:                /** Implements <code>TopComponentDroppable</code>. */
1288:                public java.awt.Shape getIndicationForLocation(Point p) {
1289:                    Rectangle bounds = getDropComponent().getBounds();
1290:                    Rectangle res = null;
1291:                    double ratio = Constants.DROP_AROUND_RATIO;
1292:                    Object constraint = getConstraintForLocation(p);
1293:                    if (constraint == JSplitPane.LEFT) {
1294:                        res = new Rectangle(0, 0,
1295:                                (int) (bounds.width * ratio) - 1,
1296:                                bounds.height - 1);
1297:                    } else if (constraint == JSplitPane.TOP) {
1298:                        res = new Rectangle(0, 0, bounds.width - 1,
1299:                                (int) (bounds.height * ratio) - 1);
1300:                    } else if (constraint == JSplitPane.RIGHT) {
1301:                        res = new Rectangle(bounds.width
1302:                                - (int) (bounds.width * ratio), 0,
1303:                                (int) (bounds.width * ratio) - 1,
1304:                                bounds.height - 1);
1305:                    } else if (constraint == JSplitPane.BOTTOM) {
1306:                        res = new Rectangle(0, bounds.height
1307:                                - (int) (bounds.height * ratio),
1308:                                bounds.width - 1,
1309:                                (int) (bounds.height * ratio) - 1);
1310:                    }
1311:
1312:                    return res;
1313:                }
1314:
1315:                /** Implements <code>TopComponentDroppable</code>. */
1316:                public Object getConstraintForLocation(Point p) {
1317:                    Rectangle bounds = getDropComponent().getBounds();
1318:                    Component leftSlide = viewAccessor
1319:                            .getSlidingModeComponent(Constants.LEFT);
1320:                    Component rightSlide = viewAccessor
1321:                            .getSlidingModeComponent(Constants.RIGHT);
1322:                    Component bottomSlide = viewAccessor
1323:                            .getSlidingModeComponent(Constants.BOTTOM);
1324:                    if (null != leftSlide
1325:                            && p.x < leftSlide.getBounds().width + 10) {
1326:                        return javax.swing.JSplitPane.LEFT;
1327:                    } else if (p.y < bounds.y) {
1328:                        return javax.swing.JSplitPane.TOP;
1329:                    } else if (null != rightSlide
1330:                            && null != leftSlide
1331:                            && p.x > bounds.width - 10
1332:                                    - rightSlide.getBounds().width
1333:                                    - leftSlide.getBounds().width) {
1334:                        return javax.swing.JSplitPane.RIGHT;
1335:                    } else if (null != bottomSlide
1336:                            && p.y > bounds.height - 10
1337:                                    - bottomSlide.getBounds().height) {
1338:                        return javax.swing.JSplitPane.BOTTOM;
1339:                    }
1340:
1341:                    return null;
1342:                }
1343:
1344:                /** Implements <code>TopComponentDroppable</code>. */
1345:                public Component getDropComponent() {
1346:                    return WindowManagerImpl.getInstance()
1347:                            .getEditorAreaComponent();
1348:                }
1349:
1350:                /** Implements <code>TopComponentDroppable</code>. */
1351:                public ViewElement getDropViewElement() {
1352:                    return null;
1353:                }
1354:
1355:                public boolean canDrop(TopComponent transfer, Point location) {
1356:                    if (Constants.SWITCH_MODE_ADD_NO_RESTRICT
1357:                            || WindowManagerImpl.getInstance()
1358:                                    .isTopComponentAllowedToMoveAnywhere(
1359:                                            transfer)) {
1360:                        return true;
1361:                    }
1362:
1363:                    ModeImpl mode = (ModeImpl) WindowManagerImpl.getInstance()
1364:                            .findMode(transfer);
1365:                    return mode != null
1366:                            && mode.getKind() == Constants.MODE_KIND_EDITOR;
1367:                }
1368:
1369:                public boolean supportsKind(int kind, TopComponent transfer) {
1370:                    if (Constants.SWITCH_MODE_ADD_NO_RESTRICT
1371:                            || WindowManagerImpl.getInstance()
1372:                                    .isTopComponentAllowedToMoveAnywhere(
1373:                                            transfer)) {
1374:                        return true;
1375:                    }
1376:
1377:                    return kind == Constants.MODE_KIND_EDITOR;
1378:                }
1379:
1380:            } // End of class EditorAreaDroppable.
1381:
1382:            /** Fake helper droppable used when dropping is done into free area.  */
1383:            private static class FreeAreaDroppable implements 
1384:                    TopComponentDroppable {
1385:
1386:                private Point location;
1387:
1388:                public FreeAreaDroppable(Point location) {
1389:                    this .location = location;
1390:                }
1391:
1392:                /** Implements <code>TopComponentDroppable</code>. */
1393:                public java.awt.Shape getIndicationForLocation(Point p) {
1394:                    return null;
1395:                }
1396:
1397:                /** Implements <code>TopComponentDroppable</code>. */
1398:                public Object getConstraintForLocation(Point p) {
1399:                    return new Rectangle(location.x, location.y,
1400:                            Constants.DROP_NEW_MODE_SIZE.width,
1401:                            Constants.DROP_NEW_MODE_SIZE.height);
1402:                }
1403:
1404:                /** Implements <code>TopComponentDroppable</code>. */
1405:                public Component getDropComponent() {
1406:                    return null;
1407:                }
1408:
1409:                /** Implements <code>TopComponentDroppable</code>. */
1410:                public ViewElement getDropViewElement() {
1411:                    return null;
1412:                }
1413:
1414:                public boolean canDrop(TopComponent transfer, Point location) {
1415:                    ModeImpl mode = (ModeImpl) WindowManagerImpl.getInstance()
1416:                            .findMode(transfer);
1417:                    if (mode == null) {
1418:                        return false;
1419:                    }
1420:                    if (Constants.SWITCH_MODE_ADD_NO_RESTRICT
1421:                            || WindowManagerImpl.getInstance()
1422:                                    .isTopComponentAllowedToMoveAnywhere(
1423:                                            transfer)) {
1424:                        return true;
1425:                    }
1426:
1427:                    // don't accept drop from separated mode with single component in it,
1428:                    // it makes no sense (because such DnD into free area equals to
1429:                    // simple window move)
1430:                    if (mode.getState() == Constants.MODE_STATE_SEPARATED
1431:                            && mode.getOpenedTopComponents().size() == 1) {
1432:                        return false;
1433:                    }
1434:
1435:                    return true;
1436:                }
1437:
1438:                public boolean supportsKind(int kind, TopComponent transfer) {
1439:                    return true;
1440:                }
1441:
1442:            } // End of class FreeAreaDroppable.
1443:
1444:            /**
1445:             * droppable for the sliding bars, both inside and outside of the main window.
1446:             *
1447:             */
1448:            private static class CenterSlidingDroppable implements 
1449:                    TopComponentDroppable, EnhancedDragPainter {
1450:
1451:                private ViewAccessor accesor;
1452:                private TopComponentDroppable original;
1453:                private String side;
1454:                JPanel pan;
1455:                private boolean isShowing;
1456:
1457:                public CenterSlidingDroppable(ViewAccessor viewAccesor,
1458:                        TopComponentDroppable slidingBarDelegate, String side) {
1459:                    original = slidingBarDelegate;
1460:                    accesor = viewAccesor;
1461:                    this .side = side;
1462:                    pan = new JPanel();
1463:                    isShowing = false;
1464:                }
1465:
1466:                public boolean canDrop(TopComponent transfer, Point location) {
1467:                    return original.canDrop(transfer, location);
1468:                }
1469:
1470:                public Object getConstraintForLocation(Point location) {
1471:                    return original.getConstraintForLocation(location);
1472:                }
1473:
1474:                public Component getDropComponent() {
1475:                    return original.getDropComponent();
1476:                }
1477:
1478:                public ViewElement getDropViewElement() {
1479:                    return original.getDropViewElement();
1480:                }
1481:
1482:                public Shape getIndicationForLocation(Point location) {
1483:                    Shape toReturn = original
1484:                            .getIndicationForLocation(location);
1485:                    Rectangle dim = original.getDropComponent().getBounds();
1486:                    if (dim.width < 10 || dim.height < 10) {
1487:                        Rectangle rect = toReturn.getBounds();
1488:                        if (Constants.LEFT.equals(side)) {
1489:                            toReturn = new Rectangle(0, 0, Math.max(rect.width,
1490:                                    Constants.DROP_AREA_SIZE), Math.max(
1491:                                    rect.height, Constants.DROP_AREA_SIZE));
1492:                        } else if (Constants.RIGHT.equals(side)) {
1493:                            toReturn = new Rectangle(-Constants.DROP_AREA_SIZE,
1494:                                    0, Math.max(rect.width,
1495:                                            Constants.DROP_AREA_SIZE), Math
1496:                                            .max(rect.height,
1497:                                                    Constants.DROP_AREA_SIZE));
1498:                        } else if (Constants.BOTTOM.equals(side)) {
1499:                            toReturn = new Rectangle(0,
1500:                                    -Constants.DROP_AREA_SIZE, Math.max(
1501:                                            rect.width,
1502:                                            Constants.DROP_AREA_SIZE), Math
1503:                                            .max(rect.height,
1504:                                                    Constants.DROP_AREA_SIZE));
1505:                        }
1506:                    }
1507:                    return toReturn;
1508:                }
1509:
1510:                public boolean isWithinSlide(Point location) {
1511:                    Component root = SwingUtilities.getRootPane(original
1512:                            .getDropComponent());
1513:                    Point barLoc = SwingUtilities.convertPoint(root, location,
1514:                            original.getDropComponent());
1515:                    if (original.getDropComponent().contains(barLoc)) {
1516:                        return true;
1517:                    }
1518:                    Dimension dim = original.getDropComponent().getSize();
1519:                    if (Constants.LEFT.equals(side)) {
1520:                        int abs = Math.abs(barLoc.x);
1521:                        if (barLoc.y > -Constants.DROP_AREA_SIZE
1522:                                && barLoc.y < dim.height
1523:                                        + Constants.DROP_AREA_SIZE) {
1524:                            if (isShowing && abs < Constants.DROP_AREA_SIZE) {
1525:                                return true;
1526:                            }
1527:                            if (!isShowing && barLoc.x <= 0
1528:                                    && barLoc.x > -Constants.DROP_AREA_SIZE) {
1529:                                return true;
1530:                            }
1531:                        }
1532:                    } else if (Constants.RIGHT.equals(side)) {
1533:                        if (barLoc.y > -Constants.DROP_AREA_SIZE
1534:                                && barLoc.y < dim.height
1535:                                        + Constants.DROP_AREA_SIZE) {
1536:                            if (isShowing
1537:                                    && ((barLoc.x < 0 && barLoc.x > -Constants.DROP_AREA_SIZE) || barLoc.x > 0
1538:                                            && barLoc.x - dim.width < Constants.DROP_AREA_SIZE)) {
1539:                                return true;
1540:                            }
1541:                            if (!isShowing
1542:                                    && barLoc.x >= 0
1543:                                    && barLoc.x < Constants.DROP_AREA_SIZE
1544:                                            + dim.width) {
1545:                                return true;
1546:                            }
1547:                        }
1548:                    } else if (Constants.BOTTOM.equals(side)) {
1549:                        if (barLoc.x > -Constants.DROP_AREA_SIZE
1550:                                && barLoc.x < dim.width
1551:                                        + Constants.DROP_AREA_SIZE) {
1552:                            if (isShowing
1553:                                    && ((barLoc.y < 0 && barLoc.y > -Constants.DROP_AREA_SIZE) || barLoc.y > 0
1554:                                            && barLoc.y - dim.height < Constants.DROP_AREA_SIZE)) {
1555:                                return true;
1556:                            }
1557:                            if (!isShowing
1558:                                    && barLoc.y >= 0
1559:                                    && barLoc.y < Constants.DROP_AREA_SIZE
1560:                                            + dim.height) {
1561:                                return true;
1562:                            }
1563:                        }
1564:                    }
1565:                    return false;
1566:
1567:                }
1568:
1569:                public boolean supportsKind(int kind, TopComponent transfer) {
1570:                    return original.supportsKind(kind, transfer);
1571:                }
1572:
1573:                public void additionalDragPaint(Graphics2D g) {
1574:                    Rectangle dim = original.getDropComponent().getBounds();
1575:                    if (dim.width > 10 && dim.height > 10) {
1576:                        return;
1577:                    }
1578:                    isShowing = true;
1579:                    Component glassPane = ((JComponent) original
1580:                            .getDropComponent()).getRootPane().getGlassPane();
1581:                    Point leftTop = SwingUtilities.convertPoint(original
1582:                            .getDropComponent(), 0, 0, glassPane);
1583:                    Point firstDivider;
1584:                    Point secondDevider;
1585:
1586:                    if (Constants.RIGHT.equals(side)) {
1587:                        leftTop = new Point(leftTop.x - 24, leftTop.y);
1588:                        firstDivider = new Point(leftTop);
1589:                        secondDevider = new Point(leftTop.x, leftTop.y
1590:                                + dim.height);
1591:                    } else if (Constants.BOTTOM.equals(side)) {
1592:                        leftTop = new Point(0, leftTop.y - 24);
1593:                        firstDivider = new Point(leftTop);
1594:                        secondDevider = new Point(leftTop.x
1595:                                + glassPane.getBounds().width, leftTop.y);
1596:                    } else {
1597:                        firstDivider = new Point(leftTop.x + 25, leftTop.y);
1598:                        secondDevider = new Point(leftTop.x + 25, leftTop.y
1599:                                + dim.height);
1600:                    }
1601:                    Rectangle rect = new Rectangle(leftTop.x, leftTop.y, Math
1602:                            .max(25, dim.width), Math.max(25, dim.height));
1603:                    if (Constants.BOTTOM.equals(side)) {
1604:                        // for bottom has special hack to use the whole width
1605:                        rect.width = glassPane.getBounds().width;
1606:                    }
1607:
1608:                    Color col = g.getColor();
1609:                    g.setColor(pan.getBackground());
1610:                    g.fill(rect);
1611:                    g.setColor(pan.getBackground().darker());
1612:                    g.drawLine(firstDivider.x, firstDivider.y, secondDevider.x,
1613:                            secondDevider.y);
1614:                    g.setColor(col);
1615:                }
1616:
1617:                public Rectangle getPaintArea() {
1618:                    Rectangle dim = original.getDropComponent().getBounds();
1619:                    if (dim.width > 10 && dim.height > 10) {
1620:                        return null;
1621:                    }
1622:                    Component glassPane = ((JComponent) original
1623:                            .getDropComponent()).getRootPane().getGlassPane();
1624:                    Point leftTop = SwingUtilities.convertPoint(original
1625:                            .getDropComponent(), 0, 0, glassPane);
1626:
1627:                    if (Constants.RIGHT.equals(side)) {
1628:                        leftTop = new Point(leftTop.x - 24, leftTop.y);
1629:                    } else if (Constants.BOTTOM.equals(side)) {
1630:                        leftTop = new Point(0, leftTop.y - 24);
1631:                    }
1632:                    Rectangle rect = new Rectangle(leftTop.x, leftTop.y, Math
1633:                            .max(25, dim.width), Math.max(25, dim.height));
1634:                    if (Constants.BOTTOM.equals(side)) {
1635:                        // for bottom has special hack to use the whole width
1636:                        rect.width = glassPane.getBounds().width;
1637:                    }
1638:                    return rect;
1639:                }
1640:            }
1641:
1642:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.