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