Source Code Cross Referenced for DockingWindow.java in  » Swing-Library » InfoNode-Docking-Windows » net » infonode » docking » 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 » Swing Library » InfoNode Docking Windows » net.infonode.docking 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (C) 2004 NNL Technology AB
0003:         * Visit www.infonode.net for information about InfoNode(R) 
0004:         * products and how to contact NNL Technology AB.
0005:         *
0006:         * This program is free software; you can redistribute it and/or
0007:         * modify it under the terms of the GNU General Public License
0008:         * as published by the Free Software Foundation; either version 2
0009:         * of the License, or (at your option) any later version.
0010:         *
0011:         * This program is distributed in the hope that it will be useful,
0012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014:         * GNU General Public License for more details.
0015:         *
0016:         * You should have received a copy of the GNU General Public License
0017:         * along with this program; if not, write to the Free Software
0018:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
0019:         * MA 02111-1307, USA.
0020:         */
0021:
0022:        // $Id: DockingWindow.java,v 1.119 2007/01/28 21:25:09 jesper Exp $
0023:        package net.infonode.docking;
0024:
0025:        import net.infonode.docking.drag.DockingWindowDragger;
0026:        import net.infonode.docking.drop.ChildDropInfo;
0027:        import net.infonode.docking.drop.DropFilter;
0028:        import net.infonode.docking.drop.SplitDropInfo;
0029:        import net.infonode.docking.internal.ReadContext;
0030:        import net.infonode.docking.internal.WindowAncestors;
0031:        import net.infonode.docking.internal.WriteContext;
0032:        import net.infonode.docking.internalutil.DropAction;
0033:        import net.infonode.docking.location.LocationDecoder;
0034:        import net.infonode.docking.model.SplitWindowItem;
0035:        import net.infonode.docking.model.TabWindowItem;
0036:        import net.infonode.docking.model.ViewWriter;
0037:        import net.infonode.docking.model.WindowItem;
0038:        import net.infonode.docking.properties.DockingWindowProperties;
0039:        import net.infonode.docking.title.DockingWindowTitleProvider;
0040:        import net.infonode.docking.title.SimpleDockingWindowTitleProvider;
0041:        import net.infonode.docking.util.DockingUtil;
0042:        import net.infonode.gui.ComponentUtil;
0043:        import net.infonode.gui.EventUtil;
0044:        import net.infonode.gui.mouse.MouseButtonListener;
0045:        import net.infonode.gui.panel.BasePanel;
0046:        import net.infonode.properties.propertymap.*;
0047:        import net.infonode.util.ArrayUtil;
0048:        import net.infonode.util.Direction;
0049:
0050:        import javax.swing.*;
0051:        import java.awt.*;
0052:        import java.awt.event.MouseAdapter;
0053:        import java.awt.event.MouseEvent;
0054:        import java.io.IOException;
0055:        import java.io.ObjectInputStream;
0056:        import java.io.ObjectOutputStream;
0057:        import java.lang.ref.WeakReference;
0058:        import java.util.ArrayList;
0059:        import java.util.HashSet;
0060:        import java.util.Iterator;
0061:        import java.util.Map;
0062:
0063:        /**
0064:         * This is the base class for all types of docking windows. The windows are structured in a tree, typically with a
0065:         * {@link RootWindow} at the root. Each DockingWindow has a window parent and a number of child windows.
0066:         * <p>
0067:         * <b>Warning: </b> the non-public methods in this class can be changed in non-compatible ways in future versions.
0068:         *
0069:         * @author $Author: jesper $
0070:         * @version $Revision: 1.119 $
0071:         */
0072:        abstract public class DockingWindow extends BasePanel {
0073:            private static int DROP_FLOATING_YOFFSET = 10;
0074:
0075:            /**
0076:             * Returns the icon for this window.
0077:             *
0078:             * @return the icon
0079:             */
0080:            abstract public Icon getIcon();
0081:
0082:            /**
0083:             * Returns the child window with index <tt>index</tt>.
0084:             *
0085:             * @param index the child window index
0086:             * @return the child window
0087:             */
0088:            abstract public DockingWindow getChildWindow(int index);
0089:
0090:            /**
0091:             * Returns the number of child windows.
0092:             *
0093:             * @return the number of child windows
0094:             */
0095:            abstract public int getChildWindowCount();
0096:
0097:            /**
0098:             *
0099:             */
0100:            abstract protected void doReplace(DockingWindow oldWindow,
0101:                    DockingWindow newWindow);
0102:
0103:            /**
0104:             *
0105:             */
0106:            abstract protected void doRemoveWindow(DockingWindow window);
0107:
0108:            /**
0109:             *
0110:             */
0111:            abstract protected void update();
0112:
0113:            abstract void removeWindowComponent(DockingWindow window);
0114:
0115:            abstract void restoreWindowComponent(DockingWindow window);
0116:
0117:            private DockingWindow windowParent;
0118:            private WindowTab tab;
0119:            private DockingWindow lastFocusedChildWindow;
0120:            private WindowPopupMenuFactory popupMenuFactory;
0121:            private ArrayList mouseButtonListeners;
0122:            private ArrayList listeners;
0123:
0124:            private PropertyMapListener propertiesListener = new PropertyMapListener() {
0125:                public void propertyValuesChanged(PropertyMap propertyMap,
0126:                        Map changes) {
0127:                    doUpdate();
0128:
0129:                    updateButtonVisibility();
0130:                }
0131:            };
0132:
0133:            private PropertyMapTreeListener propertyObjectTreeListener = new PropertyMapTreeListener() {
0134:                public void propertyValuesChanged(Map changes) {
0135:                    doUpdate();
0136:                }
0137:            };
0138:
0139:            private static HashSet optimizeWindows = new HashSet();
0140:            private static int optimizeDepth;
0141:
0142:            private WindowItem windowItem;
0143:            private WeakReference lastRootWindow = new WeakReference(null);
0144:
0145:            private static int updateModelDepth;
0146:
0147:            /**
0148:             *
0149:             */
0150:            protected DockingWindow(WindowItem windowItem) {
0151:                DockingWindow window = windowItem.getConnectedWindow();
0152:
0153:                if (window != null)
0154:                    window.setWindowItem(windowItem.copy());
0155:
0156:                this .windowItem = windowItem;
0157:                this .windowItem.setConnectedWindow(this );
0158:
0159:                addMouseListener(new MouseAdapter() {
0160:                    public void mousePressed(MouseEvent e) {
0161:                        if (e.isPopupTrigger()) {
0162:                            showPopupMenu(e);
0163:                        }
0164:                    }
0165:
0166:                    public void mouseReleased(MouseEvent e) {
0167:                        mousePressed(e);
0168:                    }
0169:                });
0170:            }
0171:
0172:            /**
0173:             *
0174:             */
0175:            protected void init() {
0176:                PropertyMapWeakListenerManager.addWeakListener(
0177:                        getWindowProperties().getMap(), propertiesListener);
0178:                PropertyMapWeakListenerManager.addWeakTreeListener(
0179:                        getPropertyObject(), propertyObjectTreeListener);
0180:                doUpdate();
0181:                updateWindowItem(getRootWindow());
0182:            }
0183:
0184:            /**
0185:             *
0186:             */
0187:            private void doUpdate() {
0188:                update();
0189:
0190:                if (tab != null)
0191:                    tab.windowTitleChanged();
0192:
0193:                if (windowParent != null
0194:                        && windowParent.getChildWindowCount() == 1)
0195:                    windowParent.doUpdate();
0196:            }
0197:
0198:            protected void addWindowItem(DockingWindow w, int index) {
0199:                boolean isRestore = w.getWindowItem().isRestoreWindow();
0200:                windowItem.addWindow(w.getWindowItem(), index);
0201:
0202:                if (!isRestore)
0203:                    w.updateWindowItems();
0204:            }
0205:
0206:            protected final void updateWindowItems() {
0207:                windowItem.clearWindows();
0208:
0209:                for (int i = 0; i < getChildWindowCount(); i++) {
0210:                    boolean isRestore = getChildWindow(i).windowItem
0211:                            .isRestoreWindow();
0212:                    windowItem.addWindow(getChildWindow(i).windowItem);
0213:
0214:                    if (!isRestore)
0215:                        getChildWindow(i).updateWindowItems();
0216:                }
0217:            }
0218:
0219:            /**
0220:             * <p>
0221:             * Sets the preferred minimize direction of this window. If the {@link WindowBar} in this direction is enabled this
0222:             * window will be placed on that bar when {@link #minimize()} is called.
0223:             * </p>
0224:             *
0225:             * <p>
0226:             * Note that a window will "remember" the last {@link WindowBar} it was added to so the preferred minimize direction
0227:             * is changed when the window is added to another {@link WindowBar}.
0228:             * </p>
0229:             *
0230:             * @param direction the preferred minimize direction of this window, null (which is default value) means use the
0231:             *                  closest, enabled {@link WindowBar}
0232:             * @since IDW 1.3.0
0233:             */
0234:            public void setPreferredMinimizeDirection(Direction direction) {
0235:                windowItem.setLastMinimizedDirection(direction);
0236:            }
0237:
0238:            /**
0239:             * <p>
0240:             * Gets the preferred minimize direction of this window. See {@link #setPreferredMinimizeDirection(net.infonode.util.Direction)}
0241:             * for more information.
0242:             * </p>
0243:             *
0244:             * @return the preferred minimize direction of this window, null if the closest {@link WindowBar} is used
0245:             * @since IDW 1.3.0
0246:             */
0247:            public Direction getPreferredMinimizeDirection() {
0248:                return windowItem.getLastMinimizedDirection();
0249:            }
0250:
0251:            private ArrayList getMouseButtonListeners() {
0252:                return mouseButtonListeners;
0253:            }
0254:
0255:            private void setMouseButtonListeners(ArrayList listeners) {
0256:                mouseButtonListeners = listeners;
0257:            }
0258:
0259:            private ArrayList getListeners() {
0260:                return listeners;
0261:            }
0262:
0263:            private void setListeners(ArrayList listeners) {
0264:                this .listeners = listeners;
0265:            }
0266:
0267:            public boolean isUndocked() {
0268:                return windowParent != null && windowParent.isUndocked();
0269:            }
0270:
0271:            /**
0272:             * <p>
0273:             * Adds a listener that receives mouse button events for window tabs. The
0274:             * listener will be called when a mouse button is pressed, clicked or released
0275:             * on a window tab of this window or a descendant of this window.
0276:             * </p>
0277:             *
0278:             * <p>
0279:             * The listeners are called in the reverse order they were added, so the last
0280:             * added listener will be called first. When all the listeners of this window
0281:             * has been called, the event is propagated up to the window parent of this
0282:             * window, if there is one.
0283:             * </p>
0284:             *
0285:             * <p>
0286:             * The {@link MouseEvent}source is the docking window connected to the tab in
0287:             * which the mouse event occured. The event point is the mouse coordinate
0288:             * where the event occured relative to the window.
0289:             * </p>
0290:             *
0291:             * @param listenerDocking the listener
0292:             * @since IDW 1.3.0
0293:             */
0294:            public void addTabMouseButtonListener(
0295:                    MouseButtonListener listenerDocking) {
0296:                if (getMouseButtonListeners() == null)
0297:                    setMouseButtonListeners(new ArrayList(2));
0298:
0299:                getMouseButtonListeners().add(listenerDocking);
0300:            }
0301:
0302:            /**
0303:             * Removes a mouse button listener that has been previously added using the
0304:             * {@link #addTabMouseButtonListener(MouseButtonListener)}.
0305:             *
0306:             * @param listenerDocking the listener
0307:             * @since IDW 1.3.0
0308:             */
0309:            public void removeTabMouseButtonListener(
0310:                    MouseButtonListener listenerDocking) {
0311:                if (getMouseButtonListeners() != null) {
0312:                    if (getMouseButtonListeners().remove(listenerDocking)
0313:                            && getMouseButtonListeners().size() == 0)
0314:                        setMouseButtonListeners(null);
0315:                }
0316:            }
0317:
0318:            void fireTabWindowMouseButtonEvent(MouseEvent event) {
0319:                fireTabWindowMouseButtonEvent(this , EventUtil.convert(event,
0320:                        this ));
0321:            }
0322:
0323:            void fireTabWindowMouseButtonEvent(DockingWindow window,
0324:                    MouseEvent event) {
0325:                if (getMouseButtonListeners() != null) {
0326:                    MouseButtonListener[] l = (MouseButtonListener[]) getMouseButtonListeners()
0327:                            .toArray(
0328:                                    new MouseButtonListener[getMouseButtonListeners()
0329:                                            .size()]);
0330:
0331:                    for (int i = l.length - 1; i >= 0; i--)
0332:                        l[i].mouseButtonEvent(event);
0333:                }
0334:
0335:                if (windowParent != null)
0336:                    windowParent.fireTabWindowMouseButtonEvent(window, event);
0337:            }
0338:
0339:            /**
0340:             * Adds a listener which will reveive events for this window and all child windows.
0341:             *
0342:             * @param listener the listener
0343:             * @since IDW 1.1.0
0344:             */
0345:            public void addListener(DockingWindowListener listener) {
0346:                if (getListeners() == null)
0347:                    setListeners(new ArrayList(2));
0348:
0349:                getListeners().add(listener);
0350:            }
0351:
0352:            /**
0353:             * Removes a previously added listener.
0354:             *
0355:             * @param listener the listener
0356:             * @since IDW 1.1.0
0357:             */
0358:            public void removeListener(DockingWindowListener listener) {
0359:                if (getListeners() != null) {
0360:                    getListeners().remove(listener);
0361:
0362:                    if (getListeners().size() == 0)
0363:                        setListeners(null);
0364:                }
0365:            }
0366:
0367:            /**
0368:             * Returns the window parent of this window.
0369:             *
0370:             * @return the window parent of this window
0371:             */
0372:            public DockingWindow getWindowParent() {
0373:                return windowParent;
0374:            }
0375:
0376:            /**
0377:             * Splits this window in the given direction. If this window is a View which is contained in a TabWindow with a single
0378:             * tab, the TabWindow will splitted instead of this View.
0379:             *
0380:             * @param splitWithWindow the splitWithWindow which to split with
0381:             * @param direction       the split direction
0382:             * @param dividerLocation the relative split divider location (0 - 1)
0383:             * @return the resulting split window
0384:             */
0385:            public SplitWindow split(final DockingWindow splitWithWindow,
0386:                    final Direction direction, final float dividerLocation) {
0387:                final SplitWindow w = new SplitWindow(
0388:                        direction == Direction.RIGHT
0389:                                || direction == Direction.LEFT);
0390:
0391:                optimizeAfter(splitWithWindow.getWindowParent(),
0392:                        new Runnable() {
0393:                            public void run() {
0394:                                getWindowParent().replaceChildWindow(
0395:                                        DockingWindow.this , w);
0396:                                w
0397:                                        .setWindows(
0398:                                                direction == Direction.DOWN
0399:                                                        || direction == Direction.RIGHT ? DockingWindow.this 
0400:                                                        : splitWithWindow,
0401:                                                direction == Direction.UP
0402:                                                        || direction == Direction.LEFT ? DockingWindow.this 
0403:                                                        : splitWithWindow);
0404:                                w.setDividerLocation(dividerLocation);
0405:                                w.getWindowParent().optimizeWindowLayout();
0406:                            }
0407:                        });
0408:
0409:                return w;
0410:            }
0411:
0412:            /**
0413:             * Starts a drag and drop operation for this window.
0414:             *
0415:             * @param dropTarget the {@link RootWindow} in which the window can be dropped
0416:             * @return an {@link DockingWindowDragger} object which controls the drag and drop operation
0417:             * @since IDW 1.3.0
0418:             */
0419:            public DockingWindowDragger startDrag(RootWindow dropTarget) {
0420:                return new WindowDragger(this , dropTarget);
0421:            }
0422:
0423:            /**
0424:             * Returns the properties for this window.
0425:             *
0426:             * @return the properties for this window
0427:             */
0428:            public DockingWindowProperties getWindowProperties() {
0429:                return getWindowItem().getDockingWindowProperties();
0430:            }
0431:
0432:            /**
0433:             * Returns the {@link RootWindow} which contains this window, null if there is none.
0434:             *
0435:             * @return the {@link RootWindow}, null if there is none
0436:             */
0437:            public RootWindow getRootWindow() {
0438:                return windowParent == null ? null : windowParent
0439:                        .getRootWindow();
0440:            }
0441:
0442:            /**
0443:             * Same as {@link #restore()}, but the {@link DockingWindowListener#windowRestoring(DockingWindow)} method of
0444:             * the window listeners will be called before restoring the window, giving them the possibility to abort the restore
0445:             * operation.
0446:             *
0447:             * @throws OperationAbortedException if the restore operation was aborted by a window listener
0448:             * @see #restore()
0449:             * @see DockingWindowListener#windowMinimizing(DockingWindow)
0450:             * @since IDW 1.4.0
0451:             */
0452:            public void restoreWithAbort() throws OperationAbortedException {
0453:                fireWindowRestoring(this );
0454:                restore();
0455:            }
0456:
0457:            /**
0458:             * Restores this window to the location before it was minimized, maximized or closed.
0459:             * If the window can't be restored to the exact same location, a good approximation is performed. It's not guaranteed
0460:             * that the window is shown anywhere after this method has returned.
0461:             */
0462:            public void restore() {
0463:                if (isMaximized())
0464:                    doRestoreFromMaximize();
0465:                else if (isMinimized() || getRootWindow() == null) {
0466:                    //    	DockingWindow lastFocused = getLastFocusedChildWindow();
0467:                    ArrayList views = new ArrayList();
0468:                    findViews(views);
0469:                    ArrayList ancestors = new ArrayList();
0470:
0471:                    for (int i = 0; i < views.size(); i++)
0472:                        ancestors.add(((DockingWindow) views.get(i))
0473:                                .getAncestors());
0474:
0475:                    restoreViews(views);
0476:
0477:                    for (int i = 0; i < views.size(); i++) {
0478:                        DockingWindow window = (DockingWindow) views.get(i);
0479:                        window.doFireWindowRestored(window);
0480:
0481:                        DockingWindow[] a = (DockingWindow[]) ancestors.get(i);
0482:
0483:                        for (int k = 0; k < a.length; k++)
0484:                            a[k].doFireWindowRestored(window);
0485:                    }
0486:
0487:                    //			if (getRootWindow() != null && lastFocused != null)
0488:                    restoreFocus(); //FocusManager.focusWindow(lastFocused);
0489:                }
0490:
0491:                updateButtonVisibility();
0492:            }
0493:
0494:            private DockingWindow doRestoreFromMaximize() {
0495:                DockingWindow restoredInWindow = null;
0496:
0497:                if (isUndocked()) {
0498:                    FloatingWindow w = DockingUtil.getFloatingWindowFor(this );
0499:                    if (w != null) {
0500:                        w.setMaximizedWindow(null);
0501:                        restoredInWindow = w;
0502:                    }
0503:                } else {
0504:                    RootWindow w = getRootWindow();
0505:                    if (w != null) {
0506:                        w.setMaximizedWindow(null);
0507:                        restoredInWindow = w;
0508:                    }
0509:                }
0510:
0511:                return restoredInWindow;
0512:            }
0513:
0514:            private ArrayList doRestore() {
0515:                ArrayList views = new ArrayList();
0516:                findViews(views);
0517:                restoreViews(views);
0518:
0519:                return views;
0520:            }
0521:
0522:            /**
0523:             * <p>Removes this window from it's window parent. If the window parent is a split window or a tab window with
0524:             * one child, it will be removed as well.</p>
0525:             *
0526:             * <p>The location of this window is saved and the window can be restored to that location using the
0527:             * {@link #restore()} method.</p>
0528:             *
0529:             * <p>This method will call the {@link DockingWindowListener#windowClosed(DockingWindow)} method of all the listeners
0530:             * of this window and all window ancestors. The listeners of child windows will not be notified, for example closing
0531:             * a tab window containing views will not notify the listeners of views in that tab window.</p>
0532:             */
0533:            public void close() {
0534:                if (windowParent != null) {
0535:                    DockingWindow[] ancestors = getAncestors();
0536:                    optimizeAfter(windowParent, new Runnable() {
0537:                        public void run() {
0538:                            windowParent.removeChildWindow(DockingWindow.this );
0539:                        }
0540:                    });
0541:
0542:                    for (int i = ancestors.length - 1; i >= 0; i--)
0543:                        ancestors[i].fireWindowClosed(this );
0544:                }
0545:            }
0546:
0547:            /**
0548:             * Same as {@link #close()}, but the {@link DockingWindowListener#windowClosing(DockingWindow)} method of
0549:             * the window listeners will be called before closing the window, giving them the possibility to abort the close
0550:             * operation.
0551:             *
0552:             * @throws OperationAbortedException if the close operation was aborted by a window listener
0553:             * @see #close()
0554:             * @see DockingWindowListener#windowClosing(DockingWindow)
0555:             * @since IDW 1.1.0
0556:             */
0557:            public void closeWithAbort() throws OperationAbortedException {
0558:                fireWindowClosing(this );
0559:                close();
0560:            }
0561:
0562:            /**
0563:             * <p>Undocks this window from it's window parent i.e. creates a {@link FloatingWindow} containing this window.</p>
0564:             *
0565:             * <p>The window can be docked again by calling {@link #dock()}.</p>
0566:             *
0567:             * <p>This method will call the {@link DockingWindowListener#windowUndocked(DockingWindow)} method of all the listeners
0568:             * of this window and all window ancestors. The listeners of child windows will not be notified, for example undocking
0569:             * a tab window containing views will not notify the listeners of views in that tab window.</p>
0570:             *
0571:             * @param location floating window location in screen coordinates
0572:             * @return the floating window containing the undocked window
0573:             * @since IDW 1.4.0
0574:             */
0575:            public FloatingWindow undock(Point location) {
0576:                FloatingWindow fw = getRootWindow().createFloatingWindow(this ,
0577:                        location);
0578:                return fw;
0579:            }
0580:
0581:            /**
0582:             * Same as {@link #undock(Point)}, but the {@link DockingWindowListener#windowUndocking(DockingWindow)} method of
0583:             * the window listeners will be called before undocking the window, giving them the possibility to abort the undock
0584:             * operation.
0585:             *
0586:             * @param location floating window location in screen coordinates
0587:             * @return the floating window containing the undocked window
0588:             * @throws OperationAbortedException if the undock operation was aborted by a window listener
0589:             * @see #undock(Point)
0590:             * @see DockingWindowListener#windowClosing(DockingWindow)
0591:             * @since IDW 1.4.0
0592:             */
0593:            public FloatingWindow undockWithAbort(Point location)
0594:                    throws OperationAbortedException {
0595:                fireWindowUndocking(this );
0596:                return undock(location);
0597:            }
0598:
0599:            /**
0600:             * <p>Docks the window to the RootWindow to the location it had before it was undocked.</p>
0601:             *
0602:             * <p>If the window can't be docked to the exact same location, a good approximation is performed. It's not
0603:             * guaranteed that the window is shown anywhere after this method has returned.
0604:             * </p>
0605:             *
0606:             * <p>This method will call the {@link DockingWindowListener#windowDocked(DockingWindow)} method of all the listeners
0607:             * of this window and all window ancestors. The listeners of child windows will not be notified, for example docking
0608:             * a tab window containing views will not notify the listeners of views in that tab window.</p>
0609:             *
0610:             * @since IDW 1.4.0
0611:             */
0612:            public void dock() {
0613:                if (isUndocked()) {
0614:                    ArrayList dockedViews = doRestore();
0615:
0616:                    updateButtonVisibility();
0617:
0618:                    fireWindowDocked(dockedViews);
0619:
0620:                    if (dockedViews.size() > 0
0621:                            && ((DockingWindow) dockedViews.get(0))
0622:                                    .getRootWindow() != null)
0623:                        FocusManager.focusWindow((DockingWindow) dockedViews
0624:                                .get(0));
0625:                }
0626:            }
0627:
0628:            /**
0629:             * Same as {@link #dock()}, but the {@link DockingWindowListener#windowDocking(DockingWindow)} method of
0630:             * the window listeners will be called before docking the window, giving them the possibility to abort the dock
0631:             * operation.
0632:             *
0633:             * @throws OperationAbortedException if the dock operation was aborted by a window listener
0634:             * @see #dock()
0635:             * @see DockingWindowListener#windowDocking(DockingWindow)
0636:             * @since IDW 1.4.0
0637:             */
0638:            public void dockWithAbort() throws OperationAbortedException {
0639:                if (isUndocked()) {
0640:                    fireWindowDocking(this );
0641:                    dock();
0642:                }
0643:            }
0644:
0645:            /**
0646:             * Returns the index of a child windows.
0647:             *
0648:             * @param window the child window
0649:             * @return the index of the child window, -1 if the window is not a child of this window
0650:             */
0651:            public int getChildWindowIndex(DockingWindow window) {
0652:                for (int i = 0; i < getChildWindowCount(); i++)
0653:                    if (getChildWindow(i) == window)
0654:                        return i;
0655:
0656:                return -1;
0657:            }
0658:
0659:            /**
0660:             * Returns the popup menu factory for this window. If it's null the window parent popup menu factory will be used
0661:             * when the mouse popup trigger is activated on this window.
0662:             *
0663:             * @return the popup menu factory for this window, null if there is none
0664:             */
0665:            public WindowPopupMenuFactory getPopupMenuFactory() {
0666:                return popupMenuFactory;
0667:            }
0668:
0669:            /**
0670:             * Sets the popup menu factory for this window. If it's not null a popup menu will be created and shown when the mouse
0671:             * popup trigger is activated on this window.
0672:             *
0673:             * @param popupMenuFactory the popup menu factory, null if no popup menu should be shown
0674:             */
0675:            public void setPopupMenuFactory(
0676:                    WindowPopupMenuFactory popupMenuFactory) {
0677:                this .popupMenuFactory = popupMenuFactory;
0678:            }
0679:
0680:            /**
0681:             * Returns true if this window is minimized, ie located in a {@link WindowBar}.
0682:             *
0683:             * @return true if this window is minimized
0684:             */
0685:            public boolean isMinimized() {
0686:                return windowParent != null && windowParent.isMinimized();
0687:            }
0688:
0689:            /**
0690:             * Returns the child window that last contained focus.
0691:             *
0692:             * @return the child window that last contained focus, null if no child window has contained focus or the child
0693:             *         has been removed from this window
0694:             */
0695:            public DockingWindow getLastFocusedChildWindow() {
0696:                return lastFocusedChildWindow;
0697:            }
0698:
0699:            /**
0700:             * Maximizes this window in its root window or in its floating window. If this window has no root window nothing
0701:             * happens. This method takes the window component and displays it at the top in the root window or in the floating
0702:             * window. It does NOT modify the window tree structure, ie the window parent remains the unchanged.
0703:             *
0704:             * <p>The location of this window is saved and the window can be restored to that location using the
0705:             * {@link #restore()} method.</p>
0706:             *
0707:             * @since IDW 1.1.0
0708:             */
0709:            public final void maximize() {
0710:                if (isUndocked()) {
0711:                    FloatingWindow w = DockingUtil.getFloatingWindowFor(this );
0712:
0713:                    if (w != null)
0714:                        w.setMaximizedWindow(this );
0715:                } else {
0716:                    RootWindow rootWindow = getRootWindow();
0717:
0718:                    if (rootWindow != null)
0719:                        rootWindow.setMaximizedWindow(this );
0720:                }
0721:
0722:                updateButtonVisibility();
0723:            }
0724:
0725:            /**
0726:             * Same as {@link #maximize()}, but the {@link DockingWindowListener#windowMaximized(DockingWindow)} method of
0727:             * the window listeners will be called before maximizing the window, giving them the possibility to abort the maximize
0728:             * operation.
0729:             *
0730:             * @throws OperationAbortedException if the maximize operation was aborted by a window listener
0731:             * @see #maximize()
0732:             * @see DockingWindowListener#windowMinimizing(DockingWindow)
0733:             * @since IDW 1.4.0
0734:             */
0735:            public void maximizeWithAbort() throws OperationAbortedException {
0736:                if (!isMaximized()) {
0737:                    fireWindowMaximizing(this );
0738:                    maximize();
0739:                }
0740:            }
0741:
0742:            /**
0743:             * Returns true if this window has a root window and is maximized in that root window or in a floating window.
0744:             *
0745:             * @return true if this window has a root window and is maximized in that root window or in a floating window
0746:             * @since IDW 1.1.0
0747:             */
0748:            public boolean isMaximized() {
0749:                DockingWindow w;
0750:                if (isUndocked()) {
0751:                    FloatingWindow floatingWindow = DockingUtil
0752:                            .getFloatingWindowFor(this );
0753:                    w = floatingWindow != null ? floatingWindow
0754:                            .getMaximizedWindow() : null;
0755:                } else {
0756:                    RootWindow rootWindow = getRootWindow();
0757:                    w = rootWindow != null ? rootWindow.getMaximizedWindow()
0758:                            : null;
0759:                }
0760:                return w == this ;
0761:            }
0762:
0763:            /**
0764:             * Minimizes this window. The window is minimized to the {@link WindowBar} in the preferred minimize direction,
0765:             * see {@link #setPreferredMinimizeDirection(net.infonode.util.Direction)} and {@link #getPreferredMinimizeDirection()}.
0766:             * If the {@link WindowBar} in that direction is not enabled, or the direction is null, thiw window is placed on the
0767:             * closest enabled {@link WindowBar}.
0768:             * If no suitable {@link WindowBar} was found or this window already is minimized, no action is performed.
0769:             *
0770:             * <p>The location of this window is saved and the window can be restored to that location using the
0771:             * {@link #restore()} method.</p>
0772:             */
0773:            public void minimize() {
0774:                getOptimizedWindow().doMinimize();
0775:            }
0776:
0777:            /**
0778:             * Minimizes this window to a {@link WindowBar}located in <tt>direction</tt>. If no suitable {@link WindowBar}was
0779:             * found or this window already is minimized, no action is performed.
0780:             *
0781:             * <p>The location of this window is saved and the window can be restored to that location using the
0782:             * {@link #restore()} method.</p>
0783:             *
0784:             * @param direction the direction in which the window bar to be minimized to is located
0785:             */
0786:            public void minimize(Direction direction) {
0787:                doMinimize(direction);
0788:            }
0789:
0790:            /**
0791:             * Same as {@link #minimize()}, but the {@link DockingWindowListener#windowMinimizing(DockingWindow)} method of
0792:             * the window listeners will be called before minimizing the window, giving them the possibility to abort the minimize
0793:             * operation.
0794:             *
0795:             * @throws OperationAbortedException if the minimize operation was aborted by a window listener
0796:             * @see #minimize()
0797:             * @see DockingWindowListener#windowMinimizing(DockingWindow)
0798:             * @since IDW 1.4.0
0799:             */
0800:            public void minimizeWithAbort() throws OperationAbortedException {
0801:                if (!isMinimized()
0802:                        && getRootWindow().getClosestWindowBar(this ) != null) {
0803:                    fireWindowMinimizing(this );
0804:                    minimize();
0805:                }
0806:            }
0807:
0808:            /**
0809:             * Same as {@link #minimize(Direction)}, but the {@link DockingWindowListener#windowMinimizing(DockingWindow)} method of
0810:             * the window listeners will be called before minimizing the window, giving them the possibility to abort the minimize
0811:             * operation.
0812:             *
0813:             * @throws OperationAbortedException if the minimize operation was aborted by a window listener
0814:             * @see #minimize(Direction)
0815:             * @see DockingWindowListener#windowMinimizing(DockingWindow)
0816:             * @since IDW 1.4.0
0817:             */
0818:            public void minimizeWithAbort(Direction direction)
0819:                    throws OperationAbortedException {
0820:                if (!isMinimized()
0821:                        && getRootWindow().getWindowBar(direction) != null) {
0822:                    fireWindowMinimizing(this );
0823:                    minimize(direction);
0824:                }
0825:            }
0826:
0827:            private void doMinimize() {
0828:                doMinimize(windowItem.getLastMinimizedDirection() != null
0829:                        && getRootWindow().getWindowBar(
0830:                                windowItem.getLastMinimizedDirection())
0831:                                .isEnabled() ? windowItem
0832:                        .getLastMinimizedDirection() : getRootWindow()
0833:                        .getClosestWindowBar(this ));
0834:            }
0835:
0836:            private void doMinimize(Direction direction) {
0837:                DockingWindow w = getOptimizedWindow();
0838:
0839:                if (direction == null || w.isMinimized())
0840:                    return;
0841:
0842:                WindowBar bar = getRootWindow().getWindowBar(direction);
0843:
0844:                if (bar != null) {
0845:                    bar.addTab(w);
0846:                    updateButtonVisibility();
0847:                }
0848:            }
0849:
0850:            /**
0851:             * Returns true if this window can be minimized by the user.
0852:             *
0853:             * @return true if this window can be minimized
0854:             * @see #minimize()
0855:             */
0856:            public boolean isMinimizable() {
0857:                return getOptimizedWindow().getWindowProperties()
0858:                        .getMinimizeEnabled()
0859:                        && !isUndocked()
0860:                        && getRootWindow() != null
0861:                        && getRootWindow().windowBarEnabled();
0862:            }
0863:
0864:            /**
0865:             * Returns true if this window can be maximized by the user.
0866:             *
0867:             * @return true if this window can be maximized
0868:             * @see #maximize()
0869:             * @since IDW 1.2.0
0870:             */
0871:            public boolean isMaximizable() {
0872:                return !isMinimized()
0873:                        && /*!isUndocked() &&*/getOptimizedWindow()
0874:                                .getWindowProperties().getMaximizeEnabled();
0875:            }
0876:
0877:            /**
0878:             * Returns true if this window can be closed by the user.
0879:             *
0880:             * @return true if this window can be closed
0881:             * @see #close()
0882:             * @see #closeWithAbort()
0883:             * @since IDW 1.2.0
0884:             */
0885:            public boolean isClosable() {
0886:                return getOptimizedWindow().getWindowProperties()
0887:                        .getCloseEnabled();
0888:            }
0889:
0890:            /**
0891:             * Returns true if this window can be restored by the user.
0892:             *
0893:             * @return true if this window can be restored
0894:             * @see #restore()
0895:             * @since IDW 1.2.0
0896:             */
0897:            public boolean isRestorable() {
0898:                return getOptimizedWindow().getWindowProperties()
0899:                        .getRestoreEnabled();
0900:            }
0901:
0902:            /**
0903:             * Returns true if this window can be undocked to a floating window.
0904:             *
0905:             * @return true if this window can be undocked
0906:             * @see #undock(Point)
0907:             * @since IDW 1.4.0
0908:             */
0909:            public boolean isUndockable() {
0910:                return getOptimizedWindow().getWindowProperties()
0911:                        .getUndockEnabled();
0912:            }
0913:
0914:            /**
0915:             * Returns true if this window can be docked to the root window from a floating window.
0916:             *
0917:             * @return true if this window can be docked
0918:             * @see #dock()
0919:             * @since IDW 1.4.0
0920:             */
0921:            public boolean isDockable() {
0922:                return getOptimizedWindow().getWindowProperties()
0923:                        .getDockEnabled();
0924:            }
0925:
0926:            /**
0927:             * Replaces a child window with another window.
0928:             *
0929:             * @param oldWindow the child window to replaceChildWindow
0930:             * @param newWindow the window to replaceChildWindow it with
0931:             */
0932:            public void replaceChildWindow(DockingWindow oldWindow,
0933:                    DockingWindow newWindow) {
0934:                if (oldWindow == newWindow)
0935:                    return;
0936:
0937:                DockingWindow nw = internalReplaceChildWindow(oldWindow,
0938:                        newWindow);
0939:
0940:                if (getUpdateModel()) {
0941:                    boolean isRestore = nw.getWindowItem().isRestoreWindow();
0942:                    oldWindow.windowItem.replaceWith(nw.getWindowItem());
0943:
0944:                    if (!isRestore)
0945:                        nw.updateWindowItems();
0946:
0947:                    cleanUpModel();
0948:                }
0949:            }
0950:
0951:            protected DockingWindow internalReplaceChildWindow(
0952:                    final DockingWindow oldWindow, final DockingWindow newWindow) {
0953:                final WindowAncestors oldAncestors = newWindow.storeAncestors();
0954:                final DockingWindow nw = newWindow
0955:                        .getContentWindow(DockingWindow.this );
0956:
0957:                optimizeAfter(newWindow, new Runnable() {
0958:                    public void run() {
0959:                        if (nw == oldWindow)
0960:                            return;
0961:
0962:                        if (nw.getWindowParent() != null)
0963:                            nw.getWindowParent().removeChildWindow(nw);
0964:
0965:                        nw.setWindowParent(DockingWindow.this );
0966:
0967:                        if (oldWindow.isShowingInRootWindow())
0968:                            oldWindow.fireWindowHidden(oldWindow);
0969:
0970:                        oldWindow.setWindowParent(null);
0971:
0972:                        if (oldWindow == lastFocusedChildWindow)
0973:                            lastFocusedChildWindow = null;
0974:
0975:                        doReplace(oldWindow, nw);
0976:
0977:                        fireTitleChanged();
0978:
0979:                        oldWindow.fireWindowRemoved(DockingWindow.this ,
0980:                                oldWindow);
0981:                        fireWindowRemoved(DockingWindow.this , oldWindow);
0982:                        nw.fireWindowAdded(DockingWindow.this , nw);
0983:
0984:                        if (nw.isShowingInRootWindow())
0985:                            nw.fireWindowShown(nw);
0986:
0987:                        newWindow.notifyListeners(oldAncestors);
0988:                    }
0989:                });
0990:
0991:                return nw;
0992:            }
0993:
0994:            /**
0995:             * Returns the title of this window.
0996:             *
0997:             * @return the window title
0998:             */
0999:            public String getTitle() {
1000:                DockingWindowTitleProvider titleProvider = getWindowProperties()
1001:                        .getTitleProvider();
1002:                return (titleProvider == null ? SimpleDockingWindowTitleProvider.INSTANCE
1003:                        : titleProvider).getTitle(this );
1004:            }
1005:
1006:            public String toString() {
1007:                return getTitle();
1008:            }
1009:
1010:            protected WindowAncestors storeAncestors() {
1011:                return new WindowAncestors(getAncestors(), isMinimized(),
1012:                        isUndocked());
1013:            }
1014:
1015:            protected void notifyListeners(WindowAncestors ancestors) {
1016:                if (isMinimized() && !ancestors.isMinimized())
1017:                    fireWindowMinimized(this , ancestors.getAncestors());
1018:
1019:                if (isUndocked() && !ancestors.isUndocked())
1020:                    fireWindowUndocked(this , ancestors.getAncestors());
1021:
1022:                if (!isUndocked() && ancestors.isUndocked())
1023:                    fireWindowDocked(this , ancestors.getAncestors());
1024:            }
1025:
1026:            protected boolean isShowingInRootWindow() {
1027:                return windowParent != null
1028:                        && windowParent.isChildShowingInRootWindow(this );
1029:            }
1030:
1031:            protected boolean isChildShowingInRootWindow(DockingWindow child) {
1032:                return isShowingInRootWindow();
1033:            }
1034:
1035:            /**
1036:             * Makes this window visible. This causes the tabs of all {@link TabWindow} parents containing this
1037:             * window to be selected.
1038:             *
1039:             * @since IDW 1.1.0
1040:             */
1041:            public void makeVisible() {
1042:                showChildWindow(null);
1043:            }
1044:
1045:            /**
1046:             * Requests that the last focused child window becomes visible and that focus is restored to the last focused
1047:             * component in that window. If no child window has had focus or the child window has been removed from this window,
1048:             * focus is transferred to a child component of this window.
1049:             *
1050:             * @since IDW 1.1.0
1051:             */
1052:            public void restoreFocus() {
1053:                if (lastFocusedChildWindow != null)
1054:                    lastFocusedChildWindow.restoreFocus();
1055:                else {
1056:                    DockingWindow w = getPreferredFocusChild();
1057:
1058:                    if (w != null)
1059:                        w.restoreFocus();
1060:                    else
1061:                        ComponentUtil.smartRequestFocus(this );
1062:                }
1063:            }
1064:
1065:            protected DockingWindow getPreferredFocusChild() {
1066:                return getChildWindowCount() > 0 ? getChildWindow(0) : null;
1067:            }
1068:
1069:            /**
1070:             * Returns the result after removing unnecessary tab windows which contains only one tab.
1071:             *
1072:             * @return the result after removing unnecessary tab windows which contains only one tab
1073:             */
1074:            protected DockingWindow getOptimizedWindow() {
1075:                return this ;
1076:            }
1077:
1078:            protected DockingWindow getBestFittedWindow(
1079:                    DockingWindow parentWindow) {
1080:                return this ;
1081:            }
1082:
1083:            protected void internalClose() {
1084:                optimizeAfter(windowParent, new Runnable() {
1085:                    public void run() {
1086:                        windowParent.removeChildWindow(DockingWindow.this );
1087:                    }
1088:                });
1089:            }
1090:
1091:            protected void showChildWindow(DockingWindow window) {
1092:                if (windowParent != null && !isMaximized())
1093:                    windowParent.showChildWindow(this );
1094:            }
1095:
1096:            /**
1097:             * @return true if this window is inside a tab __exclude__
1098:             */
1099:            protected boolean insideTab() {
1100:                return windowParent == null ? false : windowParent
1101:                        .childInsideTab();
1102:            }
1103:
1104:            /**
1105:             * @return true if the child windows are inside tabs __exclude__
1106:             */
1107:            protected boolean childInsideTab() {
1108:                return windowParent == null ? false : windowParent
1109:                        .childInsideTab();
1110:            }
1111:
1112:            protected DockingWindow[] getAncestors() {
1113:                DockingWindow w = this ;
1114:                int count = 0;
1115:
1116:                while (w != null) {
1117:                    w = w.getWindowParent();
1118:                    count++;
1119:                }
1120:
1121:                DockingWindow[] windows = new DockingWindow[count];
1122:                w = this ;
1123:
1124:                while (w != null) {
1125:                    windows[--count] = w;
1126:                    w = w.getWindowParent();
1127:                }
1128:
1129:                return windows;
1130:            }
1131:
1132:            private void fireWindowRemoved(DockingWindow removedFromWindow,
1133:                    DockingWindow removedWindow) {
1134:                if (getListeners() != null) {
1135:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1136:                            .toArray(
1137:                                    new DockingWindowListener[getListeners()
1138:                                            .size()]);
1139:
1140:                    for (int i = 0; i < l.length; i++)
1141:                        l[i].windowRemoved(removedFromWindow, removedWindow);
1142:                }
1143:
1144:                if (windowParent != null)
1145:                    windowParent.fireWindowRemoved(removedFromWindow,
1146:                            removedWindow);
1147:            }
1148:
1149:            protected void fireWindowShown(DockingWindow window) {
1150:                if (getListeners() != null) {
1151:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1152:                            .toArray(
1153:                                    new DockingWindowListener[getListeners()
1154:                                            .size()]);
1155:
1156:                    for (int i = 0; i < l.length; i++)
1157:                        l[i].windowShown(window);
1158:                }
1159:
1160:                if (windowParent != null)
1161:                    windowParent.fireWindowShown(window);
1162:            }
1163:
1164:            protected void fireViewFocusChanged(View previouslyFocusedView,
1165:                    View focusedView) {
1166:                if (getListeners() != null) {
1167:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1168:                            .toArray(
1169:                                    new DockingWindowListener[getListeners()
1170:                                            .size()]);
1171:
1172:                    for (int i = 0; i < l.length; i++)
1173:                        l[i].viewFocusChanged(previouslyFocusedView,
1174:                                focusedView);
1175:                }
1176:            }
1177:
1178:            protected void fireWindowHidden(DockingWindow window) {
1179:                if (getListeners() != null) {
1180:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1181:                            .toArray(
1182:                                    new DockingWindowListener[getListeners()
1183:                                            .size()]);
1184:
1185:                    for (int i = 0; i < l.length; i++)
1186:                        l[i].windowHidden(window);
1187:                }
1188:
1189:                if (windowParent != null)
1190:                    windowParent.fireWindowHidden(window);
1191:            }
1192:
1193:            private void fireWindowAdded(DockingWindow addedToWindow,
1194:                    DockingWindow addedWindow) {
1195:                if (getListeners() != null) {
1196:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1197:                            .toArray(
1198:                                    new DockingWindowListener[getListeners()
1199:                                            .size()]);
1200:
1201:                    for (int i = 0; i < l.length; i++)
1202:                        l[i].windowAdded(addedToWindow, addedWindow);
1203:                }
1204:
1205:                if (windowParent != null)
1206:                    windowParent.fireWindowAdded(addedToWindow, addedWindow);
1207:            }
1208:
1209:            private void fireWindowClosing(DockingWindow window)
1210:                    throws OperationAbortedException {
1211:                if (getListeners() != null) {
1212:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1213:                            .toArray(
1214:                                    new DockingWindowListener[getListeners()
1215:                                            .size()]);
1216:
1217:                    for (int i = 0; i < l.length; i++)
1218:                        l[i].windowClosing(window);
1219:                }
1220:
1221:                if (windowParent != null)
1222:                    windowParent.fireWindowClosing(window);
1223:            }
1224:
1225:            private void fireWindowClosed(DockingWindow window) {
1226:                if (getListeners() != null) {
1227:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1228:                            .toArray(
1229:                                    new DockingWindowListener[getListeners()
1230:                                            .size()]);
1231:
1232:                    for (int i = 0; i < l.length; i++)
1233:                        l[i].windowClosed(window);
1234:                }
1235:            }
1236:
1237:            void fireWindowUndocking(DockingWindow window)
1238:                    throws OperationAbortedException {
1239:                if (getListeners() != null) {
1240:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1241:                            .toArray(
1242:                                    new DockingWindowListener[getListeners()
1243:                                            .size()]);
1244:
1245:                    for (int i = 0; i < l.length; i++)
1246:                        l[i].windowUndocking(window);
1247:                }
1248:
1249:                if (windowParent != null)
1250:                    windowParent.fireWindowUndocking(window);
1251:            }
1252:
1253:            void fireWindowUndocked(DockingWindow window,
1254:                    DockingWindow[] oldAncestors) {
1255:                doFireWindowUndocked(window);
1256:
1257:                for (int i = oldAncestors.length - 1; i >= 0; i--)
1258:                    oldAncestors[i].doFireWindowUndocked(this );
1259:            }
1260:
1261:            private void doFireWindowUndocked(DockingWindow window) {
1262:                if (getListeners() != null) {
1263:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1264:                            .toArray(
1265:                                    new DockingWindowListener[getListeners()
1266:                                            .size()]);
1267:
1268:                    for (int i = 0; i < l.length; i++)
1269:                        l[i].windowUndocked(window);
1270:                }
1271:            }
1272:
1273:            void fireWindowMinimizing(DockingWindow window)
1274:                    throws OperationAbortedException {
1275:                if (getListeners() != null) {
1276:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1277:                            .toArray(
1278:                                    new DockingWindowListener[getListeners()
1279:                                            .size()]);
1280:
1281:                    for (int i = 0; i < l.length; i++)
1282:                        l[i].windowMinimizing(window);
1283:                }
1284:
1285:                if (windowParent != null)
1286:                    windowParent.fireWindowMinimizing(window);
1287:            }
1288:
1289:            void fireWindowMaximizing(DockingWindow window)
1290:                    throws OperationAbortedException {
1291:                if (getListeners() != null) {
1292:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1293:                            .toArray(
1294:                                    new DockingWindowListener[getListeners()
1295:                                            .size()]);
1296:
1297:                    for (int i = 0; i < l.length; i++)
1298:                        l[i].windowMaximizing(window);
1299:                }
1300:
1301:                if (windowParent != null)
1302:                    windowParent.fireWindowMaximizing(window);
1303:            }
1304:
1305:            void fireWindowRestoring(DockingWindow window)
1306:                    throws OperationAbortedException {
1307:                if (getListeners() != null) {
1308:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1309:                            .toArray(
1310:                                    new DockingWindowListener[getListeners()
1311:                                            .size()]);
1312:
1313:                    for (int i = 0; i < l.length; i++)
1314:                        l[i].windowRestoring(window);
1315:                }
1316:
1317:                if (windowParent != null)
1318:                    windowParent.fireWindowRestoring(window);
1319:            }
1320:
1321:            void fireWindowDocking(DockingWindow window)
1322:                    throws OperationAbortedException {
1323:                if (getListeners() != null) {
1324:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1325:                            .toArray(
1326:                                    new DockingWindowListener[getListeners()
1327:                                            .size()]);
1328:
1329:                    for (int i = 0; i < l.length; i++)
1330:                        l[i].windowDocking(window);
1331:                }
1332:
1333:                if (windowParent != null)
1334:                    windowParent.fireWindowDocking(window);
1335:            }
1336:
1337:            void fireWindowDocked(DockingWindow window,
1338:                    DockingWindow[] oldAncestors) {
1339:                doFireWindowDocked(window);
1340:
1341:                for (int i = oldAncestors.length - 1; i >= 0; i--)
1342:                    oldAncestors[i].doFireWindowDocked(this );
1343:            }
1344:
1345:            void fireWindowDocked(ArrayList dockedViews) {
1346:                for (int i = 0; i < dockedViews.size(); i++) {
1347:                    DockingWindow window = (DockingWindow) dockedViews.get(i);
1348:                    window.doFireWindowDocked(window);
1349:
1350:                    DockingWindow[] ancestors = window.getAncestors();
1351:                    for (int k = 0; k < ancestors.length; k++)
1352:                        ancestors[k].doFireWindowDocked(window);
1353:                }
1354:            }
1355:
1356:            private void doFireWindowDocked(DockingWindow window) {
1357:                if (getListeners() != null) {
1358:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1359:                            .toArray(
1360:                                    new DockingWindowListener[getListeners()
1361:                                            .size()]);
1362:
1363:                    for (int i = 0; i < l.length; i++)
1364:                        l[i].windowDocked(window);
1365:                }
1366:            }
1367:
1368:            private void doFireWindowRestored(DockingWindow window) {
1369:                if (getListeners() != null) {
1370:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1371:                            .toArray(
1372:                                    new DockingWindowListener[getListeners()
1373:                                            .size()]);
1374:
1375:                    for (int i = 0; i < l.length; i++)
1376:                        l[i].windowRestored(window);
1377:                }
1378:            }
1379:
1380:            void fireWindowMaximized(DockingWindow window) {
1381:                if (getListeners() != null) {
1382:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1383:                            .toArray(
1384:                                    new DockingWindowListener[getListeners()
1385:                                            .size()]);
1386:
1387:                    for (int i = 0; i < l.length; i++)
1388:                        l[i].windowMaximized(window);
1389:                }
1390:
1391:                if (windowParent != null)
1392:                    windowParent.fireWindowMaximized(window);
1393:            }
1394:
1395:            void fireWindowMinimized(DockingWindow window,
1396:                    DockingWindow[] oldAncestors) {
1397:                doFireWindowMinimized(window);
1398:
1399:                for (int i = oldAncestors.length - 1; i >= 0; i--)
1400:                    oldAncestors[i].doFireWindowMinimized(window);
1401:            }
1402:
1403:            private void doFireWindowMinimized(DockingWindow window) {
1404:                if (getListeners() != null) {
1405:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1406:                            .toArray(
1407:                                    new DockingWindowListener[getListeners()
1408:                                            .size()]);
1409:
1410:                    for (int i = 0; i < l.length; i++)
1411:                        l[i].windowMinimized(window);
1412:                }
1413:            }
1414:
1415:            void fireWindowRestored(DockingWindow window) {
1416:                if (getListeners() != null) {
1417:                    DockingWindowListener[] l = (DockingWindowListener[]) getListeners()
1418:                            .toArray(
1419:                                    new DockingWindowListener[getListeners()
1420:                                            .size()]);
1421:
1422:                    for (int i = 0; i < l.length; i++)
1423:                        l[i].windowRestored(window);
1424:                }
1425:
1426:                if (windowParent != null)
1427:                    windowParent.fireWindowRestored(window);
1428:            }
1429:
1430:            protected void setLastMinimizedDirection(Direction direction) {
1431:                windowItem.setLastMinimizedDirection(direction);
1432:            }
1433:
1434:            /**
1435:             *
1436:             */
1437:            protected void clearChildrenFocus(DockingWindow child, View view) {
1438:                for (int i = 0; i < getChildWindowCount(); i++)
1439:                    if (child != getChildWindow(i))
1440:                        getChildWindow(i).clearFocus(view);
1441:            }
1442:
1443:            void childGainedFocus(DockingWindow child, View view) {
1444:                if (child != null)
1445:                    lastFocusedChildWindow = child;
1446:
1447:                clearChildrenFocus(child, view);
1448:
1449:                if (windowParent != null)
1450:                    windowParent.childGainedFocus(this , view);
1451:            }
1452:
1453:            WindowTab getTab() {
1454:                if (tab == null) {
1455:                    tab = new WindowTab(this , false);
1456:                }
1457:
1458:                return tab;
1459:            }
1460:
1461:            /**
1462:             *
1463:             */
1464:            protected void childRemoved(DockingWindow child) {
1465:                if (lastFocusedChildWindow == child)
1466:                    lastFocusedChildWindow = null;
1467:            }
1468:
1469:            /**
1470:             *
1471:             */
1472:            protected void updateButtonVisibility() {
1473:                if (tab != null)
1474:                    tab.updateTabButtons(null);
1475:
1476:                for (int i = 0; i < getChildWindowCount(); i++)
1477:                    getChildWindow(i).updateButtonVisibility();
1478:            }
1479:
1480:            /**
1481:             *
1482:             */
1483:            protected final void readLocations(ObjectInputStream in,
1484:                    RootWindow rootWindow, int version) throws IOException {
1485:                if (version < 3)
1486:                    LocationDecoder.decode(in, rootWindow); // Just skip location
1487:
1488:                if (version > 1) {
1489:                    int index = in.readInt();
1490:                    lastFocusedChildWindow = index == -1 ? null
1491:                            : getChildWindow(index);
1492:                }
1493:
1494:                for (int i = 0; i < getChildWindowCount(); i++)
1495:                    getChildWindow(i).readLocations(in, rootWindow, version);
1496:            }
1497:
1498:            /**
1499:             *
1500:             */
1501:            protected void writeLocations(ObjectOutputStream out)
1502:                    throws IOException {
1503:                out.writeInt(lastFocusedChildWindow == null ? -1
1504:                        : getChildWindowIndex(lastFocusedChildWindow));
1505:
1506:                for (int i = 0; i < getChildWindowCount(); i++)
1507:                    getChildWindow(i).writeLocations(out);
1508:            }
1509:
1510:            /**
1511:             *
1512:             */
1513:            protected static void beginOptimize(DockingWindow window) {
1514:                optimizeDepth++;
1515:
1516:                if (window != null)
1517:                    optimizeWindows.add(window);
1518:
1519:                PropertyMapManager.getInstance().beginBatch();
1520:            }
1521:
1522:            /**
1523:             *
1524:             */
1525:            protected static void endOptimize() {
1526:                PropertyMapManager.getInstance().endBatch();
1527:
1528:                if (--optimizeDepth == 0) {
1529:                    while (optimizeWindows.size() > 0) {
1530:                        HashSet s = optimizeWindows;
1531:                        optimizeWindows = new HashSet();
1532:
1533:                        for (Iterator it = s.iterator(); it.hasNext();) {
1534:                            DockingWindow window = (DockingWindow) it.next();
1535:                            window.optimizeWindowLayout();
1536:                        }
1537:                    }
1538:                }
1539:            }
1540:
1541:            /**
1542:             *
1543:             */
1544:            protected static void optimizeAfter(final DockingWindow window,
1545:                    final Runnable runnable) {
1546:                FocusManager.getInstance().pinFocus(new Runnable() {
1547:                    public void run() {
1548:                        beginOptimize(window);
1549:
1550:                        try {
1551:                            runnable.run();
1552:                        } finally {
1553:                            endOptimize();
1554:                        }
1555:                    }
1556:                });
1557:            }
1558:
1559:            /**
1560:             *
1561:             */
1562:            protected boolean needsTitleWindow() {
1563:                return false;
1564:            }
1565:
1566:            /**
1567:             *
1568:             */
1569:            protected boolean showsWindowTitle() {
1570:                return false;
1571:            }
1572:
1573:            /**
1574:             *
1575:             */
1576:            protected void optimizeWindowLayout() {
1577:            }
1578:
1579:            /**
1580:             *
1581:             */
1582:            protected DockingWindow getLocationWindow() {
1583:                return this ;
1584:            }
1585:
1586:            /**
1587:             *
1588:             */
1589:            protected void fireTitleChanged() {
1590:                if (tab != null)
1591:                    tab.windowTitleChanged();
1592:
1593:                if (windowParent != null)
1594:                    windowParent.fireTitleChanged();
1595:            }
1596:
1597:            protected DockingWindow getContentWindow(DockingWindow parent) {
1598:                return needsTitleWindow() && !parent.showsWindowTitle() ? new TabWindow(
1599:                        this )
1600:                        : this ;
1601:            }
1602:
1603:            protected final void removeChildWindow(final DockingWindow window) {
1604:                optimizeAfter(window.getWindowParent(), new Runnable() {
1605:                    public void run() {
1606:                        if (window.isShowingInRootWindow())
1607:                            window.fireWindowHidden(window);
1608:
1609:                        window.setWindowParent(null);
1610:
1611:                        if (lastFocusedChildWindow == window)
1612:                            lastFocusedChildWindow = null;
1613:
1614:                        doRemoveWindow(window);
1615:                        fireTitleChanged();
1616:                        window.fireWindowRemoved(DockingWindow.this , window);
1617:                        fireWindowRemoved(DockingWindow.this , window);
1618:                        afterWindowRemoved(window);
1619:                    }
1620:                });
1621:            }
1622:
1623:            final protected void removeWindow(DockingWindow window) {
1624:                window.setWindowParent(null);
1625:
1626:                if (getUpdateModel()) {
1627:                    windowItem.removeWindow(windowItem
1628:                            .getChildWindowContaining(window.getWindowItem()));
1629:                    cleanUpModel();
1630:                }
1631:            }
1632:
1633:            final protected void detach() {
1634:                DockingWindow oldParent = getWindowParent();
1635:
1636:                if (oldParent != null)
1637:                    oldParent.removeChildWindow(this );
1638:            }
1639:
1640:            final protected DockingWindow addWindow(DockingWindow window) {
1641:                if (window == null)
1642:                    return null;
1643:
1644:                DockingWindow w = window.getContentWindow(this );
1645:                w.detach();
1646:                w.setWindowParent(this );
1647:                fireTitleChanged();
1648:                w.fireWindowAdded(this , w);
1649:
1650:                if (w.isShowingInRootWindow())
1651:                    fireWindowShown(w);
1652:
1653:                return w;
1654:            }
1655:
1656:            /**
1657:             *
1658:             */
1659:            protected void rootChanged(RootWindow oldRoot, RootWindow newRoot) {
1660:                if (newRoot != null)
1661:                    lastRootWindow = new WeakReference(newRoot);
1662:
1663:                for (int i = 0; i < getChildWindowCount(); i++)
1664:                    if (getChildWindow(i) != null)
1665:                        getChildWindow(i).rootChanged(oldRoot, newRoot);
1666:
1667:                updateWindowItem(newRoot);
1668:            }
1669:
1670:            /**
1671:             *
1672:             */
1673:            protected void clearFocus(View view) {
1674:                for (int i = 0; i < getChildWindowCount(); i++)
1675:                    getChildWindow(i).clearFocus(view);
1676:            }
1677:
1678:            private void setWindowParent(DockingWindow window) {
1679:                if (window == windowParent)
1680:                    return;
1681:
1682:                final RootWindow oldRoot = getRootWindow();
1683:
1684:                if (windowParent != null) {
1685:                    if (isMaximized()) {
1686:                        if (isUndocked())
1687:                            DockingUtil.getFloatingWindowFor(this )
1688:                                    .setMaximizedWindow(null);
1689:                        else
1690:                            getRootWindow().setMaximizedWindow(null);
1691:                    }
1692:
1693:                    windowParent.childRemoved(this );
1694:                    clearFocus(null);
1695:
1696:                    if (tab != null)
1697:                        tab.setContentComponent(this );
1698:                }
1699:
1700:                windowParent = window;
1701:                final RootWindow newRoot = getRootWindow();
1702:
1703:                if (oldRoot != newRoot) {
1704:                    rootChanged(oldRoot, newRoot);
1705:                }
1706:            }
1707:
1708:            private Direction getSplitDirection(Point p) {
1709:                double[] relativeDist = { p.getX() / getWidth(),
1710:                        (getWidth() - p.getX()) / getWidth(),
1711:                        p.getY() / getHeight(),
1712:                        (getHeight() - p.getY()) / getHeight() };
1713:                int index = ArrayUtil.findSmallest(relativeDist);
1714:                return index == 0 ? Direction.LEFT
1715:                        : index == 1 ? Direction.RIGHT
1716:                                : index == 2 ? Direction.UP : Direction.DOWN;
1717:            }
1718:
1719:            private int getEdgeDistance(Point p, Direction dir) {
1720:                return dir == Direction.RIGHT ? getWidth() - p.x
1721:                        : dir == Direction.DOWN ? getHeight() - p.y
1722:                                : dir == Direction.LEFT ? p.x : p.y;
1723:            }
1724:
1725:            DropAction acceptDrop(Point p, DockingWindow window) {
1726:                DropAction da = null;
1727:                DockingWindow fw = DockingUtil.getFloatingWindowFor(window);
1728:                DockingWindow fw2 = DockingUtil.getFloatingWindowFor(this );
1729:
1730:                // Check getRootWindow() != window.getRootWindow() so that a view not insidedrop window's root window can be dragged to a floating window
1731:                if (getRootWindow() != window.getRootWindow()
1732:                        || ((window.getWindowProperties().getDockEnabled()
1733:                                || fw == null || fw2 != null) && (window
1734:                                .getWindowProperties().getUndockEnabled() || (fw == fw2)))) {
1735:                    da = !isShowing()
1736:                            || !contains(p)
1737:                            || hasParent(window)
1738:                            || (!getRootWindow().getRootWindowProperties()
1739:                                    .getRecursiveTabsEnabled() && insideTab()) ? null
1740:                            : doAcceptDrop(p, window);
1741:                }
1742:                //System.out.println(!isShowing() + "  " + !contains(p) + "  " + hasParent(window) + "  " + (!getRootWindow().getRootWindowProperties().getRecursiveTabsEnabled() && insideTab()));
1743:                //System.out.println(" \n ----- Accept drop: " + (this instanceof
1744:                // SplitWindow));
1745:                //System.out.println("isSho " + !isShowing() + " contan " +
1746:                // !contains(p) + " parent " + hasParent(window) + " bla " +
1747:                // (!getRootWindow().getRootWindowProperties().getRecursiveTabsEnabled()
1748:                // && insideTab()));
1749:                //}
1750:
1751:                return da;
1752:            }
1753:
1754:            DropAction getDefaultDropAction() {
1755:                return new DropAction() {
1756:                    public void execute(DockingWindow window,
1757:                            MouseEvent mouseEvent) {
1758:                        if (getWindowProperties().getUndockEnabled()
1759:                                && getWindowProperties()
1760:                                        .getUndockOnDropEnabled()) {
1761:                            Point p = mouseEvent.getPoint();
1762:                            Point p2 = SwingUtilities.convertPoint(
1763:                                    (Component) mouseEvent.getSource(), p,
1764:                                    getRootWindow());
1765:                            Point p3 = SwingUtilities.convertPoint(
1766:                                    (Component) mouseEvent.getSource(), p,
1767:                                    getRootWindow().getRootPane());
1768:                            if (!getRootWindow().contains(p2)
1769:                                    && !getRootWindow()
1770:                                            .floatingWindowsContainPoint(p3)) {
1771:                                FloatingWindow fw = DockingUtil
1772:                                        .getFloatingWindowFor(window);
1773:
1774:                                if (fw == null
1775:                                        || (fw.getChildWindowCount() > 0 && fw
1776:                                                .getChildWindow(0)
1777:                                                .getChildWindowCount() > 1)) {
1778:                                    SwingUtilities.convertPointToScreen(p,
1779:                                            (Component) mouseEvent.getSource());
1780:                                    p.x = p.x - window.getWidth() / 2;
1781:                                    p.y = p.y
1782:                                            - Math.min(DROP_FLOATING_YOFFSET,
1783:                                                    window.getHeight() / 2);
1784:                                    try {
1785:                                        window.undockWithAbort(p);
1786:                                    } catch (OperationAbortedException e) {
1787:                                        // Ignore
1788:                                    }
1789:                                }
1790:                            }
1791:                        }
1792:                    }
1793:                };
1794:            }
1795:
1796:            protected boolean acceptsSplitWith(DockingWindow window) {
1797:                return window != this ;
1798:            }
1799:
1800:            protected DropAction doAcceptDrop(Point p, DockingWindow window) {
1801:                DropAction da = acceptSplitDrop(p, window, getRootWindow()
1802:                        .getRootWindowProperties().getEdgeSplitDistance());
1803:
1804:                if (da != null)
1805:                    return da;
1806:
1807:                da = acceptChildDrop(p, window);
1808:
1809:                if (da != null)
1810:                    return da;
1811:
1812:                da = acceptInteriorDrop(p, window);
1813:
1814:                if (da != null)
1815:                    return da;
1816:
1817:                return acceptSplitDrop(p, window, -1);
1818:            }
1819:
1820:            protected DropAction acceptSplitDrop(Point p, DockingWindow window,
1821:                    int splitDistance) {
1822:                if (!acceptsSplitWith(window))
1823:                    return null;
1824:
1825:                Direction splitDir = getSplitDirection(p);
1826:                int dist = getEdgeDistance(p, splitDir);
1827:
1828:                if (splitDistance != -1
1829:                        && dist > splitDistance * getEdgeDepth(splitDir))
1830:                    return null;
1831:
1832:                if (getSplitDropFilter().acceptDrop(
1833:                        new SplitDropInfo(window, this , p, splitDir)))
1834:                    return split(window, splitDir);
1835:
1836:                return null;
1837:            }
1838:
1839:            protected DropAction split(DockingWindow window,
1840:                    final Direction splitDir) {
1841:                int width = splitDir == Direction.LEFT
1842:                        || splitDir == Direction.RIGHT ? getWidth() / 3
1843:                        : getWidth();
1844:                int height = splitDir == Direction.DOWN
1845:                        || splitDir == Direction.UP ? getHeight() / 3
1846:                        : getHeight();
1847:                int x = splitDir == Direction.RIGHT ? getWidth() - width : 0;
1848:                int y = splitDir == Direction.DOWN ? getHeight() - height : 0;
1849:
1850:                Rectangle rect = new Rectangle(x, y, width, height);
1851:                getRootWindow().setDragRectangle(
1852:                        SwingUtilities.convertRectangle(this , rect,
1853:                                getRootWindow()));
1854:
1855:                return new DropAction() {
1856:                    public void execute(DockingWindow window,
1857:                            MouseEvent mouseEvent) {
1858:                        try {
1859:                            window.beforeDrop(DockingWindow.this );
1860:                            split(window, splitDir, splitDir == Direction.UP
1861:                                    || splitDir == Direction.LEFT ? 0.33f
1862:                                    : 0.66f);
1863:                            window.restoreFocus();
1864:                        } catch (OperationAbortedException e) {
1865:                            // Ignore
1866:                        }
1867:                    }
1868:                };
1869:            }
1870:
1871:            protected void beforeDrop(DockingWindow target)
1872:                    throws OperationAbortedException {
1873:                if (!isMinimized() && target.isMinimized())
1874:                    fireWindowMinimizing(this );
1875:
1876:                if (!isUndocked() && target.isUndocked())
1877:                    fireWindowUndocking(this );
1878:            }
1879:
1880:            protected DropAction createTabWindow(DockingWindow window) {
1881:                getRootWindow().setDragRectangle(
1882:                        SwingUtilities.convertRectangle(getParent(),
1883:                                getBounds(), getRootWindow()));
1884:
1885:                return new DropAction() {
1886:                    public void execute(final DockingWindow window,
1887:                            MouseEvent mouseEvent) {
1888:                        optimizeAfter(window.getWindowParent(), new Runnable() {
1889:                            public void run() {
1890:                                try {
1891:                                    window.beforeDrop(DockingWindow.this );
1892:                                    TabWindow tabWindow = new TabWindow();
1893:                                    windowParent.replaceChildWindow(
1894:                                            DockingWindow.this , tabWindow);
1895:                                    tabWindow.addTab(DockingWindow.this );
1896:                                    tabWindow.addTab(window);
1897:                                } catch (OperationAbortedException e) {
1898:                                    // Ignore
1899:                                }
1900:                            }
1901:                        });
1902:                    }
1903:                };
1904:            }
1905:
1906:            protected DropAction acceptInteriorDrop(Point p,
1907:                    DockingWindow window) {
1908:                return null;
1909:            }
1910:
1911:            /**
1912:             *
1913:             */
1914:            protected boolean hasParent(DockingWindow w) {
1915:                return w == this 
1916:                        || (getWindowParent() != null && getWindowParent()
1917:                                .hasParent(w));
1918:            }
1919:
1920:            /**
1921:             *
1922:             */
1923:            protected DockingWindow oldRead(ObjectInputStream in,
1924:                    ReadContext context) throws IOException {
1925:                windowItem.readSettings(in, context);
1926:                return this ;
1927:            }
1928:
1929:            /**
1930:             *
1931:             */
1932:            abstract protected PropertyMap getPropertyObject();
1933:
1934:            /**
1935:             *
1936:             */
1937:            abstract protected PropertyMap createPropertyObject();
1938:
1939:            void showPopupMenu(MouseEvent event) {
1940:                if (event.isConsumed())
1941:                    return;
1942:
1943:                DockingWindow w = this ;
1944:
1945:                while (w.getPopupMenuFactory() == null) {
1946:                    w = w.getWindowParent();
1947:
1948:                    if (w == null)
1949:                        return;
1950:                }
1951:
1952:                JPopupMenu popupMenu = w.getPopupMenuFactory().createPopupMenu(
1953:                        this );
1954:
1955:                if (popupMenu != null && popupMenu.getComponentCount() > 0)
1956:                    popupMenu.show(event.getComponent(), event.getX(), event
1957:                            .getY());
1958:            }
1959:
1960:            protected void setFocused(boolean focused) {
1961:                if (tab != null)
1962:                    tab.setFocused(focused);
1963:            }
1964:
1965:            protected int getEdgeDepth(Direction dir) {
1966:                return 1 + (windowParent == null ? 0 : windowParent
1967:                        .getChildEdgeDepth(this , dir));
1968:            }
1969:
1970:            protected int getChildEdgeDepth(DockingWindow window, Direction dir) {
1971:                return windowParent == null ? 0 : windowParent
1972:                        .getChildEdgeDepth(this , dir);
1973:            }
1974:
1975:            protected DropAction acceptChildDrop(Point p, DockingWindow window) {
1976:                for (int i = 0; i < getChildWindowCount(); i++) {
1977:                    DockingWindow childWindow = getChildWindow(i);
1978:                    Point p2 = SwingUtilities
1979:                            .convertPoint(this , p, childWindow);
1980:
1981:                    if (getChildDropFilter().acceptDrop(
1982:                            new ChildDropInfo(window, this , p, childWindow))) {
1983:                        DropAction da = childWindow.acceptDrop(p2, window);
1984:
1985:                        if (da != null)
1986:                            return da;
1987:                    }
1988:                }
1989:
1990:                return null;
1991:            }
1992:
1993:            protected WindowItem getWindowItem() {
1994:                return windowItem;
1995:            }
1996:
1997:            protected boolean getUpdateModel() {
1998:                return updateModelDepth == 0 && windowItem.isRestoreWindow();
1999:            }
2000:
2001:            private void findViews(ArrayList views) {
2002:                if (this  instanceof  View)
2003:                    views.add(this );
2004:
2005:                for (int i = 0; i < getChildWindowCount(); i++)
2006:                    getChildWindow(i).findViews(views);
2007:            }
2008:
2009:            private void restoreViews(ArrayList views) {
2010:                for (int i = 0; i < views.size(); i++)
2011:                    ((DockingWindow) views.get(i)).restoreItem();
2012:            }
2013:
2014:            protected static void beginUpdateModel() {
2015:                updateModelDepth++;
2016:            }
2017:
2018:            protected static void endUpdateModel() {
2019:                updateModelDepth--;
2020:            }
2021:
2022:            private void restoreItem() {
2023:                beginUpdateModel();
2024:
2025:                try {
2026:                    if (windowItem != null) {
2027:                        WindowItem item = windowItem;
2028:
2029:                        while (item.getParent() != null) {
2030:                            DockingWindow parentWindow = item.getParent()
2031:                                    .getConnectedWindow();
2032:
2033:                            if (parentWindow != null
2034:                                    && parentWindow.getRootWindow() != null
2035:                                    && !parentWindow.isMinimized()
2036:                                    && !parentWindow.isUndocked()) {
2037:                                if (parentWindow instanceof  TabWindow)
2038:                                    insertTab((TabWindow) parentWindow, this );
2039:                                else if (parentWindow instanceof  RootWindow) {
2040:                                    DockingWindow w = getContainer(item
2041:                                            .getParent(), windowItem);
2042:                                    ((RootWindow) parentWindow).setWindow(w);
2043:                                }
2044:
2045:                                return;
2046:                            } else {
2047:                                DockingWindow w = null;
2048:
2049:                                for (int i = 0; i < item.getParent()
2050:                                        .getWindowCount(); i++) {
2051:                                    WindowItem child = item.getParent()
2052:                                            .getWindow(i);
2053:
2054:                                    if (child != item) {
2055:                                        w = child.getVisibleDockingWindow();
2056:
2057:                                        if (w != null)
2058:                                            break;
2059:                                    }
2060:                                }
2061:
2062:                                if (w != null) {
2063:                                    final DockingWindow w1 = w;
2064:                                    final WindowItem fitem = item;
2065:
2066:                                    optimizeAfter(w.getWindowParent(),
2067:                                            new Runnable() {
2068:                                                public void run() {
2069:                                                    if (fitem.getParent() instanceof  SplitWindowItem) {
2070:                                                        SplitWindowItem splitWindowItem = (SplitWindowItem) fitem
2071:                                                                .getParent();
2072:                                                        boolean isLeft = splitWindowItem
2073:                                                                .getWindow(0) == fitem;
2074:                                                        SplitWindow newWindow = new SplitWindow(
2075:                                                                splitWindowItem
2076:                                                                        .isHorizontal(),
2077:                                                                splitWindowItem
2078:                                                                        .getDividerLocation(),
2079:                                                                null, null,
2080:                                                                splitWindowItem);
2081:                                                        w1
2082:                                                                .getWindowParent()
2083:                                                                .internalReplaceChildWindow(
2084:                                                                        w1,
2085:                                                                        newWindow);
2086:                                                        DockingWindow w = getContainer(
2087:                                                                splitWindowItem,
2088:                                                                windowItem);
2089:                                                        DockingWindow w2 = w1
2090:                                                                .getContainer(
2091:                                                                        splitWindowItem,
2092:                                                                        w1.windowItem);
2093:                                                        newWindow
2094:                                                                .setWindows(
2095:                                                                        isLeft ? w
2096:                                                                                : w2,
2097:                                                                        isLeft ? w2
2098:                                                                                : w);
2099:                                                    } else if (fitem
2100:                                                            .getParent() instanceof  TabWindowItem) {
2101:                                                        TabWindowItem tabWindowItem = (TabWindowItem) fitem
2102:                                                                .getParent();
2103:                                                        TabWindow newWindow = new TabWindow(
2104:                                                                null,
2105:                                                                tabWindowItem);
2106:                                                        w1
2107:                                                                .getWindowParent()
2108:                                                                .internalReplaceChildWindow(
2109:                                                                        w1,
2110:                                                                        newWindow);
2111:                                                        insertTab(
2112:                                                                newWindow,
2113:                                                                DockingWindow.this );
2114:                                                        insertTab(
2115:                                                                newWindow,
2116:                                                                w1
2117:                                                                        .getOptimizedWindow());
2118:                                                    }
2119:                                                }
2120:                                            });
2121:
2122:                                    return;
2123:                                }
2124:                            }
2125:
2126:                            item = item.getParent();
2127:                        }
2128:                    }
2129:
2130:                    final RootWindow rootWindow = (RootWindow) lastRootWindow
2131:                            .get();
2132:
2133:                    if (rootWindow != null) {
2134:                        final WindowItem topItem = getWindowItem().getTopItem();
2135:
2136:                        optimizeAfter(null, new Runnable() {
2137:                            public void run() {
2138:                                DockingWindow w = rootWindow.getWindow();
2139:
2140:                                if (w == null) {
2141:                                    WindowItem wi = rootWindow.getWindowItem();
2142:
2143:                                    if (wi.getWindowCount() == 0)
2144:                                        wi.addWindow(topItem);
2145:                                    else {
2146:                                        SplitWindowItem splitWindowItem = new SplitWindowItem();
2147:                                        splitWindowItem.addWindow(wi
2148:                                                .getWindow(0));
2149:                                        splitWindowItem.addWindow(topItem);
2150:                                        wi.addWindow(splitWindowItem);
2151:                                    }
2152:
2153:                                    rootWindow.setWindow(getContainer(topItem,
2154:                                            getWindowItem()));
2155:                                } else {
2156:                                    SplitWindow newWindow = new SplitWindow(
2157:                                            true);
2158:                                    newWindow.getWindowItem().addWindow(
2159:                                            rootWindow.getWindowItem()
2160:                                                    .getWindow(0));
2161:                                    newWindow.getWindowItem()
2162:                                            .addWindow(topItem);
2163:                                    rootWindow.setWindow(newWindow);
2164:                                    newWindow.setWindows(w, getContainer(
2165:                                            topItem, getWindowItem()));
2166:                                    rootWindow.getWindowItem().addWindow(
2167:                                            newWindow.getWindowItem());
2168:                                }
2169:                            }
2170:                        });
2171:                    }
2172:                } finally {
2173:                    endUpdateModel();
2174:                }
2175:            }
2176:
2177:            private static void insertTab(TabWindow tabWindow,
2178:                    DockingWindow window) {
2179:                int index = 0;
2180:                WindowItem item = tabWindow.getWindowItem();
2181:                WindowItem childItem = item.getChildWindowContaining(window
2182:                        .getWindowItem());
2183:
2184:                for (int i = 0; i < item.getWindowCount(); i++) {
2185:                    WindowItem wi = item.getWindow(i);
2186:
2187:                    if (wi == childItem)
2188:                        break;
2189:
2190:                    DockingWindow w = wi.getVisibleDockingWindow();
2191:
2192:                    if (w != null)
2193:                        index++;
2194:                }
2195:
2196:                tabWindow.addTabNoSelect(window, index);
2197:                tabWindow.updateSelectedTab();
2198:            }
2199:
2200:            private DockingWindow getContainer(WindowItem topItem,
2201:                    WindowItem item) {
2202:                if (!needsTitleWindow())
2203:                    return this ;
2204:
2205:                while (item != topItem) {
2206:                    if (item instanceof  TabWindowItem) {
2207:                        TabWindow w = new TabWindow(null, (TabWindowItem) item);
2208:                        w.addTabNoSelect(this , 0);
2209:                        return w;
2210:                    }
2211:
2212:                    item = item.getParent();
2213:                }
2214:
2215:                TabWindow w = new TabWindow();
2216:                w.addTabNoSelect(this , 0);
2217:                item.replaceWith(w.getWindowItem());
2218:                w.getWindowItem().addWindow(item);
2219:                return w;
2220:            }
2221:
2222:            private void setWindowItem(WindowItem windowItem) {
2223:                this .windowItem = windowItem;
2224:                windowItem.setConnectedWindow(this );
2225:                updateWindowItem(getRootWindow());
2226:            }
2227:
2228:            protected void updateWindowItem(RootWindow rootWindow) {
2229:                windowItem
2230:                        .setParentDockingWindowProperties(rootWindow == null ? WindowItem.emptyProperties
2231:                                : rootWindow.getRootWindowProperties()
2232:                                        .getDockingWindowProperties());
2233:            }
2234:
2235:            protected void afterWindowRemoved(DockingWindow window) {
2236:            }
2237:
2238:            protected void write(ObjectOutputStream out, WriteContext context,
2239:                    ViewWriter viewWriter) throws IOException {
2240:            }
2241:
2242:            protected void cleanUpModel() {
2243:                if (windowParent != null)
2244:                    windowParent.cleanUpModel();
2245:            }
2246:
2247:            /*  static int cc = 0;
2248:             protected void finalize() {
2249:             try {
2250:             System.out.println("\n\ndocking window finalized " + cc++ + "  " + hashCode() + "\n");
2251:             super.finalize();
2252:             } catch (Throwable e) {
2253:             throw new RuntimeException(e);
2254:             }
2255:             }*/
2256:
2257:            DropFilter getSplitDropFilter() {
2258:                return getWindowProperties().getDropFilterProperties()
2259:                        .getSplitDropFilter();
2260:            }
2261:
2262:            DropFilter getChildDropFilter() {
2263:                return getWindowProperties().getDropFilterProperties()
2264:                        .getChildDropFilter();
2265:            }
2266:
2267:            DropFilter getInteriorDropFilter() {
2268:                return getWindowProperties().getDropFilterProperties()
2269:                        .getInteriorDropFilter();
2270:            }
2271:
2272:            DropFilter getInsertTabDropFilter() {
2273:                return getWindowProperties().getDropFilterProperties()
2274:                        .getInsertTabDropFilter();
2275:            }
2276:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.