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: }
|