0001: /*
0002: * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025: package java.awt;
0026:
0027: import java.awt.peer.FramePeer;
0028: import java.awt.event.*;
0029: import java.util.ArrayList;
0030: import java.util.Arrays;
0031: import java.util.List;
0032: import java.util.Vector;
0033: import java.io.Serializable;
0034: import java.io.ObjectOutputStream;
0035: import java.io.ObjectInputStream;
0036: import java.io.IOException;
0037: import sun.awt.AppContext;
0038: import sun.awt.SunToolkit;
0039: import java.lang.ref.WeakReference;
0040: import javax.accessibility.*;
0041:
0042: /**
0043: * A <code>Frame</code> is a top-level window with a title and a border.
0044: * <p>
0045: * The size of the frame includes any area designated for the
0046: * border. The dimensions of the border area may be obtained
0047: * using the <code>getInsets</code> method, however, since
0048: * these dimensions are platform-dependent, a valid insets
0049: * value cannot be obtained until the frame is made displayable
0050: * by either calling <code>pack</code> or <code>show</code>.
0051: * Since the border area is included in the overall size of the
0052: * frame, the border effectively obscures a portion of the frame,
0053: * constraining the area available for rendering and/or displaying
0054: * subcomponents to the rectangle which has an upper-left corner
0055: * location of <code>(insets.left, insets.top)</code>, and has a size of
0056: * <code>width - (insets.left + insets.right)</code> by
0057: * <code>height - (insets.top + insets.bottom)</code>.
0058: * <p>
0059: * The default layout for a frame is <code>BorderLayout</code>.
0060: * <p>
0061: * A frame may have its native decorations (i.e. <code>Frame</code>
0062: * and <code>Titlebar</code>) turned off
0063: * with <code>setUndecorated</code>. This can only be done while the frame
0064: * is not {@link Component#isDisplayable() displayable}.
0065: * <p>
0066: * In a multi-screen environment, you can create a <code>Frame</code>
0067: * on a different screen device by constructing the <code>Frame</code>
0068: * with {@link #Frame(GraphicsConfiguration)} or
0069: * {@link #Frame(String title, GraphicsConfiguration)}. The
0070: * <code>GraphicsConfiguration</code> object is one of the
0071: * <code>GraphicsConfiguration</code> objects of the target screen
0072: * device.
0073: * <p>
0074: * In a virtual device multi-screen environment in which the desktop
0075: * area could span multiple physical screen devices, the bounds of all
0076: * configurations are relative to the virtual-coordinate system. The
0077: * origin of the virtual-coordinate system is at the upper left-hand
0078: * corner of the primary physical screen. Depending on the location
0079: * of the primary screen in the virtual device, negative coordinates
0080: * are possible, as shown in the following figure.
0081: * <p>
0082: * <img src="doc-files/MultiScreen.gif"
0083: * alt="Diagram of virtual device encompassing three physical screens and one primary physical screen. The primary physical screen
0084: * shows (0,0) coords while a different physical screen shows (-80,-100) coords."
0085: * ALIGN=center HSPACE=10 VSPACE=7>
0086: * <p>
0087: * In such an environment, when calling <code>setLocation</code>,
0088: * you must pass a virtual coordinate to this method. Similarly,
0089: * calling <code>getLocationOnScreen</code> on a <code>Frame</code>
0090: * returns virtual device coordinates. Call the <code>getBounds</code>
0091: * method of a <code>GraphicsConfiguration</code> to find its origin in
0092: * the virtual coordinate system.
0093: * <p>
0094: * The following code sets the
0095: * location of the <code>Frame</code> at (10, 10) relative
0096: * to the origin of the physical screen of the corresponding
0097: * <code>GraphicsConfiguration</code>. If the bounds of the
0098: * <code>GraphicsConfiguration</code> is not taken into account, the
0099: * <code>Frame</code> location would be set at (10, 10) relative to the
0100: * virtual-coordinate system and would appear on the primary physical
0101: * screen, which might be different from the physical screen of the
0102: * specified <code>GraphicsConfiguration</code>.
0103: *
0104: * <pre>
0105: * Frame f = new Frame(GraphicsConfiguration gc);
0106: * Rectangle bounds = gc.getBounds();
0107: * f.setLocation(10 + bounds.x, 10 + bounds.y);
0108: * </pre>
0109: *
0110: * <p>
0111: * Frames are capable of generating the following types of
0112: * <code>WindowEvent</code>s:
0113: * <ul>
0114: * <li><code>WINDOW_OPENED</code>
0115: * <li><code>WINDOW_CLOSING</code>:
0116: * <br>If the program doesn't
0117: * explicitly hide or dispose the window while processing
0118: * this event, the window close operation is canceled.
0119: * <li><code>WINDOW_CLOSED</code>
0120: * <li><code>WINDOW_ICONIFIED</code>
0121: * <li><code>WINDOW_DEICONIFIED</code>
0122: * <li><code>WINDOW_ACTIVATED</code>
0123: * <li><code>WINDOW_DEACTIVATED</code>
0124: * <li><code>WINDOW_GAINED_FOCUS</code>
0125: * <li><code>WINDOW_LOST_FOCUS</code>
0126: * <li><code>WINDOW_STATE_CHANGED</code>
0127: * </ul>
0128: *
0129: * @version 1.169, 05/05/07
0130: * @author Sami Shaio
0131: * @see WindowEvent
0132: * @see Window#addWindowListener
0133: * @since JDK1.0
0134: */
0135: public class Frame extends Window implements MenuContainer {
0136:
0137: /* Note: These are being obsoleted; programs should use the Cursor class
0138: * variables going forward. See Cursor and Component.setCursor.
0139: */
0140:
0141: /**
0142: * @deprecated replaced by <code>Cursor.DEFAULT_CURSOR</code>.
0143: */
0144: @Deprecated
0145: public static final int DEFAULT_CURSOR = Cursor.DEFAULT_CURSOR;
0146:
0147: /**
0148: * @deprecated replaced by <code>Cursor.CROSSHAIR_CURSOR</code>.
0149: */
0150: @Deprecated
0151: public static final int CROSSHAIR_CURSOR = Cursor.CROSSHAIR_CURSOR;
0152:
0153: /**
0154: * @deprecated replaced by <code>Cursor.TEXT_CURSOR</code>.
0155: */
0156: @Deprecated
0157: public static final int TEXT_CURSOR = Cursor.TEXT_CURSOR;
0158:
0159: /**
0160: * @deprecated replaced by <code>Cursor.WAIT_CURSOR</code>.
0161: */
0162: @Deprecated
0163: public static final int WAIT_CURSOR = Cursor.WAIT_CURSOR;
0164:
0165: /**
0166: * @deprecated replaced by <code>Cursor.SW_RESIZE_CURSOR</code>.
0167: */
0168: @Deprecated
0169: public static final int SW_RESIZE_CURSOR = Cursor.SW_RESIZE_CURSOR;
0170:
0171: /**
0172: * @deprecated replaced by <code>Cursor.SE_RESIZE_CURSOR</code>.
0173: */
0174: @Deprecated
0175: public static final int SE_RESIZE_CURSOR = Cursor.SE_RESIZE_CURSOR;
0176:
0177: /**
0178: * @deprecated replaced by <code>Cursor.NW_RESIZE_CURSOR</code>.
0179: */
0180: @Deprecated
0181: public static final int NW_RESIZE_CURSOR = Cursor.NW_RESIZE_CURSOR;
0182:
0183: /**
0184: * @deprecated replaced by <code>Cursor.NE_RESIZE_CURSOR</code>.
0185: */
0186: @Deprecated
0187: public static final int NE_RESIZE_CURSOR = Cursor.NE_RESIZE_CURSOR;
0188:
0189: /**
0190: * @deprecated replaced by <code>Cursor.N_RESIZE_CURSOR</code>.
0191: */
0192: @Deprecated
0193: public static final int N_RESIZE_CURSOR = Cursor.N_RESIZE_CURSOR;
0194:
0195: /**
0196: * @deprecated replaced by <code>Cursor.S_RESIZE_CURSOR</code>.
0197: */
0198: @Deprecated
0199: public static final int S_RESIZE_CURSOR = Cursor.S_RESIZE_CURSOR;
0200:
0201: /**
0202: * @deprecated replaced by <code>Cursor.W_RESIZE_CURSOR</code>.
0203: */
0204: @Deprecated
0205: public static final int W_RESIZE_CURSOR = Cursor.W_RESIZE_CURSOR;
0206:
0207: /**
0208: * @deprecated replaced by <code>Cursor.E_RESIZE_CURSOR</code>.
0209: */
0210: @Deprecated
0211: public static final int E_RESIZE_CURSOR = Cursor.E_RESIZE_CURSOR;
0212:
0213: /**
0214: * @deprecated replaced by <code>Cursor.HAND_CURSOR</code>.
0215: */
0216: @Deprecated
0217: public static final int HAND_CURSOR = Cursor.HAND_CURSOR;
0218:
0219: /**
0220: * @deprecated replaced by <code>Cursor.MOVE_CURSOR</code>.
0221: */
0222: @Deprecated
0223: public static final int MOVE_CURSOR = Cursor.MOVE_CURSOR;
0224:
0225: /**
0226: * Frame is in the "normal" state. This symbolic constant names a
0227: * frame state with all state bits cleared.
0228: * @see #setExtendedState(int)
0229: * @see #getExtendedState
0230: */
0231: public static final int NORMAL = 0;
0232:
0233: /**
0234: * This state bit indicates that frame is iconified.
0235: * @see #setExtendedState(int)
0236: * @see #getExtendedState
0237: */
0238: public static final int ICONIFIED = 1;
0239:
0240: /**
0241: * This state bit indicates that frame is maximized in the
0242: * horizontal direction.
0243: * @see #setExtendedState(int)
0244: * @see #getExtendedState
0245: * @since 1.4
0246: */
0247: public static final int MAXIMIZED_HORIZ = 2;
0248:
0249: /**
0250: * This state bit indicates that frame is maximized in the
0251: * vertical direction.
0252: * @see #setExtendedState(int)
0253: * @see #getExtendedState
0254: * @since 1.4
0255: */
0256: public static final int MAXIMIZED_VERT = 4;
0257:
0258: /**
0259: * This state bit mask indicates that frame is fully maximized
0260: * (that is both horizontally and vertically). It is just a
0261: * convenience alias for
0262: * <code>MAXIMIZED_VERT | MAXIMIZED_HORIZ</code>.
0263: *
0264: * <p>Note that the correct test for frame being fully maximized is
0265: * <pre>
0266: * (state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH
0267: * </pre>
0268: *
0269: * <p>To test is frame is maximized in <em>some</em> direction use
0270: * <pre>
0271: * (state & Frame.MAXIMIZED_BOTH) != 0
0272: * </pre>
0273: *
0274: * @see #setExtendedState(int)
0275: * @see #getExtendedState
0276: * @since 1.4
0277: */
0278: public static final int MAXIMIZED_BOTH = MAXIMIZED_VERT
0279: | MAXIMIZED_HORIZ;
0280:
0281: /**
0282: * Maximized bounds for this frame.
0283: * @see #setMaximizedBounds(Rectangle)
0284: * @see #getMaximizedBounds
0285: * @serial
0286: * @since 1.4
0287: */
0288: Rectangle maximizedBounds;
0289:
0290: /**
0291: * This is the title of the frame. It can be changed
0292: * at any time. <code>title</code> can be null and if
0293: * this is the case the <code>title</code> = "".
0294: *
0295: * @serial
0296: * @see #getTitle
0297: * @see #setTitle(String)
0298: */
0299: String title = "Untitled";
0300:
0301: /**
0302: * The frames menubar. If <code>menuBar</code> = null
0303: * the frame will not have a menubar.
0304: *
0305: * @serial
0306: * @see #getMenuBar
0307: * @see #setMenuBar(MenuBar)
0308: */
0309: MenuBar menuBar;
0310:
0311: /**
0312: * This field indicates whether the frame is resizable.
0313: * This property can be changed at any time.
0314: * <code>resizable</code> will be true if the frame is
0315: * resizable, otherwise it will be false.
0316: *
0317: * @serial
0318: * @see #isResizable()
0319: */
0320: boolean resizable = true;
0321:
0322: /**
0323: * This field indicates whether the frame is undecorated.
0324: * This property can only be changed while the frame is not displayable.
0325: * <code>undecorated</code> will be true if the frame is
0326: * undecorated, otherwise it will be false.
0327: *
0328: * @serial
0329: * @see #setUndecorated(boolean)
0330: * @see #isUndecorated()
0331: * @see Component#isDisplayable()
0332: * @since 1.4
0333: */
0334: boolean undecorated = false;
0335:
0336: /**
0337: * <code>mbManagement</code> is only used by the Motif implementation.
0338: *
0339: * @serial
0340: */
0341: boolean mbManagement = false; /* used only by the Motif impl. */
0342:
0343: // XXX: uwe: abuse old field for now
0344: // will need to take care of serialization
0345: private int state = NORMAL;
0346:
0347: /*
0348: * The Windows owned by the Frame.
0349: * Note: in 1.2 this has been superceded by Window.ownedWindowList
0350: *
0351: * @serial
0352: * @see java.awt.Window#ownedWindowList
0353: */
0354: Vector ownedWindows;
0355:
0356: private static final String base = "frame";
0357: private static int nameCounter = 0;
0358:
0359: /*
0360: * JDK 1.1 serialVersionUID
0361: */
0362: private static final long serialVersionUID = 2673458971256075116L;
0363:
0364: static {
0365: /* ensure that the necessary native libraries are loaded */
0366: Toolkit.loadLibraries();
0367: if (!GraphicsEnvironment.isHeadless()) {
0368: initIDs();
0369: }
0370: }
0371:
0372: /**
0373: * Constructs a new instance of <code>Frame</code> that is
0374: * initially invisible. The title of the <code>Frame</code>
0375: * is empty.
0376: * @exception HeadlessException when
0377: * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0378: * @see java.awt.GraphicsEnvironment#isHeadless()
0379: * @see Component#setSize
0380: * @see Component#setVisible(boolean)
0381: */
0382: public Frame() throws HeadlessException {
0383: this ("");
0384: }
0385:
0386: /**
0387: * Constructs a new, initially invisible {@code Frame} with the
0388: * specified {@code GraphicsConfiguration}.
0389: *
0390: * @param gc the <code>GraphicsConfiguration</code>
0391: * of the target screen device. If <code>gc</code>
0392: * is <code>null</code>, the system default
0393: * <code>GraphicsConfiguration</code> is assumed.
0394: * @exception IllegalArgumentException if
0395: * <code>gc</code> is not from a screen device.
0396: * @exception HeadlessException when
0397: * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0398: * @see java.awt.GraphicsEnvironment#isHeadless()
0399: * @since 1.3
0400: */
0401: public Frame(GraphicsConfiguration gc) {
0402: this ("", gc);
0403: }
0404:
0405: /**
0406: * Constructs a new, initially invisible <code>Frame</code> object
0407: * with the specified title.
0408: * @param title the title to be displayed in the frame's border.
0409: * A <code>null</code> value
0410: * is treated as an empty string, "".
0411: * @exception HeadlessException when
0412: * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0413: * @see java.awt.GraphicsEnvironment#isHeadless()
0414: * @see java.awt.Component#setSize
0415: * @see java.awt.Component#setVisible(boolean)
0416: * @see java.awt.GraphicsConfiguration#getBounds
0417: */
0418: public Frame(String title) throws HeadlessException {
0419: init(title, null);
0420: }
0421:
0422: /**
0423: * Constructs a new, initially invisible <code>Frame</code> object
0424: * with the specified title and a
0425: * <code>GraphicsConfiguration</code>.
0426: * @param title the title to be displayed in the frame's border.
0427: * A <code>null</code> value
0428: * is treated as an empty string, "".
0429: * @param gc the <code>GraphicsConfiguration</code>
0430: * of the target screen device. If <code>gc</code> is
0431: * <code>null</code>, the system default
0432: * <code>GraphicsConfiguration</code> is assumed.
0433: * @exception IllegalArgumentException if <code>gc</code>
0434: * is not from a screen device.
0435: * @exception HeadlessException when
0436: * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0437: * @see java.awt.GraphicsEnvironment#isHeadless()
0438: * @see java.awt.Component#setSize
0439: * @see java.awt.Component#setVisible(boolean)
0440: * @see java.awt.GraphicsConfiguration#getBounds
0441: * @since 1.3
0442: */
0443: public Frame(String title, GraphicsConfiguration gc) {
0444: super (gc);
0445: init(title, gc);
0446: }
0447:
0448: private void init(String title, GraphicsConfiguration gc) {
0449: this .title = title;
0450: SunToolkit.checkAndSetPolicy(this , false);
0451: }
0452:
0453: /**
0454: * Construct a name for this component. Called by getName() when the
0455: * name is null.
0456: */
0457: String constructComponentName() {
0458: synchronized (Frame.class) {
0459: return base + nameCounter++;
0460: }
0461: }
0462:
0463: /**
0464: * Makes this Frame displayable by connecting it to
0465: * a native screen resource. Making a frame displayable will
0466: * cause any of its children to be made displayable.
0467: * This method is called internally by the toolkit and should
0468: * not be called directly by programs.
0469: * @see Component#isDisplayable
0470: * @see #removeNotify
0471: */
0472: public void addNotify() {
0473: synchronized (getTreeLock()) {
0474: if (peer == null) {
0475: peer = getToolkit().createFrame(this );
0476: }
0477: FramePeer p = (FramePeer) peer;
0478: MenuBar menuBar = this .menuBar;
0479: if (menuBar != null) {
0480: mbManagement = true;
0481: menuBar.addNotify();
0482: p.setMenuBar(menuBar);
0483: }
0484: p.setMaximizedBounds(maximizedBounds);
0485: super .addNotify();
0486: }
0487: }
0488:
0489: /**
0490: * Gets the title of the frame. The title is displayed in the
0491: * frame's border.
0492: * @return the title of this frame, or an empty string ("")
0493: * if this frame doesn't have a title.
0494: * @see #setTitle(String)
0495: */
0496: public String getTitle() {
0497: return title;
0498: }
0499:
0500: /**
0501: * Sets the title for this frame to the specified string.
0502: * @param title the title to be displayed in the frame's border.
0503: * A <code>null</code> value
0504: * is treated as an empty string, "".
0505: * @see #getTitle
0506: */
0507: public void setTitle(String title) {
0508: String oldTitle = this .title;
0509: if (title == null) {
0510: title = "";
0511: }
0512:
0513: synchronized (this ) {
0514: this .title = title;
0515: FramePeer peer = (FramePeer) this .peer;
0516: if (peer != null) {
0517: peer.setTitle(title);
0518: }
0519: }
0520: firePropertyChange("title", oldTitle, title);
0521: }
0522:
0523: /**
0524: * Returns the image to be displayed as the icon for this frame.
0525: * <p>
0526: * This method is obsolete and kept for backward compatibility
0527: * only. Use {@link Window#getIconImages Window.getIconImages()} instead.
0528: * <p>
0529: * If a list of several images was specified as a Window's icon,
0530: * this method will return the first item of the list.
0531: *
0532: * @return the icon image for this frame, or <code>null</code>
0533: * if this frame doesn't have an icon image.
0534: * @see #setIconImage(Image)
0535: * @see Window#getIconImages()
0536: * @see Window#setIconImages
0537: */
0538: public Image getIconImage() {
0539: java.util.List<Image> icons = this .icons;
0540: if (icons != null) {
0541: if (icons.size() > 0) {
0542: return icons.get(0);
0543: }
0544: }
0545: return null;
0546: }
0547:
0548: /**
0549: * {@inheritDoc}
0550: */
0551: public void setIconImage(Image image) {
0552: super .setIconImage(image);
0553: }
0554:
0555: /**
0556: * Gets the menu bar for this frame.
0557: * @return the menu bar for this frame, or <code>null</code>
0558: * if this frame doesn't have a menu bar.
0559: * @see #setMenuBar(MenuBar)
0560: */
0561: public MenuBar getMenuBar() {
0562: return menuBar;
0563: }
0564:
0565: /**
0566: * Sets the menu bar for this frame to the specified menu bar.
0567: * @param mb the menu bar being set.
0568: * If this parameter is <code>null</code> then any
0569: * existing menu bar on this frame is removed.
0570: * @see #getMenuBar
0571: */
0572: public void setMenuBar(MenuBar mb) {
0573: synchronized (getTreeLock()) {
0574: if (menuBar == mb) {
0575: return;
0576: }
0577: if ((mb != null) && (mb.parent != null)) {
0578: mb.parent.remove(mb);
0579: }
0580: if (menuBar != null) {
0581: remove(menuBar);
0582: }
0583: menuBar = mb;
0584: if (menuBar != null) {
0585: menuBar.parent = this ;
0586:
0587: FramePeer peer = (FramePeer) this .peer;
0588: if (peer != null) {
0589: mbManagement = true;
0590: menuBar.addNotify();
0591: if (valid) {
0592: invalidate();
0593: }
0594: peer.setMenuBar(menuBar);
0595: }
0596: }
0597: }
0598: }
0599:
0600: /**
0601: * Indicates whether this frame is resizable by the user.
0602: * By default, all frames are initially resizable.
0603: * @return <code>true</code> if the user can resize this frame;
0604: * <code>false</code> otherwise.
0605: * @see java.awt.Frame#setResizable(boolean)
0606: */
0607: public boolean isResizable() {
0608: return resizable;
0609: }
0610:
0611: /**
0612: * Sets whether this frame is resizable by the user.
0613: * @param resizable <code>true</code> if this frame is resizable;
0614: * <code>false</code> otherwise.
0615: * @see java.awt.Frame#isResizable
0616: */
0617: public void setResizable(boolean resizable) {
0618: boolean oldResizable = this .resizable;
0619: boolean testvalid = false;
0620:
0621: synchronized (this ) {
0622: this .resizable = resizable;
0623: FramePeer peer = (FramePeer) this .peer;
0624: if (peer != null) {
0625: peer.setResizable(resizable);
0626: testvalid = true;
0627: }
0628: }
0629:
0630: // On some platforms, changing the resizable state affects
0631: // the insets of the Frame. If we could, we'd call invalidate()
0632: // from the peer, but we need to guarantee that we're not holding
0633: // the Frame lock when we call invalidate().
0634: if (testvalid && valid) {
0635: invalidate();
0636: }
0637: firePropertyChange("resizable", oldResizable, resizable);
0638: }
0639:
0640: /**
0641: * Sets the state of this frame (obsolete).
0642: * <p>
0643: * In older versions of JDK a frame state could only be NORMAL or
0644: * ICONIFIED. Since JDK 1.4 set of supported frame states is
0645: * expanded and frame state is represented as a bitwise mask.
0646: * <p>
0647: * For compatibility with old programs this method still accepts
0648: * <code>Frame.NORMAL</code> and <code>Frame.ICONIFIED</code> but
0649: * it only changes the iconic state of the frame, other aspects of
0650: * frame state are not affected by this method.
0651: *
0652: * @param state either <code>Frame.NORMAL</code> or
0653: * <code>Frame.ICONIFIED</code>.
0654: * @see #getState
0655: * @see #setExtendedState(int)
0656: */
0657: public synchronized void setState(int state) {
0658: int current = getExtendedState();
0659: if (state == ICONIFIED && (current & ICONIFIED) == 0) {
0660: setExtendedState(current | ICONIFIED);
0661: } else if (state == NORMAL && (current & ICONIFIED) != 0) {
0662: setExtendedState(current & ~ICONIFIED);
0663: }
0664: }
0665:
0666: /**
0667: * Sets the state of this frame. The state is
0668: * represented as a bitwise mask.
0669: * <ul>
0670: * <li><code>NORMAL</code>
0671: * <br>Indicates that no state bits are set.
0672: * <li><code>ICONIFIED</code>
0673: * <li><code>MAXIMIZED_HORIZ</code>
0674: * <li><code>MAXIMIZED_VERT</code>
0675: * <li><code>MAXIMIZED_BOTH</code>
0676: * <br>Concatenates <code>MAXIMIZED_HORIZ</code>
0677: * and <code>MAXIMIZED_VERT</code>.
0678: * </ul>
0679: * <p>Note that if the state is not supported on a
0680: * given platform, nothing will happen. The application
0681: * may determine if a specific state is available via
0682: * the <code>java.awt.Toolkit.isFrameStateSupported(int state)</code>
0683: * method.
0684: *
0685: * @param state a bitwise mask of frame state constants
0686: * @see #getExtendedState
0687: * @see java.awt.Toolkit#isFrameStateSupported(int)
0688: * @since 1.4
0689: */
0690: public synchronized void setExtendedState(int state) {
0691: if (!isFrameStateSupported(state)) {
0692: return;
0693: }
0694: this .state = state;
0695: FramePeer peer = (FramePeer) this .peer;
0696: if (peer != null) {
0697: peer.setState(state);
0698: }
0699: }
0700:
0701: private boolean isFrameStateSupported(int state) {
0702: if (!getToolkit().isFrameStateSupported(state)) {
0703: // * Toolkit.isFrameStateSupported returns always false
0704: // on compound state even if all parts are supported;
0705: // * if part of state is not supported, state is not supported;
0706: // * MAXIMIZED_BOTH is not a compound state.
0707: if (((state & ICONIFIED) != 0)
0708: && !getToolkit().isFrameStateSupported(ICONIFIED)) {
0709: return false;
0710: } else {
0711: state &= ~ICONIFIED;
0712: }
0713: return getToolkit().isFrameStateSupported(state);
0714: }
0715: return true;
0716: }
0717:
0718: /**
0719: * Gets the state of this frame (obsolete).
0720: * <p>
0721: * In older versions of JDK a frame state could only be NORMAL or
0722: * ICONIFIED. Since JDK 1.4 set of supported frame states is
0723: * expanded and frame state is represented as a bitwise mask.
0724: * <p>
0725: * For compatibility with old programs this method still returns
0726: * <code>Frame.NORMAL</code> and <code>Frame.ICONIFIED</code> but
0727: * it only reports the iconic state of the frame, other aspects of
0728: * frame state are not reported by this method.
0729: *
0730: * @return <code>Frame.NORMAL</code> or <code>Frame.ICONIFIED</code>.
0731: * @see #setState(int)
0732: * @see #getExtendedState
0733: */
0734: public synchronized int getState() {
0735: return (getExtendedState() & ICONIFIED) != 0 ? ICONIFIED
0736: : NORMAL;
0737: }
0738:
0739: /**
0740: * Gets the state of this frame. The state is
0741: * represented as a bitwise mask.
0742: * <ul>
0743: * <li><code>NORMAL</code>
0744: * <br>Indicates that no state bits are set.
0745: * <li><code>ICONIFIED</code>
0746: * <li><code>MAXIMIZED_HORIZ</code>
0747: * <li><code>MAXIMIZED_VERT</code>
0748: * <li><code>MAXIMIZED_BOTH</code>
0749: * <br>Concatenates <code>MAXIMIZED_HORIZ</code>
0750: * and <code>MAXIMIZED_VERT</code>.
0751: * </ul>
0752: *
0753: * @return a bitwise mask of frame state constants
0754: * @see #setExtendedState(int)
0755: * @since 1.4
0756: */
0757: public synchronized int getExtendedState() {
0758: FramePeer peer = (FramePeer) this .peer;
0759: if (peer != null) {
0760: state = peer.getState();
0761: }
0762: return state;
0763: }
0764:
0765: /**
0766: * Sets the maximized bounds for this frame.
0767: * <p>
0768: * When a frame is in maximized state the system supplies some
0769: * defaults bounds. This method allows some or all of those
0770: * system supplied values to be overridden.
0771: * <p>
0772: * If <code>bounds</code> is <code>null</code>, accept bounds
0773: * supplied by the system. If non-<code>null</code> you can
0774: * override some of the system supplied values while accepting
0775: * others by setting those fields you want to accept from system
0776: * to <code>Integer.MAX_VALUE</code>.
0777: * <p>
0778: * On some systems only the size portion of the bounds is taken
0779: * into account.
0780: *
0781: * @param bounds bounds for the maximized state
0782: * @see #getMaximizedBounds()
0783: * @since 1.4
0784: */
0785: public synchronized void setMaximizedBounds(Rectangle bounds) {
0786: this .maximizedBounds = bounds;
0787: FramePeer peer = (FramePeer) this .peer;
0788: if (peer != null) {
0789: peer.setMaximizedBounds(bounds);
0790: }
0791: }
0792:
0793: /**
0794: * Gets maximized bounds for this frame.
0795: * Some fields may contain <code>Integer.MAX_VALUE</code> to indicate
0796: * that system supplied values for this field must be used.
0797: *
0798: * @return maximized bounds for this frame; may be <code>null</code>
0799: * @see #setMaximizedBounds(Rectangle)
0800: * @since 1.4
0801: */
0802: public Rectangle getMaximizedBounds() {
0803: return maximizedBounds;
0804: }
0805:
0806: /**
0807: * Disables or enables decorations for this frame.
0808: * This method can only be called while the frame is not displayable.
0809: * @param undecorated <code>true</code> if no frame decorations are
0810: * to be enabled;
0811: * <code>false</code> if frame decorations are to be enabled.
0812: * @throws <code>IllegalComponentStateException</code> if the frame
0813: * is displayable.
0814: * @see #isUndecorated
0815: * @see Component#isDisplayable
0816: * @see javax.swing.JFrame#setDefaultLookAndFeelDecorated(boolean)
0817: * @since 1.4
0818: */
0819: public void setUndecorated(boolean undecorated) {
0820: /* Make sure we don't run in the middle of peer creation.*/
0821: synchronized (getTreeLock()) {
0822: if (isDisplayable()) {
0823: throw new IllegalComponentStateException(
0824: "The frame is displayable.");
0825: }
0826: this .undecorated = undecorated;
0827: }
0828: }
0829:
0830: /**
0831: * Indicates whether this frame is undecorated.
0832: * By default, all frames are initially decorated.
0833: * @return <code>true</code> if frame is undecorated;
0834: * <code>false</code> otherwise.
0835: * @see java.awt.Frame#setUndecorated(boolean)
0836: * @since 1.4
0837: */
0838: public boolean isUndecorated() {
0839: return undecorated;
0840: }
0841:
0842: /**
0843: * Removes the specified menu bar from this frame.
0844: * @param m the menu component to remove.
0845: * If <code>m</code> is <code>null</code>, then
0846: * no action is taken
0847: */
0848: public void remove(MenuComponent m) {
0849: if (m == null) {
0850: return;
0851: }
0852: synchronized (getTreeLock()) {
0853: if (m == menuBar) {
0854: menuBar = null;
0855: FramePeer peer = (FramePeer) this .peer;
0856: if (peer != null) {
0857: mbManagement = true;
0858: if (valid) {
0859: invalidate();
0860: }
0861: peer.setMenuBar(null);
0862: m.removeNotify();
0863: }
0864: m.parent = null;
0865: } else {
0866: super .remove(m);
0867: }
0868: }
0869: }
0870:
0871: /**
0872: * Makes this Frame undisplayable by removing its connection
0873: * to its native screen resource. Making a Frame undisplayable
0874: * will cause any of its children to be made undisplayable.
0875: * This method is called by the toolkit internally and should
0876: * not be called directly by programs.
0877: * @see Component#isDisplayable
0878: * @see #addNotify
0879: */
0880: public void removeNotify() {
0881: synchronized (getTreeLock()) {
0882: FramePeer peer = (FramePeer) this .peer;
0883: if (peer != null) {
0884: // get the latest Frame state before disposing
0885: getState();
0886:
0887: if (menuBar != null) {
0888: mbManagement = true;
0889: peer.setMenuBar(null);
0890: menuBar.removeNotify();
0891: }
0892: }
0893: super .removeNotify();
0894: }
0895: }
0896:
0897: void postProcessKeyEvent(KeyEvent e) {
0898: if (menuBar != null && menuBar.handleShortcut(e)) {
0899: e.consume();
0900: return;
0901: }
0902: super .postProcessKeyEvent(e);
0903: }
0904:
0905: /**
0906: * Returns a string representing the state of this <code>Frame</code>.
0907: * This method is intended to be used only for debugging purposes, and the
0908: * content and format of the returned string may vary between
0909: * implementations. The returned string may be empty but may not be
0910: * <code>null</code>.
0911: *
0912: * @return the parameter string of this frame
0913: */
0914: protected String paramString() {
0915: String str = super .paramString();
0916: if (title != null) {
0917: str += ",title=" + title;
0918: }
0919: if (resizable) {
0920: str += ",resizable";
0921: }
0922: getExtendedState(); // sync with peer
0923: if (state == NORMAL) {
0924: str += ",normal";
0925: } else {
0926: if ((state & ICONIFIED) != 0) {
0927: str += ",iconified";
0928: }
0929: if ((state & MAXIMIZED_BOTH) == MAXIMIZED_BOTH) {
0930: str += ",maximized";
0931: } else if ((state & MAXIMIZED_HORIZ) != 0) {
0932: str += ",maximized_horiz";
0933: } else if ((state & MAXIMIZED_VERT) != 0) {
0934: str += ",maximized_vert";
0935: }
0936: }
0937: return str;
0938: }
0939:
0940: /**
0941: * @deprecated As of JDK version 1.1,
0942: * replaced by <code>Component.setCursor(Cursor)</code>.
0943: */
0944: @Deprecated
0945: public void setCursor(int cursorType) {
0946: if (cursorType < DEFAULT_CURSOR || cursorType > MOVE_CURSOR) {
0947: throw new IllegalArgumentException("illegal cursor type");
0948: }
0949: setCursor(Cursor.getPredefinedCursor(cursorType));
0950: }
0951:
0952: /**
0953: * @deprecated As of JDK version 1.1,
0954: * replaced by <code>Component.getCursor()</code>.
0955: */
0956: @Deprecated
0957: public int getCursorType() {
0958: return (getCursor().getType());
0959: }
0960:
0961: /**
0962: * Returns an array of all {@code Frame}s created by this application.
0963: * If called from an applet, the array includes only the {@code Frame}s
0964: * accessible by that applet.
0965: * <p>
0966: * <b>Warning:</b> this method may return system created frames, such
0967: * as a shared, hidden frame which is used by Swing. Applications
0968: * should not assume the existence of these frames, nor should an
0969: * application assume anything about these frames such as component
0970: * positions, <code>LayoutManager</code>s or serialization.
0971: * <p>
0972: * <b>Note</b>: To obtain a list of all ownerless windows, including
0973: * ownerless {@code Dialog}s (introduced in release 1.6), use {@link
0974: * Window#getOwnerlessWindows Window.getOwnerlessWindows}.
0975: *
0976: * @see Window#getWindows()
0977: * @see Window#getOwnerlessWindows
0978: *
0979: * @since 1.2
0980: */
0981: public static Frame[] getFrames() {
0982: Window[] allWindows = Window.getWindows();
0983:
0984: int frameCount = 0;
0985: for (Window w : allWindows) {
0986: if (w instanceof Frame) {
0987: frameCount++;
0988: }
0989: }
0990:
0991: Frame[] frames = new Frame[frameCount];
0992: int c = 0;
0993: for (Window w : allWindows) {
0994: if (w instanceof Frame) {
0995: frames[c++] = (Frame) w;
0996: }
0997: }
0998:
0999: return frames;
1000: }
1001:
1002: /* Serialization support. If there's a MenuBar we restore
1003: * its (transient) parent field here. Likewise for top level
1004: * windows that are "owned" by this frame.
1005: */
1006:
1007: /**
1008: * <code>Frame</code>'s Serialized Data Version.
1009: *
1010: * @serial
1011: */
1012: private int frameSerializedDataVersion = 1;
1013:
1014: /**
1015: * Writes default serializable fields to stream. Writes
1016: * an optional serializable icon <code>Image</code>, which is
1017: * available as of 1.4.
1018: *
1019: * @param s the <code>ObjectOutputStream</code> to write
1020: * @serialData an optional icon <code>Image</code>
1021: * @see java.awt.Image
1022: * @see #getIconImage
1023: * @see #setIconImage(Image)
1024: * @see #readObject(ObjectInputStream)
1025: */
1026: private void writeObject(ObjectOutputStream s) throws IOException {
1027: s.defaultWriteObject();
1028: if (icons != null && icons.size() > 0) {
1029: Image icon1 = icons.get(0);
1030: if (icon1 instanceof Serializable) {
1031: s.writeObject(icon1);
1032: return;
1033: }
1034: }
1035: s.writeObject(null);
1036: }
1037:
1038: /**
1039: * Reads the <code>ObjectInputStream</code>. Tries
1040: * to read an icon <code>Image</code>, which is optional
1041: * data available as of 1.4. If an icon <code>Image</code>
1042: * is not available, but anything other than an EOF
1043: * is detected, an <code>OptionalDataException</code>
1044: * will be thrown.
1045: * Unrecognized keys or values will be ignored.
1046: *
1047: * @param s the <code>ObjectInputStream</code> to read
1048: * @exception java.io.OptionalDataException if an icon <code>Image</code>
1049: * is not available, but anything other than an EOF
1050: * is detected
1051: * @exception HeadlessException if
1052: * <code>GraphicsEnvironment.isHeadless</code> returns
1053: * <code>true</code>
1054: * @see java.awt.GraphicsEnvironment#isHeadless()
1055: * @see java.awt.Image
1056: * @see #getIconImage
1057: * @see #setIconImage(Image)
1058: * @see #writeObject(ObjectOutputStream)
1059: */
1060: private void readObject(ObjectInputStream s)
1061: throws ClassNotFoundException, IOException,
1062: HeadlessException {
1063: // HeadlessException is thrown by Window's readObject
1064: s.defaultReadObject();
1065: try {
1066: Image icon = (Image) s.readObject();
1067: if (icons == null) {
1068: icons = new ArrayList<Image>();
1069: icons.add(icon);
1070: }
1071: } catch (java.io.OptionalDataException e) {
1072: // pre-1.4 instances will not have this optional data.
1073: // 1.6 and later instances serialize icons in the Window class
1074: // e.eof will be true to indicate that there is no more
1075: // data available for this object.
1076:
1077: // If e.eof is not true, throw the exception as it
1078: // might have been caused by unrelated reasons.
1079: if (!e.eof) {
1080: throw (e);
1081: }
1082: }
1083:
1084: if (menuBar != null)
1085: menuBar.parent = this ;
1086:
1087: // Ensure 1.1 serialized Frames can read & hook-up
1088: // owned windows properly
1089: //
1090: if (ownedWindows != null) {
1091: for (int i = 0; i < ownedWindows.size(); i++) {
1092: connectOwnedWindow((Window) ownedWindows.elementAt(i));
1093: }
1094: ownedWindows = null;
1095: }
1096: }
1097:
1098: /**
1099: * Initialize JNI field and method IDs
1100: */
1101: private static native void initIDs();
1102:
1103: /*
1104: * --- Accessibility Support ---
1105: *
1106: */
1107:
1108: /**
1109: * Gets the AccessibleContext associated with this Frame.
1110: * For frames, the AccessibleContext takes the form of an
1111: * AccessibleAWTFrame.
1112: * A new AccessibleAWTFrame instance is created if necessary.
1113: *
1114: * @return an AccessibleAWTFrame that serves as the
1115: * AccessibleContext of this Frame
1116: * @since 1.3
1117: */
1118: public AccessibleContext getAccessibleContext() {
1119: if (accessibleContext == null) {
1120: accessibleContext = new AccessibleAWTFrame();
1121: }
1122: return accessibleContext;
1123: }
1124:
1125: /**
1126: * This class implements accessibility support for the
1127: * <code>Frame</code> class. It provides an implementation of the
1128: * Java Accessibility API appropriate to frame user-interface elements.
1129: * @since 1.3
1130: */
1131: protected class AccessibleAWTFrame extends AccessibleAWTWindow {
1132: /*
1133: * JDK 1.3 serialVersionUID
1134: */
1135: private static final long serialVersionUID = -6172960752956030250L;
1136:
1137: /**
1138: * Get the role of this object.
1139: *
1140: * @return an instance of AccessibleRole describing the role of the
1141: * object
1142: * @see AccessibleRole
1143: */
1144: public AccessibleRole getAccessibleRole() {
1145: return AccessibleRole.FRAME;
1146: }
1147:
1148: /**
1149: * Get the state of this object.
1150: *
1151: * @return an instance of AccessibleStateSet containing the current
1152: * state set of the object
1153: * @see AccessibleState
1154: */
1155: public AccessibleStateSet getAccessibleStateSet() {
1156: AccessibleStateSet states = super .getAccessibleStateSet();
1157: if (getFocusOwner() != null) {
1158: states.add(AccessibleState.ACTIVE);
1159: }
1160: if (isResizable()) {
1161: states.add(AccessibleState.RESIZABLE);
1162: }
1163: return states;
1164: }
1165:
1166: } // inner class AccessibleAWTFrame
1167:
1168: }
|