home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / IFC_112 / netscape / application / InternalWindow.java < prev    next >
Encoding:
Text File  |  1999-05-28  |  66.3 KB  |  1,967 lines  |  [TEXT/CWIE]

  1. // InternalWindow.java
  2. // By Ned Etcode
  3. // Copyright 1995, 1996, 1997 Netscape Communications Corp.  All rights reserved.
  4.  
  5. package netscape.application;
  6.  
  7. import netscape.util.*;
  8.  
  9. /** View subclass implementing "window-like" behavior
  10.   * found in traditional windowing systems.  An InternalWindow can have a
  11.   * title bar (displaying a text string) by which a user can drag the
  12.   * InternalWindow around the screen; a close button that the user can click
  13.   * to make a InternalWindow invisible (remove it from the View hierarchy); and
  14.   * a resize bar, allowing a user to resize the InternalWindow and its
  15.   * contents.<p>
  16.   * An InternalWindow has a "contentView," which is the ancestor of all
  17.   * Views added to InternalWindow programmatically.  Calling InternalWindow's
  18.   * <B>addSubvew()</B> adds the View to the InternalWindow's contentView
  19.   * rather than directly to the InternalWindow.<p>
  20.   * You make an InternalWindow visible (add it to the View hierarchy) by
  21.   * calling the <B>show()</B> method, and remove it by calling
  22.   * <B>hide()</B>.  Each RootView can contain zero or more
  23.   * InternalWindows, but only one visible InternalWindow can be the
  24.   * Application's "main InternalWindow."  The main InternalWindow displays its
  25.   * title bar differently than all other InternalWindows, and represents the
  26.   * InternalWindow in which the user is currently working.  The IFC passes
  27.   * key events to the focused View in the current main InternalWindow.
  28.   * InternalWindows containing tool palettes or other sets
  29.   * of controls might never become the main Window because they
  30.   * do not need to receive key events.  Sending the message
  31.   * <B>setCanBecomeMain(false)</B> will prevent this. <p>
  32.   * In general, InternalWindows overlap each other.  To ensure that certain
  33.   * InternalWindows never obscure certain others, you can assign
  34.   * InternalWindows to "layers."  For example, if you want a tool palette to
  35.   * never be obscured by a document InternalWindow, you can set the tool
  36.   * palette InternalWindow's layer to <B>PALETTE_LAYER</B>, a layer higher than
  37.   * the default InternalWindow layer. Other InternalWindows in the tool
  38.   * palette's layer can obscure each other, but they can never be obscured by
  39.   * InternalWindows in lower layers.  The InternalWindow class defines
  40.   * several layers; if needed, you can define your own, but the
  41.   * predefined layers should be enough.<p>
  42.   * InternalWindow are rectangular regions.  If you need to use a View with
  43.   * InternalWindow-like properties (clipping, primarily) but also have it
  44.   * appear non-rectangular, you can make the InternalWindow transparent.  A
  45.   * transparent InternalWindow allocates an offscreen buffer to perform its
  46.   * drawing.  Unless
  47.   * the InternalWindow's contentView contains Views that draw, the
  48.   * InternalWindow remains completely transparent or invisible (except for the
  49.   * InternalWindow's Border, if set).  Clicking and
  50.   * dragging anywhere within the InternalWindow's bounds
  51.   * moves the InternalWindow. You can regulate this movement by overriding the
  52.   * InternalWindow's <b>isPointInBorder()</b> method.<p>
  53.   * Objects interested in events such as the InternalWindow closing,
  54.   * resizing, and so on, can implement the WindowOwner
  55.   * interfaces and set themselves as an InternalWindow's owner.<p>
  56.   * @note 1.0 internal window document removed
  57.   * @note 1.0 application wide document window support added.
  58.   * @note 1.0 removed InternalWindowOwner
  59.   * @note 1.0 focusing a view inside the window now makes the internal
  60.   *           window the main window
  61.   * @note 1.0 focusing a view in a window that cannot become main does
  62.   *           not change the focused view in the rootview anymore
  63.   * @note 1.0 remove Component support
  64.   * @note 1.0 added support for Menus
  65.   * @note 1.0 added ignoreWindowClipView layer
  66.   * @note 1.0 rewrote drawing of Windows with layers and transparency
  67.   * @note 1.0 fixed bug with resize windows on incorrect rootView
  68.   * @note 1.0 fixes for coordinate view transforms
  69.   * @note 1.0 archiving changes for focus model and menu
  70.   * @note 1.0 added protected method willMoveTo() to intercept movements
  71.   * @note 1.1 fixed bug in dragging code
  72.   */
  73.  
  74.  
  75. public class InternalWindow extends View implements Window {
  76.     // Even though this is set, the window may not be visible.
  77.     RootView            rootView;
  78.     WindowOwner          _owner;
  79.     WindowContentView    _contentView;
  80.     View                 _focusedView;/* Warning always call focusedView() */
  81.     View                 _defaultSelectedView;
  82.     Button               _closeButton;
  83.     MenuView             menuView;
  84.  
  85.     Font                 _titleFont;
  86.     String               _title = "";
  87.     Border               _border;
  88.     int                  _layer, _type = TITLE_TYPE, _lastX, _lastY,
  89.                          _resizePart = NO_PART;
  90.     boolean              _closeable, _resizable, _canBecomeMain = true,
  91.                          _containsDocument = false, _drewOnLastDrag,
  92.                          _drawToBackingStore, _onscreen = true,
  93.                          _createdDrawingBuffer, transparent = false,
  94.                          scrollToVisible;
  95.  
  96.     static Vector        _resizeWindowVector = new Vector();
  97.  
  98.     final static int            ABOVE = 0, BEHIND = 1;
  99.     final static int            NO_PART = 0, LEFT_PART = 1, MIDDLE_PART = 2,
  100.                                 RIGHT_PART = 3;
  101.  
  102.     final static String         ownerKey = "owner",
  103.                                 contentViewKey = "contentView",
  104.                                 focusedViewKey = "focusedView",
  105.                                 closeButtonKey = "closeButton",
  106.                                 titleFontKey = "titleFont",
  107.                                 titleKey = "title", borderKey = "border",
  108.                                 layerKey = "layer", typeKey = "type",
  109.                                 closeableKey = "closeable",
  110.                                 resizableKey = "resizeable",
  111.                                 canBecomeMainKey = "canBecomeMain",
  112.                                 containsDocumentKey = "canBecomeDocument",
  113.                                 onscreenKey = "onscreen",
  114.                                 transparentKey = "transparent",
  115.                                 scrollToVisibleKey = "scrollToVisible",
  116.                                 defaultSelectedViewKey = "defaultSelectedView",
  117.                                 menuViewKey = "menuView";
  118.  
  119.  
  120.     /** Default window layer. */
  121.     public final static int     DEFAULT_LAYER = 0;
  122.     /** "Palette" window layer. */
  123.     public final static int     PALETTE_LAYER = 100;
  124.     /** Modal InternalWindow layer. */
  125.     public final static int     MODAL_LAYER   = 200;
  126.     /** Popup window layer. */
  127.     public final static int     POPUP_LAYER = 300;
  128.     /** Drag layer. */
  129.     public final static int     DRAG_LAYER = 400;
  130.  
  131.     /** Windows on this Layer will NOT be clipped to the WindowClipView
  132.       * @private
  133.       */
  134.     public final static int     IGNORE_WINDOW_CLIPVIEW_LAYER = 500;
  135.  
  136.  
  137.     /* constructors */
  138.  
  139.     /** Constructs an InternalWindow with origin (0, 0), zero width and
  140.       * height, and no title.
  141.       */
  142.     public InternalWindow() {
  143.         this(0, 0, 0, 0);
  144.     }
  145.  
  146.     /** Constructs an InternalWindow with bounds <B>rect</B>.
  147.       */
  148.     public InternalWindow(Rect rect) {
  149.         this(rect.x, rect.y, rect.width, rect.height);
  150.     }
  151.  
  152.     /** Constructs an InternalWindow with
  153.       * bounds (<B>x</B>, <B>y</B>, <B>width</B>, <B>height</B>).
  154.       */
  155.     public InternalWindow(int x, int y, int width, int height) {
  156.         this(TITLE_TYPE, x, y, width, height);
  157.     }
  158.  
  159.     /** Constructs an InternalWindow of type
  160.       * <b>type</b> and bounds (<B>x</B>, <B>y</B>, <B>width</B>,
  161.       * <B>height</B>).
  162.       */
  163.     public InternalWindow(int type, int x, int y, int width, int height) {
  164.         super(x, y, width, height);
  165.  
  166.         rootView = application().mainRootView();
  167.  
  168.         _titleFont = Font.fontNamed("Helvetica", Font.BOLD, 12);
  169.  
  170.         _contentView = new WindowContentView(0, 0, 1, 1);
  171.         _contentView.setHorizResizeInstruction(WIDTH_CAN_CHANGE);
  172.         _contentView.setVertResizeInstruction(HEIGHT_CAN_CHANGE);
  173.         addSubviewToWindow(_contentView);
  174.  
  175.         _layer = DEFAULT_LAYER;
  176.  
  177.         _border = new InternalWindowBorder(this);
  178.  
  179.         layoutParts();
  180.         setType(type);
  181.         _defaultSelectedView = this;
  182.     }
  183.  
  184.     /** Returns the InternalWindow's MenuView height.
  185.       */
  186.     int menuViewHeight() {
  187.         if (menuView == null) {
  188.             return 0;
  189.         } else {
  190.             return menuView.height();
  191.         }
  192.     }
  193.  
  194.     /** Returns the InternalWindow's title bar height, by asking its
  195.       * InternalWindowBorder. <b>BLANK_TYPE</b> InternalWindows have
  196.       * zero-height title bars.
  197.       */
  198.     int titleBarMargin() {
  199.         if (_type == BLANK_TYPE) {
  200.             return 0;
  201.         } else {
  202.             return _border.topMargin();
  203.         }
  204.     }
  205.  
  206.     /** Returns the InternalWindow's left border width, by asking its
  207.       * InternalWindowBorder. <b>BLANK_TYPE</b> InternalWindows have a
  208.       * zero-width left border.
  209.       */
  210.     int leftBorderMargin() {
  211.         if (_type == BLANK_TYPE) {
  212.             return 0;
  213.         } else {
  214.             return _border.leftMargin();
  215.         }
  216.     }
  217.  
  218.     /** Returns the InternalWindow's right border width, by asking its
  219.       * InternalWindowBorder. <b>BLANK_TYPE</b> InternalWindows have a
  220.       * zero-width right border.
  221.       */
  222.     int rightBorderMargin() {
  223.         if (_type == BLANK_TYPE) {
  224.             return 0;
  225.         } else {
  226.             return _border.rightMargin();
  227.         }
  228.     }
  229.  
  230.     /** Returns the InternalWindow's bottom border height, by asking its
  231.       * InternalWindowBorder. <b>BLANK_TYPE</b> InternalWindows have a
  232.       * zero-height bottom border.
  233.       */
  234.     int bottomBorderMargin() {
  235.         if (_type == BLANK_TYPE) {
  236.             return 0;
  237.         } else {
  238.             return _border.bottomMargin();
  239.         }
  240.     }
  241.  
  242.     /** Returns the InternalWindow's contentView, the View in which all
  243.       * programmatically-added Views live.
  244.       */
  245.     public WindowContentView contentView() {
  246.         return _contentView;
  247.     }
  248.  
  249.     /** Returns the Size defining the InternalWindow's content area. Use this
  250.       * Size to properly position and size any View that you plan to add to the
  251.       * InternalWindow.
  252.       */
  253.     public Size contentSize() {
  254.         if (_contentView == null) {
  255.             return null;
  256.         }
  257.  
  258.         return new Size(_contentView.bounds.width, _contentView.bounds.height);
  259.     }
  260.  
  261.     /** Resizes and repositions the InternalWindow's contentView to its
  262.       * correct size and location within the InternalWindow based on the
  263.       * InternalWindow's Border.  Positions the close button, if present.
  264.       */
  265.     public void layoutParts() {
  266.         if (_contentView != null) {
  267.             _contentView.setAutoResizeSubviews(false);
  268.             _contentView.setBounds(leftBorderMargin(),
  269.                                    titleBarMargin() + menuViewHeight(),
  270.                                    bounds.width -
  271.                                    (leftBorderMargin() + rightBorderMargin()),
  272.                                    bounds.height -
  273.                                    (titleBarMargin() + menuViewHeight() +
  274.                                       bottomBorderMargin()));
  275.             _contentView.setAutoResizeSubviews(true);
  276.         }
  277.  
  278.         if (_closeButton != null) {
  279.             _closeButton.removeFromSuperview();
  280.  
  281.             _closeButton.moveTo(0, 2 + (titleBarMargin() - 4 -
  282.                                         _closeButton.bounds.height) / 2);
  283.             if (_closeable) {
  284.                 addSubview(_closeButton);
  285.             }
  286.         }
  287.     }
  288.  
  289.     /** Adds <B>aView</B> to the InternalWindow's contentView.  To add a View
  290.       * directly to the InternalWindow, call <b>addSubviewToWindow()</b>.
  291.       * @see #addSubviewToWindow
  292.       */
  293.     public void addSubview(View aView) {
  294.         if (aView == _contentView || aView == _closeButton) {
  295.             addSubviewToWindow(aView);
  296.         } else if (_contentView != null) {
  297.             _contentView.addSubview(aView);
  298.         }
  299.     }
  300.  
  301.     /** Adds <B>aView</B> directly to the InternalWindow.  Unless you're adding
  302.       * special Views or controls to the InternalWindow's border, you should
  303.       * call <b>addSubview()</b> instead of this method to add the View to the
  304.       * InternalWindow's contentView.
  305.       * @see #addSubview
  306.       */
  307.     public void addSubviewToWindow(View aView) {
  308.         super.addSubview(aView);
  309.     }
  310.  
  311.     /** Sets the InternalWindow's RootView, the RootView on which it should
  312.       * appear.  This method does <i>not</i> place the InternalWindow in the
  313.       * View hierarchy, or make it visible in any way.  You
  314.       * need to call this method only if you intend for the InternalWindow to
  315.       * appear on any RootView other than the Application's
  316.       * main RootView.
  317.       */
  318.     public void setRootView(RootView rView) {
  319.         if (rootView != rView) {
  320.             if ((rootView != null) && (_superview != null))
  321.                 rootView.removeWindow(this);
  322.         }
  323.         rootView = rView;
  324.     }
  325.  
  326.     /** Makes the InternalWindow visible (adds it to its RootView's
  327.       * View hierarchy).  Call this method instead of adding the
  328.       * InternalWindow as a subview of the RootView.
  329.      */
  330.     public void show() {
  331.         if (rootView == null) {
  332.             throw new InconsistencyException(
  333.                                     "Can't show Window.  No RootView");
  334.         }
  335.         if (_owner == null || _owner.windowWillShow(this)) {
  336.             if (_superview == null) {
  337.                 rootView.addWindowRelativeTo(this, ABOVE, null);
  338.             } else {
  339.                 rootView.makeWindowVisible(this, ABOVE, null);
  340.             }
  341.             if (_owner != null)
  342.                 _owner.windowDidShow(this);
  343.         }
  344.     }
  345.  
  346.     /** Makes the InternalWindow visible. This method does not return
  347.       * until the user closes the InternalWindow. While the InternalWindow is
  348.       * visible, Views that are not subviews of the InternalWindow will not
  349.       * receive Events.  If the InternalWindow's layer is < MODAL_LAYER, sets
  350.       * it to MODAL_LAYER for the modal session.
  351.       */
  352.     public void showModally() {
  353.         View focusedView;
  354.         Application application = Application.application();
  355.         Event event;
  356.         EventLoop eventLoop = application.eventLoop();
  357.         int previousLayer = layer();
  358.  
  359.         if( previousLayer < MODAL_LAYER ) {
  360.             setLayer( MODAL_LAYER );
  361.         }
  362.  
  363.         this.show();
  364.         rootView()._setMainWindow(this);
  365.         application.beginModalSessionForView(this);
  366.         application.drawAllDirtyViews();
  367.         while(this.isVisible()) {
  368.             event = eventLoop.getNextEvent();
  369.             try {
  370.                 eventLoop.processEvent(event);
  371.             } catch (Exception e) {
  372.                 System.err.println("Uncaught Exception.");
  373.                 e.printStackTrace(System.err);
  374.                 System.err.println("Restarting modal EventLoop.");
  375.             }
  376.         }
  377.         application.endModalSessionForView(this);
  378.  
  379.         if( previousLayer != layer() )
  380.             setLayer(previousLayer);
  381.     }
  382.  
  383.     /** Makes the InternalWindow visible, positioned in front of
  384.       * <B>aWindow</B>.
  385.       * @see #show
  386.       */
  387.     public void showInFrontOf(InternalWindow aWindow) {
  388.         if (aWindow.rootView != rootView) {
  389.             setRootView(aWindow.rootView);
  390.             rootView.addWindowRelativeTo(this, ABOVE, aWindow);
  391.         } else if (_superview == null) {
  392.             rootView.addWindowRelativeTo(this, ABOVE, aWindow);
  393.         } else {
  394.             rootView.makeWindowVisible(this, ABOVE, aWindow);
  395.         }
  396.     }
  397.  
  398.     /** Makes the InternalWindow visible, positioned behind <B>aWindow</B>.
  399.       * @see #show
  400.       */
  401.     public void showBehind(InternalWindow aWindow) {
  402.         if (aWindow.rootView != rootView) {
  403.             setRootView(aWindow.rootView);
  404.             rootView.addWindowRelativeTo(this, BEHIND, aWindow);
  405.         } else if (_superview == null) {
  406.             rootView.addWindowRelativeTo(this, BEHIND, aWindow);
  407.         }
  408.     }
  409.  
  410.     /** Move the window to the front of all other windows with the same layer
  411.       *
  412.       */
  413.     public void moveToFront() {
  414.         InternalWindow   topWindow;
  415.  
  416.         if(!isVisible()) {
  417.             return;
  418.         }
  419.  
  420.         topWindow = rootView.frontWindowWithLayer(layer());
  421.         if(topWindow != null && topWindow != this) {
  422.             rootView.makeWindowVisible(this,ABOVE,topWindow);
  423.         }
  424.     }
  425.  
  426.     /** Move the window behind all other windows with the same layer.
  427.       *
  428.       */
  429.     public void moveToBack() {
  430.         InternalWindow   bottomWindow;
  431.  
  432.         if(!isVisible())
  433.             return;
  434.  
  435.         bottomWindow = rootView.backWindowWithLayer(layer());
  436.         if(bottomWindow != null && bottomWindow != this) {
  437.             rootView.makeWindowVisible(this,BEHIND,bottomWindow);
  438.         }
  439.     }
  440.  
  441.     /** Hides the InternalWindow (removes it from its RootView's View
  442.       * hierarchy).
  443.       * Call this method instead of <B>removeFromSuperview()</b>.
  444.       */
  445.     public void hide() {
  446.         if(isVisible()) {
  447.             if (_owner == null || _owner.windowWillHide(this)) {
  448.                 RootView rView;
  449.  
  450.                 if(containsDocument() && isCurrentDocument()) {
  451.                     Application.application().chooseNextCurrentDocumentWindow(this);
  452.                 }
  453.                 rView = rootView();
  454.                 if (rView != null) {
  455.                     rView.removeWindow(this);
  456.                 }
  457.                 if (_owner != null)
  458.                     _owner.windowDidHide(this);
  459.             }
  460.         }
  461.     }
  462.  
  463.     /** Tells the IFC that this InternalWindow can become the
  464.       * main InternalWindow.
  465.       */
  466.     public void setCanBecomeMain(boolean flag) {
  467.         _canBecomeMain = flag;
  468.         if (isMain() && !_canBecomeMain && rootView != null) {
  469.             rootView._setMainWindow(null);
  470.         }
  471.     }
  472.  
  473.     /** Returns <B>true</B> if the InternalWindow can become the main
  474.       * InternalWindow.
  475.       */
  476.     public boolean canBecomeMain() {
  477.         return _canBecomeMain;
  478.     }
  479.  
  480.     /** Returns <B>true</B> if the InternalWindow is visible.
  481.       */
  482.     public boolean isVisible() {
  483.         return (_superview != null);
  484.     }
  485.  
  486.     /** Sets whether the InternalWindow is visible when unarchived.
  487.       * @private
  488.       */
  489.     public void setOnscreenAtStartup(boolean flag) {
  490.         _onscreen = flag;
  491.     }
  492.  
  493.     /** Returns <b>true</b> if the InternalWindow is visible when unarchived.
  494.       * @private
  495.       */
  496.     public boolean onscreenAtStartup() {
  497.         return _onscreen;
  498.     }
  499.  
  500.     /** Returns <B>true</B> if the InternalWindow is the Application's main
  501.       * InternalWindow.
  502.       */
  503.     public boolean isMain() {
  504.         return ((rootView != null) && rootView.mainWindow() == this);
  505.     }
  506.  
  507.     /** Called by the InternalWindow to create its close button.
  508.       * Override this method to return your own special close button.
  509.       */
  510.     protected Button createCloseButton() {
  511.         Button    button;
  512.  
  513.         button = new Button(0, 0, 1, 1);
  514.         button.setImage(Bitmap.bitmapNamed(
  515.                                "netscape/application/CloseButton.gif"));
  516.         button.setAltImage(Bitmap.bitmapNamed(
  517.                                "netscape/application/CloseButtonActive.gif"));
  518.         //          button.setBezeled(false);
  519.         button.setTransparent(true);
  520.         button.sizeToMinSize();
  521.         button.setHorizResizeInstruction(RIGHT_MARGIN_CAN_CHANGE);
  522.         button.setVertResizeInstruction(BOTTOM_MARGIN_CAN_CHANGE);
  523.         button.moveTo(0, 2 + (titleBarMargin() - 4 -
  524.                               button.bounds.height) / 2);
  525.         button.setTarget(this);
  526.         button.setCommand(HIDE);
  527.         button.removeAllCommandsForKeys();
  528.  
  529.         return button;
  530.     }
  531.  
  532.     /** If the InternalWindow is not <b>BLANK_TYPE</b>, adds or removes a
  533.       * "close" button to (from) the InternalWindow.
  534.       */
  535.     public void setCloseable(boolean flag) {
  536.         _closeable = flag;
  537.         if (_type == BLANK_TYPE) {
  538.             _closeable = false;
  539.         }
  540.         if (_closeable && _closeButton == null) {
  541.             _closeButton = createCloseButton();
  542.         }
  543.  
  544.         if (_closeable) {
  545.             addSubviewToWindow(_closeButton);
  546.         } else if (_closeButton != null) {
  547.             _closeButton.removeFromSuperview();
  548.         }
  549.     }
  550.  
  551.     /** Returns <B>true</B> if the InternalWindow has a close button.
  552.       * @see #setCloseable
  553.       */
  554.     public boolean isCloseable() {
  555.         return _closeable;
  556.     }
  557.  
  558.     /** If the InternalWindow is not <b>BLANK_TYPE</b> or <b>TITLE_TYPE</b>,
  559.       * makes the InternalWindow resizable.
  560.       */
  561.     public void setResizable(boolean flag) {
  562.         if (flag != _resizable) {
  563.             _resizable = flag;
  564.  
  565.             if (_resizable) {
  566.                 _contentView.setHorizResizeInstruction(WIDTH_CAN_CHANGE);
  567.                 _contentView.setVertResizeInstruction(HEIGHT_CAN_CHANGE);
  568.             }
  569.  
  570.             if (_type == TITLE_TYPE) {
  571.                 drawBottomBorder();
  572.                 layoutParts();
  573.             }
  574.         }
  575.     }
  576.  
  577.     /** Returns <B>true</B> if the InternalWindow can be resized by the
  578.       * user.
  579.       * @see #setResizable
  580.       */
  581.     public boolean isResizable() {
  582.         return _resizable;
  583.     }
  584.  
  585.     /** Returns the width of the controls on a resizable InternalWindowBorder.
  586.       */
  587.     int resizePartWidth() {
  588.         if (_border instanceof InternalWindowBorder) {
  589.             return ((InternalWindowBorder)_border).resizePartWidth();
  590.         }
  591.         return 0;
  592.     }
  593.  
  594.     /** Returns the Size the InternalWindow must be to support a content
  595.       * size of (<B>width</B>, <B>height</B>).
  596.       */
  597.     public Size windowSizeForContentSize(int width, int height) {
  598.         return new Size(width + leftBorderMargin() + rightBorderMargin(),
  599.                         height + titleBarMargin() + menuViewHeight() +
  600.                         bottomBorderMargin());
  601.     }
  602.  
  603.     /** Sets the InternalWindow's title, the string displayed in its title
  604.       * bar.
  605.       */
  606.     public void setTitle(String aString) {
  607.         if (_title != null && aString != null && _title.equals(aString)) {
  608.             return;
  609.         }
  610.  
  611.         _title = aString;
  612.         drawTitleBar();
  613.     }
  614.  
  615.     /** Returns the InternalWindow's title.
  616.       * @see #setTitle
  617.       */
  618.     public String title() {
  619.         return _title;
  620.     }
  621.  
  622.     /** Sets the InternalWindow's Border.
  623.       * @see Border
  624.       */
  625.     public void setBorder(Border border) {
  626.         _border = border;
  627.     }
  628.  
  629.     /** Returns the InternalWindow's Border.
  630.       * @see #setBorder
  631.       */
  632.     public Border border() {
  633.         return _border;
  634.     }
  635.  
  636.     /** Sets the InternalWindow's layer.  InternalWindows in a higher layer
  637.       * cannot be obscured by InternalWindows in a lower layer.
  638.       */
  639.     public void setLayer(int windowLayer) {
  640.         _layer = windowLayer;
  641.     }
  642.  
  643.     /** Returns the InternalWindow's layer.
  644.       * @see #setLayer
  645.       */
  646.     public int layer() {
  647.         return _layer;
  648.     }
  649.  
  650.     /** Returns the InternalWindow's minimum size, based in part on the
  651.       * presence of its Border.  <B>BLANK_TYPE</B>
  652.       * InternalWindows return a Size instance with zero width and height.
  653.       */
  654.     public Size minSize() {
  655.         if (_minSize != null) {
  656.             return new Size(_minSize);
  657.         }
  658.  
  659.         setMinSize(resizePartWidth() * 2 + 1, titleBarMargin() +
  660.                    menuViewHeight() + 2);
  661.  
  662.         if (_type == BLANK_TYPE) {
  663.             _minSize.width = 0;
  664.             _minSize.height = 0;
  665.             return _minSize;
  666.         }
  667.  
  668.         if (_minSize.width < leftBorderMargin() + rightBorderMargin()) {
  669.             _minSize.width = leftBorderMargin() + rightBorderMargin();
  670.         }
  671.  
  672.         if (_minSize.height < titleBarMargin() + menuViewHeight() +
  673.                                                  bottomBorderMargin()) {
  674.             _minSize.height = titleBarMargin() + menuViewHeight() +
  675.                                                  bottomBorderMargin();
  676.         }
  677.  
  678.         return new Size(_minSize);
  679.     }
  680.  
  681.     /** Sets the InternalWindow's owner, an object interested in special
  682.       * events, such as the user closing the InternalWindow.
  683.       */
  684.     public void setOwner(WindowOwner anObject) {
  685.         _owner = anObject;
  686.     }
  687.  
  688.     /** Returns the InternalWindow's owner.
  689.       * @see #setOwner
  690.       */
  691.     public WindowOwner owner() {
  692.         return _owner;
  693.     }
  694.  
  695.     /** Sets the MenuView that will appear along the top edge of the Window.
  696.       * This will be an IFC View-based Menu.
  697.       * @see MenuView
  698.       *
  699.       */
  700.     public void setMenuView(MenuView aMenuView) {
  701.         int x, y, width, height;
  702.  
  703.         if (aMenuView != null && aMenuView == menuView) {
  704.             return;
  705.         }
  706.  
  707.         if (menuView != null) {
  708.             menuView.removeFromSuperview();
  709.         }
  710.         menuView = aMenuView;
  711.  
  712.         x = leftBorderMargin();
  713.         y = titleBarMargin();
  714.         width = bounds.width - (leftBorderMargin() + rightBorderMargin());
  715.         height = menuView.height();
  716.         if (height == 0) {
  717.             height = menuView.minSize().height;
  718.         }
  719.  
  720.         menuView.setBounds(x, y, width, height);
  721.  
  722.         addSubviewToWindow(menuView);
  723.         layoutParts();
  724.     }
  725.  
  726.     /** Returns the MenuView that appears along the top edge of this
  727.       * InternalWindow, null if one is not set.
  728.       * @see #setMenuView
  729.       *
  730.       */
  731.     public MenuView menuView() {
  732.         return menuView;
  733.     }
  734.  
  735.     /** Returns <B>true</B> if the InternalWindow's title or resize bar
  736.       * contains the point (<b>x</b>, <b>y</b>).
  737.       * In the case of <B>BLANK_TYPE</B> InternalWindows, this method returns
  738.       * <b>true</b> if the point is anywhere within the InternalWindow's bounds.
  739.       * Override this method to implement any special InternalWindow dragging
  740.       * hotspots your InternalWindow subclass needs.
  741.       */
  742.     public boolean isPointInBorder(int x, int y) {
  743.         if (_type == BLANK_TYPE) {
  744.             return Rect.contains(0, 0, bounds.width, bounds.height, x, y);
  745.         }
  746.  
  747.         if (_resizable && y > bounds.height - bottomBorderMargin()) {
  748.             if (x < resizePartWidth()) {
  749.                 _resizePart = LEFT_PART;
  750.             } else if (x > bounds.width - resizePartWidth()) {
  751.                 _resizePart = RIGHT_PART;
  752.             } else {
  753.                 _resizePart = MIDDLE_PART;
  754.             }
  755.             return true;
  756.         }
  757.  
  758.         if (y > titleBarMargin()) {
  759.             return false;
  760.         }
  761.  
  762.         return true;
  763.     }
  764.  
  765.     /** Overridden to handle special condition of
  766.       * <B>BLANK_TYPE</B> InternalWindows.
  767.       */
  768.     public View viewForMouse(int x, int y) {
  769.         View    theView;
  770.         theView = super.viewForMouse(x, y);
  771.  
  772.         if (_type == BLANK_TYPE && theView == _contentView) {
  773.             theView = this;
  774.         }
  775.  
  776.         return theView;
  777.     }
  778.  
  779.     /** Sets the InternalWindow to be transparent.  A transparent
  780.       * InternalWindow allocates an Image to buffer its drawing, and the
  781.       * IFC's drawing machinery
  782.       * ensures that any portions of the InternalWindow's bounds that it
  783.       * does not draw contain the images bnehind the InternalWindow.
  784.       * @see #isPointInBorder
  785.       */
  786.     public void setTransparent(boolean flag) {
  787.         transparent = flag;
  788.  
  789.         if (transparent) {
  790.             _contentView.setTransparent(true);
  791.             setBuffered(true);
  792.         } else {
  793.             setBuffered(false);
  794.             _contentView.setTransparent(false);
  795.         }
  796.     }
  797.  
  798.     /** Overridden to return <b>true</b> if the InternalWindow is transparent.
  799.       * @see #setTransparent
  800.       */
  801.     public boolean isTransparent() {
  802.         return transparent;
  803.     }
  804.  
  805.     /** Sets the InternalWindow's type.  See the InternalWindow type constants
  806.       * for an enumeration of the various types.
  807.       */
  808.     public void setType(int windowType) {
  809.         _type = windowType;
  810.         if (_type == BLANK_TYPE) {
  811.             setCanBecomeMain(false);
  812.             setCloseable(false);
  813.         }
  814.         layoutParts();
  815.     }
  816.  
  817.     /** Returns the InternalWindow's type.
  818.       * @see #setType
  819.       */
  820.     public int type() {
  821.         return _type;
  822.     }
  823.  
  824.     void updateDrawingBuffer() {
  825.         InternalWindow  nextWindow;
  826.         View            bufferView;
  827.         int             i, count, start;
  828.         Graphics        bufferedGraphics;
  829.         Rect            windowRect, rootBounds;
  830.         boolean         foundWindow = false;
  831.  
  832.         if (drawingBuffer == null) {
  833.             return;
  834.         }
  835.  
  836.         if (rootView == null) {
  837.             throw new InconsistencyException(
  838.                                         "Can't draw window - no RootView");
  839.         }
  840.  
  841.         windowRect = Rect.newRect();
  842.         rootView.disableWindowsAbove(this, true);
  843.         reenableDrawing();
  844.         bufferedGraphics = drawingBuffer.createGraphics();
  845.         bufferedGraphics.setDebugOptions(shouldDebugGraphics());
  846.         superview().convertRectToView(null, bounds, windowRect);
  847.         bufferedGraphics.pushState();
  848.         bufferedGraphics.translate(-windowRect.x, -windowRect.y);
  849.         rootView.draw(bufferedGraphics, windowRect);
  850.         bufferedGraphics.popState();
  851.  
  852.         count = isTransparent() ? rootView.windows.count()
  853.                                 : rootView.windows.indexOf(this);
  854.         start = 0;
  855.         for (i = count; (i-- > 0) && (start == 0); ) {
  856.             nextWindow = (InternalWindow)rootView.windows.elementAt(i);
  857.             if (!nextWindow.isTransparent() &&
  858.                 nextWindow.bounds.contains(bounds)) {
  859.                 start = i;
  860.             }
  861.         }
  862.         if (start == 0) {
  863.             bufferView = rootView.viewWithBuffer(rootView, windowRect);
  864.             if (bufferView != null) {
  865.                 Rect bufferRect = Rect.newRect(0, 0, width(), height());
  866.  
  867.                 convertRectToView(bufferView, bufferRect, bufferRect);
  868.                 bufferedGraphics.pushState();
  869.                 bufferedGraphics.translate(-bufferRect.x,
  870.                                            -bufferRect.y);
  871.                 bufferView.draw(bufferedGraphics, bufferRect);
  872.                 bufferedGraphics.popState();
  873.                 Rect.returnRect(bufferRect);
  874.             }
  875.         }
  876.         for (i = start; i < count; i++) {
  877.             nextWindow = (InternalWindow)rootView.windows.elementAt(i);
  878.             if (nextWindow.bounds.intersects(bounds)) {
  879.                 windowRect.setBounds(0, 0, width(), height());
  880.                 /* since we translated the buffer to our coordinates we need
  881.                  * to bring it back to the other window's coordinate system
  882.                  */
  883.                 convertRectToView(nextWindow, windowRect, windowRect);
  884.                 bufferedGraphics.pushState();
  885.                 bufferedGraphics.translate(-windowRect.x,
  886.                                            -windowRect.y);
  887.                 nextWindow.draw(bufferedGraphics, windowRect);
  888.                 bufferedGraphics.popState();
  889.             }
  890.         }
  891.         Rect.returnRect(windowRect);
  892.  
  893.         rootView.disableWindowsAbove(this, false);
  894.         reenableDrawing();
  895. // ALERT! - We don't seem to need this draw....but why?
  896. //        draw(bufferedGraphics, null);
  897.         bufferedGraphics.dispose();
  898.  
  899.     }
  900.  
  901.     /** Handles a mouse click in the title or resize bar.
  902.       */
  903.     public boolean mouseDown(MouseEvent event) {
  904.         InternalWindow window;
  905.  
  906.         rootView.makeWindowVisible(this, ABOVE, null);
  907.  
  908.         if (!isPointInBorder(event.x, event.y)) {
  909.             return false;
  910.         }
  911.  
  912.         _lastX = event.x + bounds.x;
  913.         _lastY = event.y + bounds.y;
  914.  
  915.         if (_resizePart != NO_PART) {
  916.           /* left */
  917.             window = new InternalWindow(bounds.x, bounds.y, 1, bounds.height);
  918.             window.setType(BLANK_TYPE);
  919.             window._contentView.setTransparent(false);
  920.             window._contentView.setBackgroundColor(Color.darkGray);
  921.             window.setLayer(DRAG_LAYER);
  922.             window.setVertResizeInstruction(HEIGHT_CAN_CHANGE);
  923.             window.setRootView(rootView());
  924.             window.show();
  925.             _resizeWindowVector.addElement(window);
  926.  
  927.           /* right */
  928.             window = new InternalWindow(bounds.maxX() - 1, bounds.y,
  929.                                         1, bounds.height);
  930.             window.setType(BLANK_TYPE);
  931.             window._contentView.setTransparent(false);
  932.             window._contentView.setBackgroundColor(Color.darkGray);
  933.             window.setLayer(DRAG_LAYER);
  934.             window.setVertResizeInstruction(HEIGHT_CAN_CHANGE);
  935.             window.setRootView(rootView());
  936.             window.show();
  937.             _resizeWindowVector.addElement(window);
  938.  
  939.           /* top */
  940.             window = new InternalWindow(bounds.x + 1, bounds.y,
  941.                                         bounds.width - 2, 1);
  942.             window.setType(BLANK_TYPE);
  943.             window._contentView.setTransparent(false);
  944.             window._contentView.setBackgroundColor(Color.darkGray);
  945.             window.setLayer(DRAG_LAYER);
  946.             window.setHorizResizeInstruction(WIDTH_CAN_CHANGE);
  947.             window.setRootView(rootView());
  948.             window.show();
  949.             _resizeWindowVector.addElement(window);
  950.  
  951.           /* bottom */
  952.             window = new InternalWindow(bounds.x + 1, bounds.maxY() - 1,
  953.                                         bounds.width - 2, 1);
  954.             window.setType(BLANK_TYPE);
  955.             window._contentView.setTransparent(false);
  956.             window._contentView.setBackgroundColor(Color.darkGray);
  957.             window.setLayer(DRAG_LAYER);
  958.             window.setHorizResizeInstruction(WIDTH_CAN_CHANGE);
  959.             window.setRootView(rootView());
  960.             window.show();
  961.             _resizeWindowVector.addElement(window);
  962.  
  963.             return true;
  964.         }
  965.  
  966.         return true;
  967.     }
  968.  
  969.     // This override is here to hack in the old behavior of moveBy & sizeBy.
  970.     // We don't call super()!  ALERT!
  971.  
  972.     /** Overridden to provide special InternalWindow resizing behavior. */
  973.     public void setBounds(int x, int y, int width, int height) {
  974.         int dx, dy, dw, dh;
  975.  
  976.         dx = x - bounds.x;
  977.         dy = y - bounds.y;
  978.         dw = width - bounds.width;
  979.         dh = height - bounds.height;
  980.  
  981.         if (isVisible()) {
  982.             moveByAndSizeBy(dx, dy, dw, dh);
  983.             return;
  984.         }
  985.  
  986.         _moveBy(dx, dy);
  987.         _sizeBy(dw, dh);
  988.         _setBounds(x, y, width, height);
  989.     }
  990.  
  991.     private void _super_moveBy(int dx, int dy) {
  992.         if (dx == 0 && dy == 0)
  993.             return;
  994.  
  995.         _setBounds(bounds.x + dx, bounds.y + dy, bounds.width, bounds.height);
  996.         if (_superview != null) {
  997.             _superview.subviewDidMove(this);
  998.         }
  999.         didMoveBy(dx, dy);
  1000.     }
  1001.  
  1002.     private void _super_sizeBy(int dw, int dh) {
  1003.         if (dw == 0 && dh == 0)
  1004.             return;
  1005.  
  1006.         _setBounds(bounds.x, bounds.y, bounds.width + dw, bounds.height + dh);
  1007.  
  1008.         if (buffered) {
  1009.             if (bounds.width != 0 && bounds.height != 0) {
  1010.                 drawingBuffer = new Bitmap(bounds.width, bounds.height);
  1011.                 drawingBufferValid = false;
  1012.             } else if (drawingBuffer != null) {
  1013.                 drawingBuffer.flush();
  1014.                 drawingBuffer = null;
  1015.             }
  1016.         }
  1017.  
  1018.         disableDrawing();
  1019.         if (_superview != null) {
  1020.             _superview.subviewDidResize(this);
  1021.         }
  1022.         super.didSizeBy(dw, dh);
  1023.         reenableDrawing();
  1024.     }
  1025.  
  1026.     /** Called by the InternalWindow before every move, whether through
  1027.       * explicit setBounds() calls or with mouse dragging. Subclasses can
  1028.       * override this method to modify <b>newPoint</b> to
  1029.       * constrain movement. The Point <b>newPoint</b> is in the coordinate
  1030.       * system of this Window's superview.
  1031.       *
  1032.       */
  1033.     protected void willMoveTo(Point newPoint) {
  1034.     }
  1035.  
  1036.     private void _moveBy(int deltaX, int deltaY) {
  1037.         MouseEvent      moveEvent;
  1038.         Point           tmpPoint;
  1039.  
  1040.         if (deltaX == 0 && deltaY == 0) {
  1041.             return;
  1042.         }
  1043.  
  1044.         tmpPoint = Point.newPoint(bounds.x + deltaX, bounds.y + deltaY);
  1045.         willMoveTo(tmpPoint);
  1046.         deltaX = tmpPoint.x - bounds.x;
  1047.         deltaY = tmpPoint.y - bounds.y;
  1048.         Point.returnPoint(tmpPoint);
  1049.  
  1050.         if (!isVisible()) {
  1051.             _super_moveBy(deltaX, deltaY);
  1052.             return;
  1053.         }
  1054.  
  1055.         _lastX = bounds.x;
  1056.         _lastY = bounds.y;
  1057.  
  1058.         moveEvent = new MouseEvent(0, MouseEvent.MOUSE_DRAGGED,
  1059.                                    _lastX + deltaX, _lastY + deltaY, 0);
  1060.         mouseDragged(moveEvent);
  1061.  
  1062.     }
  1063.  
  1064.     void _checkSize(Size deltaSize) {
  1065.         Size    minSize;
  1066.  
  1067.         minSize = minSize();
  1068.         if (bounds.width + deltaSize.width < minSize.width) {
  1069.             deltaSize.width = minSize.width - bounds.width;
  1070.         }
  1071.         if (bounds.height + deltaSize.height < minSize.height) {
  1072.             deltaSize.height = minSize.height - bounds.height;
  1073.         }
  1074.  
  1075.         if (_owner != null) {
  1076.             _owner.windowWillSizeBy(this, deltaSize);
  1077.         }
  1078.     }
  1079.  
  1080.     private void _sizeBy(int deltaWidth, int deltaHeight) {
  1081.         Rect    tmpRect;
  1082.         Size    tmpSize;
  1083.  
  1084.         if (deltaWidth == 0 && deltaHeight == 0) {
  1085.             return;
  1086.         }
  1087.  
  1088.         tmpSize = Size.newSize(deltaWidth, deltaHeight);
  1089.         _checkSize(tmpSize);
  1090.         deltaWidth = tmpSize.width;
  1091.         deltaHeight = tmpSize.height;
  1092.         Size.returnSize(tmpSize);
  1093.  
  1094.         if (!isVisible()) {
  1095.             _super_sizeBy(deltaWidth, deltaHeight);
  1096.             layoutParts();
  1097.             return;
  1098.         }
  1099.  
  1100.         tmpRect = Rect.newRect(bounds);
  1101.         _super_sizeBy(deltaWidth, deltaHeight);
  1102.         layoutParts();
  1103.  
  1104.         /* in Constructor, we may not be subviews of the RootView, so
  1105.          * have to convert
  1106.          */
  1107.         if (canDraw()) {
  1108.             tmpRect.unionWith(bounds);
  1109.             superview().convertRectToView(null, tmpRect, tmpRect);
  1110.             rootView.redraw(tmpRect);
  1111.         }
  1112.  
  1113.         Rect.returnRect(tmpRect);
  1114.     }
  1115.  
  1116.     /** Smoothly, simultaneously moves and resizes a visible Window.
  1117.       */
  1118.     private void moveByAndSizeBy(int deltaX, int deltaY, int deltaWidth,
  1119.                                  int deltaHeight) {
  1120.         Rect    tmpRect;
  1121.         Size    tmpSize;
  1122.         Point   tmpPoint;
  1123.  
  1124.         if (deltaX == 0 && deltaY == 0 && deltaWidth == 0 &&
  1125.             deltaHeight == 0) {
  1126.             return;
  1127.         }
  1128.  
  1129.         tmpSize = Size.newSize(deltaWidth, deltaHeight);
  1130.         _checkSize(tmpSize);
  1131.         deltaWidth = tmpSize.width;
  1132.         deltaHeight = tmpSize.height;
  1133.         Size.returnSize(tmpSize);
  1134.  
  1135.         tmpPoint = Point.newPoint(bounds.x + deltaX, bounds.y + deltaY);
  1136.         willMoveTo(tmpPoint);
  1137.         deltaX = tmpPoint.x - bounds.x;
  1138.         deltaY = tmpPoint.y - bounds.y;
  1139.         Point.returnPoint(tmpPoint);
  1140.  
  1141.         if (!isVisible()) {
  1142.             _super_moveBy(deltaX, deltaY);
  1143.             _super_sizeBy(deltaWidth, deltaHeight);
  1144.             layoutParts();
  1145.             return;
  1146.         }
  1147.  
  1148.         tmpRect = Rect.newRect(bounds);
  1149.         _super_moveBy(deltaX, deltaY);
  1150.         _super_sizeBy(deltaWidth, deltaHeight);
  1151.         if (deltaWidth != 0 || deltaHeight != 0) {
  1152.             layoutParts();
  1153.         }
  1154.         tmpRect.unionWith(bounds);
  1155.  
  1156.         /// If we are not the immediate subview of our rootView, we need
  1157.         /// to translate the rect to the rootView. This happens in constructor
  1158.         /// when we wrap the InternalWindow in a ComponentView. Normally this
  1159.         /// should not happen, as the InternalWindow will always be in the rootView.
  1160.         if(superview() != rootView) {
  1161.             superview().convertRectToView(rootView, tmpRect, tmpRect);
  1162.         }
  1163.  
  1164.         if (isTransparent()) {
  1165.             disableDrawing();
  1166.             rootView.redraw(tmpRect);
  1167.             reenableDrawing();
  1168.             draw();
  1169.         } else {
  1170.             rootView.redraw(tmpRect);
  1171.         }
  1172.  
  1173.         Rect.returnRect(tmpRect);
  1174.     }
  1175.  
  1176.     /** Convenience method for smoothly, simultaneously moving and resizing a
  1177.       * visible Window.  Equivalent to
  1178.       * <pre>
  1179.       *     moveByAndSizeBy(x - bounds.x, y - bounds.y,
  1180.       *                     width - bounds.width,
  1181.       *                     height - bounds.height);
  1182.       * </pre>
  1183.       */
  1184.     private void moveToAndSizeTo(int x, int y, int width, int height) {
  1185.         moveByAndSizeBy(x - bounds.x, y - bounds.y,
  1186.                         width - bounds.width,
  1187.                         height - bounds.height);
  1188.     }
  1189.  
  1190.     /** Configures the InternalWindow to move itself in response to scroll
  1191.       * requests sent via <b>scrollRectToVisible</b>.  By default, any scroll
  1192.       * requests received via <b>scrollRectToVisible</b> are ignored.  If
  1193.       * <b>flag</b> is <b>true</b>, the InternalWindow will move itself so
  1194.       * that the scroll rectangle is completely visible, meaning not clipped
  1195.       * by the RootView.  Popups use this feature to allow users to
  1196.       * navigate Popup windows that popup such that they are clipped by
  1197.       * the RootView.
  1198.       * @see View#scrollRectToVisible
  1199.       * @private
  1200.       */
  1201.     public void setScrollsToVisible(boolean flag) {
  1202.         scrollToVisible = flag;
  1203.     }
  1204.  
  1205.     /** Returns <b>true</b> if the InternalWindow moves itself in response to
  1206.       * scroll requests sent via <b>scrollRectToVisible</b>.
  1207.       * @see #setScrollToVisible
  1208.       * @private
  1209.       */
  1210.     public boolean scrollsToVisible() {
  1211.         return scrollToVisible;
  1212.     }
  1213.  
  1214.     /** Overridden to autoscroll the InternalWindow if configured to
  1215.       * autoscroll.
  1216.       * @see #setScrollToVisible
  1217.       * @private
  1218.       */
  1219.     public void scrollRectToVisible(Rect aRect) {
  1220.         Rect    visibleRect, tmpRect, absoluteBounds, backgroundBounds;
  1221.         int     deltaX = 0, deltaY = 0;
  1222.  
  1223.         if (!scrollToVisible) {
  1224.             return;
  1225.         }
  1226.  
  1227.         visibleRect = Rect.newRect();
  1228.         computeVisibleRect(visibleRect);
  1229.  
  1230.         /* are we completely visible? */
  1231.         if (visibleRect.width == bounds.width &&
  1232.             visibleRect.height == bounds.height) {
  1233.             Rect.returnRect(visibleRect);
  1234.             return;
  1235.         }
  1236.  
  1237.         if (!visibleRect.contains(aRect)) {
  1238.             convertRectToView(null, visibleRect, visibleRect);
  1239.             tmpRect = Rect.newRect();
  1240.             convertRectToView(null, aRect, tmpRect);
  1241.             absoluteBounds = Rect.newRect(0, 0, width(), height());
  1242.             convertRectToView(null, absoluteBounds, absoluteBounds);
  1243.  
  1244.             if (tmpRect.x < visibleRect.x &&
  1245.                 visibleRect.x > absoluteBounds.x) {
  1246.                 deltaX = visibleRect.x - tmpRect.x;
  1247.             } else if (tmpRect.maxX() > visibleRect.maxX() &&
  1248.                        visibleRect.maxX() < absoluteBounds.maxX()) {
  1249.                 deltaX = visibleRect.maxX() - tmpRect.maxX();
  1250.             }
  1251.  
  1252.             if (tmpRect.y < visibleRect.y &&
  1253.                 visibleRect.y > absoluteBounds.y) {
  1254.                 deltaY = visibleRect.y - tmpRect.y;
  1255.             } else if (tmpRect.maxY() > visibleRect.maxY() &&
  1256.                        visibleRect.maxY() < absoluteBounds.maxY()) {
  1257.                 deltaY = visibleRect.maxY() - tmpRect.maxY();
  1258.             }
  1259.  
  1260.             /* don't yank onscreen more than 3 pixels, any side */
  1261.             backgroundBounds = rootView().bounds;
  1262.             if (deltaX > 0 && absoluteBounds.x + deltaX > 3) {
  1263.                 deltaX = 3 - absoluteBounds.x;
  1264.             } else if (deltaX < 0 && absoluteBounds.maxX() + deltaX <
  1265.                                                 backgroundBounds.maxX() - 3) {
  1266.                 deltaX = backgroundBounds.maxX() - 3 - absoluteBounds.maxX();
  1267.             }
  1268.             if (deltaY > 0 && absoluteBounds.y + deltaY > 3) {
  1269.                 deltaY = 3 - absoluteBounds.y;
  1270.             } else if (deltaY < 0 && absoluteBounds.maxY() + deltaY <
  1271.                                                 backgroundBounds.maxY() - 3) {
  1272.                 deltaY = backgroundBounds.maxY() - 3 - absoluteBounds.maxY();
  1273.             }
  1274.  
  1275.             moveBy(deltaX, deltaY);
  1276.  
  1277.             Rect.returnRect(tmpRect);
  1278.             Rect.returnRect(absoluteBounds);
  1279.         }
  1280.  
  1281.         Rect.returnRect(visibleRect);
  1282.     }
  1283.  
  1284.     /** Overridden to do nothing.
  1285.       */
  1286.     public void subviewDidResize() {
  1287.     }
  1288.  
  1289.     /** Centers the InternalWindow's within its RootView. */
  1290.     public void center() {
  1291.         Rect    rootViewBounds;
  1292.         Rect    newBounds;
  1293.         rootViewBounds = rootView.bounds;
  1294.  
  1295.         newBounds = new Rect((int)((rootViewBounds.width - bounds.width) / 2),
  1296.                                (int)((rootViewBounds.height - bounds.height) / 2),
  1297.                                bounds.width, bounds.height);
  1298.         if(newBounds.y < 0)
  1299.             newBounds.y = 0;
  1300.         setBounds(newBounds);
  1301.     }
  1302.  
  1303.     void mouseResizeDrag(MouseEvent event) {
  1304.         InternalWindow  window;
  1305.         Rect            newBounds;
  1306.         Size            tmpSize;
  1307.         int             deltaX = 0, deltaY = 0;
  1308.  
  1309.         event.x += bounds.x;
  1310.         event.y += bounds.y;
  1311.  
  1312.         if (_resizePart == MIDDLE_PART /*||
  1313.             (_resizeInstructions & WIDTH_CAN_CHANGE) == 0*/) {
  1314.             event.x = _lastX;
  1315.         }
  1316.  
  1317.         newBounds = Rect.newRect(bounds);
  1318.  
  1319.         if (_resizePart == LEFT_PART) {
  1320.             newBounds.moveBy(event.x - _lastX, 0);
  1321.             newBounds.sizeBy(_lastX - event.x, event.y - _lastY);
  1322.         } else {
  1323.             newBounds.sizeBy(event.x - _lastX, event.y - _lastY);
  1324.         }
  1325.         /* don't let the user drag the bottom border off the screen */
  1326.         if (newBounds.height > superview().height() - newBounds.y) {
  1327.             newBounds.sizeBy(0, superview().height() - newBounds.height -
  1328.                              newBounds.y);
  1329.         }
  1330.         tmpSize = Size.newSize(newBounds.width - bounds.width,
  1331.                                newBounds.height - bounds.height);
  1332.         _checkSize(tmpSize);
  1333.         if (_resizePart == LEFT_PART) {
  1334.             if (newBounds.x > bounds.x + bounds.width) {
  1335.                 newBounds.moveBy(bounds.x - newBounds.x - tmpSize.width, 0);
  1336.             } else {
  1337.                 newBounds.moveBy(newBounds.width - bounds.width -
  1338.                                  tmpSize.width, 0);
  1339.             }
  1340.         }
  1341.         newBounds.sizeBy(tmpSize.width -
  1342.                          (newBounds.width - bounds.width),
  1343.                          tmpSize.height -
  1344.                          (newBounds.height - bounds.height));
  1345.         Size.returnSize(tmpSize);
  1346.  
  1347.         window = (InternalWindow)_resizeWindowVector.elementAt(0);
  1348.         deltaY = newBounds.height - window.bounds.height;
  1349.         if (_resizePart == LEFT_PART) {
  1350.             if (deltaY < 0) {
  1351.               /* right, top, bottom, left */
  1352.                 window = (InternalWindow)_resizeWindowVector.elementAt(1);
  1353.                 window.sizeTo(1, newBounds.height);
  1354.  
  1355.                 window = (InternalWindow)_resizeWindowVector.elementAt(2);
  1356.                 window.moveToAndSizeTo(newBounds.x + 1, newBounds.y,
  1357.                                        newBounds.width - 2, 1);
  1358.  
  1359.                 window = (InternalWindow)_resizeWindowVector.elementAt(3);
  1360.                 window.moveToAndSizeTo(newBounds.x + 1, newBounds.maxY() - 1,
  1361.                                        newBounds.width - 2, 1);
  1362.  
  1363.                 window = (InternalWindow)_resizeWindowVector.elementAt(0);
  1364.                 window.moveToAndSizeTo(newBounds.x, newBounds.y, 1,
  1365.                                        newBounds.height);
  1366.             } else {
  1367.               /* left, bottom, top, right */
  1368.                 window = (InternalWindow)_resizeWindowVector.elementAt(0);
  1369.                 window.moveToAndSizeTo(newBounds.x, newBounds.y, 1,
  1370.                                        newBounds.height);
  1371.  
  1372.                 window = (InternalWindow)_resizeWindowVector.elementAt(3);
  1373.                 window.moveToAndSizeTo(newBounds.x + 1, newBounds.maxY() - 1,
  1374.                                        newBounds.width - 2, 1);
  1375.  
  1376.                 window = (InternalWindow)_resizeWindowVector.elementAt(2);
  1377.                 window.moveToAndSizeTo(newBounds.x + 1, newBounds.y,
  1378.                                        newBounds.width - 2, 1);
  1379.  
  1380.                 window = (InternalWindow)_resizeWindowVector.elementAt(1);
  1381.                 window.sizeTo(1, newBounds.height);
  1382.             }
  1383.         } else if (_resizePart == MIDDLE_PART) {
  1384.             if (deltaY < 0) {
  1385.               /* left, right, bottom */
  1386.                 window = (InternalWindow)_resizeWindowVector.elementAt(1);
  1387.                 window.sizeTo(1, newBounds.height);
  1388.  
  1389.                 window = (InternalWindow)_resizeWindowVector.elementAt(0);
  1390.                 window.sizeTo(1, newBounds.height);
  1391.  
  1392.                 window = (InternalWindow)_resizeWindowVector.elementAt(3);
  1393.                 window.moveToAndSizeTo(newBounds.x + 1, newBounds.maxY() - 1,
  1394.                                        window.bounds.width,
  1395.                                        window.bounds.height);
  1396.             } else {
  1397.               /* bottom, left, right */
  1398.                 window = (InternalWindow)_resizeWindowVector.elementAt(3);
  1399.                 window.moveToAndSizeTo(newBounds.x + 1, newBounds.maxY() - 1,
  1400.                                        window.bounds.width,
  1401.                                        window.bounds.height);
  1402.  
  1403.                 window = (InternalWindow)_resizeWindowVector.elementAt(1);
  1404.                 window.sizeTo(1, newBounds.height);
  1405.  
  1406.                 window = (InternalWindow)_resizeWindowVector.elementAt(0);
  1407.                 window.sizeTo(1, newBounds.height);
  1408.             }
  1409.         } else {
  1410.             if (deltaY < 0) {
  1411.               /* left, top, bottom, right */
  1412.                 window = (InternalWindow)_resizeWindowVector.elementAt(0);
  1413.                 window.sizeTo(1, newBounds.height);
  1414.  
  1415.                 window = (InternalWindow)_resizeWindowVector.elementAt(2);
  1416.                 window.sizeTo(newBounds.width - 2, 1);
  1417.  
  1418.                 window = (InternalWindow)_resizeWindowVector.elementAt(3);
  1419.                 window.moveToAndSizeTo(newBounds.x + 1, newBounds.maxY() - 1,
  1420.                                        newBounds.width - 2, 1);
  1421.  
  1422.                 window = (InternalWindow)_resizeWindowVector.elementAt(1);
  1423.                 window.moveToAndSizeTo(newBounds.maxX() - 1, newBounds.y, 1,
  1424.                                        newBounds.height);
  1425.             } else {
  1426.               /* right, bottom, top, left */
  1427.                 window = (InternalWindow)_resizeWindowVector.elementAt(1);
  1428.                 window.moveToAndSizeTo(newBounds.maxX() - 1, newBounds.y, 1,
  1429.                                        newBounds.height);
  1430.  
  1431.                 window = (InternalWindow)_resizeWindowVector.elementAt(3);
  1432.                 window.moveToAndSizeTo(newBounds.x + 1, newBounds.maxY() - 1,
  1433.                                        newBounds.width - 2, 1);
  1434.  
  1435.                 window = (InternalWindow)_resizeWindowVector.elementAt(2);
  1436.                 window.sizeTo(newBounds.width - 2, 1);
  1437.  
  1438.                 window = (InternalWindow)_resizeWindowVector.elementAt(0);
  1439.                 window.sizeTo(1, newBounds.height);
  1440.             }
  1441.         }
  1442.  
  1443.         Rect.returnRect(newBounds);
  1444.     }
  1445.  
  1446.     /** Handles a mouse drag in the title or resize bar.
  1447.       */
  1448.     public void mouseDragged(MouseEvent event) {
  1449.         Rect            oldBounds, clipRect;
  1450.         Point           tmpPoint;
  1451.         int             x, y, minX, minY, maxX, maxY, eventX, eventY;
  1452.  
  1453.         /* resize? */
  1454.         if (_resizePart != NO_PART) {
  1455.             mouseResizeDrag(event);
  1456.             return;
  1457.         }
  1458.  
  1459.         /* we want everything to be in the absolute coord. system */
  1460.         eventX = event.x + bounds.x;
  1461.         eventY = event.y + bounds.y;
  1462.  
  1463.         /* don't let the user drag the window completely offscreen */
  1464.         if (_type == BLANK_TYPE) {
  1465.             minY = -5;
  1466.         } else {
  1467.             minY = -titleBarMargin() + 5;
  1468.         }
  1469.         maxY = superview().height() - 5;
  1470.  
  1471.         y = bounds.y + eventY - _lastY;
  1472.         if (y < minY) {
  1473.             eventY = minY + _lastY - bounds.y;
  1474.         } else if (y > maxY) {
  1475.             eventY = maxY + _lastY - bounds.y;
  1476.         }
  1477.  
  1478.         minX = -bounds.width + 5;
  1479.         maxX = superview().width() - 5;
  1480.  
  1481.         x = bounds.x + eventX - _lastX;
  1482.         if (x < minX) {
  1483.             eventX = minX + _lastX - bounds.x;
  1484.         } else if (x > maxX) {
  1485.             eventX = maxX + _lastX - bounds.x;
  1486.         }
  1487.  
  1488.         tmpPoint = Point.newPoint(bounds.x + eventX - _lastX,
  1489.                                   bounds.y + eventY - _lastY);
  1490.         willMoveTo(tmpPoint);
  1491.         eventX = tmpPoint.x + _lastX - bounds.x;
  1492.         eventY = tmpPoint.y + _lastY - bounds.y;
  1493.         Point.returnPoint(tmpPoint);
  1494.  
  1495.         /* setup */
  1496.         clipRect = Rect.newRect();
  1497.         computeVisibleRect(clipRect);
  1498.  
  1499.         /* in Constructor, Window may not be subview of RootView, so
  1500.          * can't just assume its bounds is in the absolute coordinate
  1501.          * system.
  1502.          */
  1503.         oldBounds = Rect.newRect();
  1504.         convertRectToView(null, clipRect, oldBounds);
  1505.         if (!isTransparent() && drawingBuffer == null) {
  1506.             Graphics bufferedGraphics;
  1507.  
  1508.             _createdDrawingBuffer = true;
  1509.             setBuffered(true);
  1510.             _drawToBackingStore = true;
  1511.             bufferedGraphics = drawingBuffer.createGraphics();
  1512.             bufferedGraphics.setDebugOptions(shouldDebugGraphics());
  1513.             draw(bufferedGraphics, null);
  1514.             bufferedGraphics.dispose();
  1515.             bufferedGraphics = null;
  1516.             _drawToBackingStore = false;
  1517.         }
  1518.  
  1519.         _super_moveBy(eventX - _lastX, eventY - _lastY);
  1520.  
  1521.         // I believe this hack is here because we manually buffering ourselves
  1522.         // above if we not.
  1523.         if (!isTransparent()) {
  1524.             if (drawingBuffer != null) {
  1525.                 drawingBufferIsBitCache = true;
  1526.             }
  1527.  
  1528.             draw();
  1529.  
  1530.             if (drawingBuffer != null) {
  1531.                 drawingBufferIsBitCache = false;
  1532.             }
  1533.         }
  1534.  
  1535.         if (isTransparent()) {
  1536.             draw();
  1537.         }
  1538.  
  1539.         rootView.disableWindowsAbove(this, true);
  1540.         rootView.redraw(oldBounds);
  1541.         rootView.disableWindowsAbove(this, false);
  1542.  
  1543.         _lastX = eventX;
  1544.         _lastY = eventY;
  1545.  
  1546. //        oldBounds.unionWith(bounds);
  1547.         oldBounds.unionWith(superview().convertRectToView(null, bounds));
  1548.         rootView.redrawTransparentWindows(oldBounds, this);
  1549.         Rect.returnRect(clipRect);
  1550.     }
  1551.  
  1552.     /** Handles a mouse up in the title or resize bar.
  1553.       */
  1554.     public void mouseUp(MouseEvent event) {
  1555.         InternalWindow nextWindow, secondWindow;
  1556.         int             i;
  1557.  
  1558.         if (_resizePart != NO_PART) {
  1559.             nextWindow = (InternalWindow)_resizeWindowVector.elementAt(0);
  1560.             secondWindow = (InternalWindow)_resizeWindowVector.elementAt(1);
  1561.  
  1562.             if (_resizePart == LEFT_PART) {
  1563.                 moveByAndSizeBy(nextWindow.bounds.x - bounds.x, 0,
  1564.                                 secondWindow.bounds.x - nextWindow.bounds.x -
  1565.                                                             bounds.width + 1,
  1566.                                 nextWindow.bounds.height - bounds.height);
  1567.             } else {
  1568.                 sizeTo(secondWindow.bounds.x - nextWindow.bounds.x + 1,
  1569.                        nextWindow.bounds.height);
  1570.             }
  1571.  
  1572.             i = _resizeWindowVector.count();
  1573.             while (i-- > 0) {
  1574.                 nextWindow = (InternalWindow)_resizeWindowVector.elementAt(i);
  1575.                 nextWindow.hide();
  1576.             }
  1577.  
  1578.             _resizeWindowVector.removeAllElements();
  1579.  
  1580.             _resizePart = NO_PART;
  1581.         }
  1582.  
  1583.         if (_createdDrawingBuffer) {
  1584.             setBuffered(false);
  1585.             _createdDrawingBuffer = false;
  1586.         }
  1587.     }
  1588.  
  1589.     void _drawLine(Graphics g, int x1, int x2, int y, Color c1, Color c2) {
  1590.         int     i, count;
  1591.  
  1592.         g.setColor(c1);
  1593.         for (i = x1; i <= x2; i += 2) {
  1594.             g.drawLine(i, y, i, y);
  1595.         }
  1596.         g.setColor(c2);
  1597.         for (i = x1 + 1; i <= x2; i += 2) {
  1598.             g.drawLine(i, y, i, y);
  1599.         }
  1600.     }
  1601.  
  1602.     /** Draws the InternalWindow's Border.
  1603.       * If the InternalWindow is of type <B>BLANK_TYPE</B>, this method does
  1604.       * nothing. You never call this method directly - use the <b>draw()</b>
  1605.       * method to draw the InternalWindow.
  1606.       * @see View#draw
  1607.       */
  1608.     public void drawView(Graphics g) {
  1609.         if (drawingBuffer != null && !g.isDrawingBuffer() ||
  1610.             _type == BLANK_TYPE) {
  1611.             return;
  1612.         }
  1613.  
  1614.         _border.drawInRect(g, 0, 0, bounds.width, bounds.height);
  1615.     }
  1616.  
  1617.     /** Convenience method for drawing the InternalWindow's title bar portion,
  1618.       * only if the InternalWindow is not of type
  1619.       * <b>BLANK_TYPE</b>.  Calls <B>draw()</B>.
  1620.       */
  1621.     public void drawTitleBar() {
  1622.         Rect    tmpRect;
  1623.  
  1624.         if (_type == BLANK_TYPE) {
  1625.             return;
  1626.         }
  1627.  
  1628.         tmpRect = Rect.newRect(0, 0, bounds.width, titleBarMargin());
  1629.         draw(tmpRect);
  1630.  
  1631.         Rect.returnRect(tmpRect);
  1632.     }
  1633.  
  1634.  
  1635.     /** Convenience method for drawing the InternalWindow's bottom Border
  1636.       * portion , only if the InternalWindow is not of type
  1637.       * <b>BLANK_TYPE</b>.  Calls <B>draw()</B>.
  1638.       */
  1639.     public void drawBottomBorder() {
  1640.         Rect    tmpRect;
  1641.  
  1642.         if (_type == BLANK_TYPE) {
  1643.             return;
  1644.         }
  1645.  
  1646.         tmpRect = Rect.newRect(0, bounds.height - bottomBorderMargin(),
  1647.                                bounds.width, bottomBorderMargin());
  1648.         draw(tmpRect);
  1649.  
  1650.         Rect.returnRect(tmpRect);
  1651.     }
  1652.  
  1653.     /** Overridden to handle special needs of transparent InternalWindows.
  1654.       */
  1655.     public void draw(Graphics g, Rect clipRect) {
  1656.         View        containingView;
  1657.  
  1658.        if (isTransparent() && (g == null || !g.isDrawingBuffer()) &&
  1659.             rootView._redrawTransWindows) {
  1660. //            containingView = _viewForRect(clipRect, this);
  1661.             containingView = null;
  1662.             if (containingView == null || containingView.isTransparent()) {
  1663.                 updateDrawingBuffer();
  1664.             }
  1665.         }
  1666.         super.draw(g, clipRect);
  1667.     }
  1668.  
  1669.     /** Informs the InternalWindow that it has become the main InternalWindow,
  1670.       * and notifies its owner.
  1671.       * @see #setOwner
  1672.       */
  1673.     public void didBecomeMain() {
  1674.         drawTitleBar();
  1675.  
  1676.         if (_owner != null) {
  1677.             _owner.windowDidBecomeMain(this);
  1678.         }
  1679.  
  1680.         rootView.setFocusedView(focusedView(), false);
  1681.  
  1682.         if(containsDocument()) {
  1683.             Application.application().makeCurrentDocumentWindow(this);
  1684.         }
  1685.     }
  1686.  
  1687.     /** Informs the InternalWindow that another InternalWindow has replaced it
  1688.       * as the Application's main InternalWindow, and notifies its owner.
  1689.       * @see #setOwner
  1690.       */
  1691.     public void didResignMain() {
  1692.         drawTitleBar();
  1693.  
  1694.         if (_owner != null) {
  1695.             _owner.windowDidResignMain(this);
  1696.         }
  1697.         if (rootView != null)
  1698.             rootView.setFocusedView(null, false);
  1699.     }
  1700.  
  1701.     /** Sets whether the window contains a document. Windows containing document
  1702.       * are treated in a different manner by the target chain.
  1703.       *
  1704.       */
  1705.     public void setContainsDocument(boolean containsDocument) {
  1706.         _containsDocument = containsDocument;
  1707.     }
  1708.  
  1709.     /** Return whether the window contains a document.
  1710.      */
  1711.     public boolean containsDocument() {
  1712.         return _containsDocument;
  1713.     }
  1714.  
  1715.     /** For backward compatibility
  1716.      *  @private
  1717.      */
  1718.     public void setCanBecomeDocument(boolean containsDocument) {
  1719.         setContainsDocument(containsDocument);
  1720.     }
  1721.  
  1722.     /** For backward compatibility
  1723.      *  @private
  1724.      */
  1725.     public boolean canBecomeDocument() {
  1726.         return containsDocument();
  1727.     }
  1728.  
  1729.     /** If the window contains a document, this method is called
  1730.       * when the window just became the current document.
  1731.       *
  1732.       */
  1733.     public void didBecomeCurrentDocument() {
  1734.     }
  1735.  
  1736.     /** If the window contains a document, this method is called
  1737.       * when the window is no longer the current document.
  1738.       *
  1739.       */
  1740.     public void didResignCurrentDocument() {
  1741.     }
  1742.  
  1743.     /** Return whether this window is the current document
  1744.       *
  1745.       */
  1746.     public boolean isCurrentDocument() {
  1747.         if(Application.application().currentDocumentWindow() == this)
  1748.             return true;
  1749.         else
  1750.             return false;
  1751.     }
  1752.  
  1753.  
  1754.     /** Sets the InternalWindow's "focused" View, the View that will receive
  1755.       * key events.
  1756.       */
  1757.     public void setFocusedView(View view) {
  1758.         _focusedView = view;
  1759.         if (rootView != null) {
  1760.             if(rootView.mainWindow() == this && view != null)
  1761.                 rootView.makeWindowVisible(this,ABOVE,null);
  1762.             rootView.setFocusedView(focusedView());
  1763.         }
  1764.     }
  1765.  
  1766.     /** Returns the InternalWindow's "focused" View.
  1767.       * @see #setFocusedView
  1768.       */
  1769.     public View focusedView() {
  1770.         if(_focusedView != null && _focusedView.descendsFrom(this))
  1771.             return _focusedView;
  1772.         else {
  1773.             _focusedView = null;
  1774.             return _focusedView;
  1775.         }
  1776.     }
  1777.  
  1778. /* archiving */
  1779.  
  1780.  
  1781.     /** Describes the InternalWindow class' information.
  1782.       * @seeCodable#describeClassInfo
  1783.       */
  1784.     public void describeClassInfo(ClassInfo info) {
  1785.         super.describeClassInfo(info);
  1786.  
  1787.         info.addClass("netscape.application.InternalWindow", 3);
  1788.         info.addField(ownerKey, OBJECT_TYPE);
  1789.         info.addField(contentViewKey, OBJECT_TYPE);
  1790.         info.addField(focusedViewKey, OBJECT_TYPE);
  1791.         info.addField(closeButtonKey, OBJECT_TYPE);
  1792.         info.addField(titleFontKey, OBJECT_TYPE);
  1793.         info.addField(titleKey, STRING_TYPE);
  1794.         info.addField(borderKey, OBJECT_TYPE);
  1795.         info.addField(layerKey, INT_TYPE);
  1796.         info.addField(typeKey, INT_TYPE);
  1797.         info.addField(closeableKey, BOOLEAN_TYPE);
  1798.         info.addField(resizableKey, BOOLEAN_TYPE );
  1799.         info.addField(canBecomeMainKey, BOOLEAN_TYPE);
  1800.         info.addField(containsDocumentKey, BOOLEAN_TYPE);
  1801.         info.addField(onscreenKey, BOOLEAN_TYPE);
  1802.         info.addField(transparentKey, BOOLEAN_TYPE);
  1803.         info.addField(scrollToVisibleKey, BOOLEAN_TYPE);
  1804.         info.addField(defaultSelectedViewKey,OBJECT_TYPE);
  1805.  
  1806.         info.addField(menuViewKey, OBJECT_TYPE);
  1807.     }
  1808.  
  1809.     /** Encodes the InternalWindow instance.
  1810.       * @see Codable#encode
  1811.       */
  1812.     public void encode(Encoder encoder) throws CodingException {
  1813.         super.encode(encoder);
  1814.  
  1815.         encoder.encodeObject(ownerKey, (Codable)_owner);
  1816.         encoder.encodeObject(contentViewKey, _contentView);
  1817.         encoder.encodeObject(focusedViewKey, focusedView());
  1818.         encoder.encodeObject(closeButtonKey, _closeButton);
  1819.         encoder.encodeObject(titleFontKey, _titleFont);
  1820.  
  1821.         encoder.encodeString(titleKey, _title);
  1822.  
  1823.         encoder.encodeObject(borderKey, _border);
  1824.  
  1825.         encoder.encodeInt(layerKey, _layer);
  1826.         encoder.encodeInt(typeKey, _type);
  1827.  
  1828.         encoder.encodeBoolean(closeableKey, _closeable);
  1829.         encoder.encodeBoolean(resizableKey, _resizable);
  1830.         encoder.encodeBoolean(canBecomeMainKey, _canBecomeMain);
  1831.         encoder.encodeBoolean(containsDocumentKey, _containsDocument);
  1832.         encoder.encodeBoolean(onscreenKey, _onscreen);
  1833.         encoder.encodeBoolean(transparentKey, transparent);
  1834.         encoder.encodeBoolean(scrollToVisibleKey, scrollToVisible);
  1835.         encoder.encodeObject(defaultSelectedViewKey,_defaultSelectedView);
  1836.  
  1837.         encoder.encodeObject(menuViewKey, menuView);
  1838.     }
  1839.  
  1840.     /** Decodes the InternalWindow instance.
  1841.       * @see Codable#decode
  1842.       */
  1843.     public void decode(Decoder decoder) throws CodingException {
  1844.         int version = decoder.versionForClassName("netscape.application.TextField");
  1845.         super.decode(decoder);
  1846.  
  1847.         _owner = (WindowOwner)decoder.decodeObject(ownerKey);
  1848.         _contentView = (WindowContentView)decoder.decodeObject(contentViewKey);
  1849.         _focusedView = (View)decoder.decodeObject(focusedViewKey);
  1850.         _closeButton = (Button)decoder.decodeObject(closeButtonKey);
  1851.         _titleFont = (Font)decoder.decodeObject(titleFontKey);
  1852.  
  1853.         _title = decoder.decodeString(titleKey);
  1854.  
  1855.         _border = (Border)decoder.decodeObject(borderKey);
  1856.  
  1857.         _layer = decoder.decodeInt(layerKey);
  1858.         _type = decoder.decodeInt(typeKey);
  1859.  
  1860.         _closeable = decoder.decodeBoolean(closeableKey);
  1861.         _resizable = decoder.decodeBoolean(resizableKey);
  1862.         _canBecomeMain = decoder.decodeBoolean(canBecomeMainKey);
  1863.         _containsDocument = decoder.decodeBoolean(containsDocumentKey);
  1864.         _onscreen = decoder.decodeBoolean(onscreenKey);
  1865.         transparent = decoder.decodeBoolean(transparentKey);
  1866.         scrollToVisible = decoder.decodeBoolean(scrollToVisibleKey);
  1867.         if(version > 1) {
  1868.             _defaultSelectedView = (View) decoder.decodeObject(defaultSelectedViewKey);
  1869.         }
  1870.         if (version > 2) {
  1871.             menuView = (MenuView)decoder.decodeObject(menuViewKey);
  1872.         }
  1873.     }
  1874.  
  1875.     /** Finishes the InternalWindow instance decoding.  Initializes the Slider's value.
  1876.      * @see Codable#finishDecoding
  1877.      */
  1878.     public void finishDecoding() throws CodingException {
  1879.         super.finishDecoding();
  1880.         if(_closeButton != null)
  1881.             _closeButton.removeAllCommandsForKeys();
  1882.     }
  1883.  
  1884.     /** Returns the InternalWindow's string representation. */
  1885.     public String toString() {
  1886.         if (_title != null)
  1887.             return "InternalWindow (" + _title + ")";
  1888.         else
  1889.             return super.toString();
  1890.     }
  1891.  
  1892.     View ancestorWithDrawingBuffer() {
  1893.         if (drawingBuffer != null) {
  1894.             return this;
  1895.         }
  1896.  
  1897.         return null;
  1898.     }
  1899.  
  1900.     /** Overridden to return the InternalWindow.
  1901.       * @see View#window
  1902.       */
  1903.     public InternalWindow window() {
  1904.         return this;
  1905.     }
  1906.  
  1907.     /** @private */
  1908.     public Font font() {
  1909.         return _titleFont;
  1910.     }
  1911.  
  1912.     /** Implements InternalWindow's commands:
  1913.       * <ul>
  1914.       * <li>SHOW - calls the InternalWindow's <b>show()</b> method.
  1915.       * <li>HIDE - calls the InternalWindow's <b>hide()</b> method.
  1916.       * </ul>
  1917.       * Subclasses of InternalWindow should call super.performCommand() to
  1918.       * allow the default close Button to send its "hide" command.
  1919.       * @see #show
  1920.       * @see #hide
  1921.       */
  1922.     public void performCommand(String command, Object data) {
  1923.         if (SHOW.equals(command)) {
  1924.             show();
  1925.         } else if (HIDE.equals(command)) {
  1926.             hide();
  1927.         } else {
  1928.             throw new NoSuchMethodError("unknown command: " + command);
  1929.         }
  1930.     }
  1931.  
  1932.     /** Overriden to return true.  Internal windows are root for keyboard UI.
  1933.       *
  1934.       */
  1935.     public boolean hidesSubviewsFromKeyboard() {
  1936.         return true;
  1937.     }
  1938.  
  1939.     /** Set the default selected view, when the window becomes main.
  1940.       *
  1941.       */
  1942.     public void setDefaultSelectedView(View aView) {
  1943.         _defaultSelectedView = aView;
  1944.     }
  1945.  
  1946.     /** Returns the default selected view when the window become main
  1947.       *
  1948.       */
  1949.     public View defaultSelectedView() {
  1950.         return _defaultSelectedView;
  1951.     }
  1952.  
  1953.     /** Overriden to return true if the window is currently main
  1954.       *
  1955.       */
  1956.     public boolean canBecomeSelectedView() {
  1957.         if(isMain())
  1958.             return true;
  1959.         else
  1960.             return false;
  1961.     }
  1962.  
  1963.     boolean wantsKeyboardArrow() {
  1964.         return false;
  1965.     }
  1966. }
  1967.