1 /*
   2  * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.awt;
  26 
  27 import java.awt.event.KeyEvent;
  28 import java.awt.event.WindowEvent;
  29 import java.awt.peer.FramePeer;
  30 import java.io.IOException;
  31 import java.io.ObjectInputStream;
  32 import java.io.ObjectOutputStream;
  33 import java.io.Serializable;
  34 import java.util.ArrayList;
  35 import java.util.Vector;
  36 
  37 import javax.accessibility.AccessibleContext;
  38 import javax.accessibility.AccessibleRole;
  39 import javax.accessibility.AccessibleState;
  40 import javax.accessibility.AccessibleStateSet;
  41 import javax.swing.WindowConstants;
  42 
  43 import sun.awt.AWTAccessor;
  44 import sun.awt.SunToolkit;
  45 
  46 /**
  47  * A {@code Frame} is a top-level window with a title and a border.
  48  * <p>
  49  * The size of the frame includes any area designated for the
  50  * border.  The dimensions of the border area may be obtained
  51  * using the {@code getInsets} method, however, since
  52  * these dimensions are platform-dependent, a valid insets
  53  * value cannot be obtained until the frame is made displayable
  54  * by either calling {@code pack} or {@code show}.
  55  * Since the border area is included in the overall size of the
  56  * frame, the border effectively obscures a portion of the frame,
  57  * constraining the area available for rendering and/or displaying
  58  * subcomponents to the rectangle which has an upper-left corner
  59  * location of {@code (insets.left, insets.top)}, and has a size of
  60  * {@code width - (insets.left + insets.right)} by
  61  * {@code height - (insets.top + insets.bottom)}.
  62  * <p>
  63  * The default layout for a frame is {@code BorderLayout}.
  64  * <p>
  65  * A frame may have its native decorations (i.e. {@code Frame}
  66  * and {@code Titlebar}) turned off
  67  * with {@code setUndecorated}. This can only be done while the frame
  68  * is not {@link Component#isDisplayable() displayable}.
  69  * <p>
  70  * In a multi-screen environment, you can create a {@code Frame}
  71  * on a different screen device by constructing the {@code Frame}
  72  * with {@link #Frame(GraphicsConfiguration)} or
  73  * {@link #Frame(String title, GraphicsConfiguration)}.  The
  74  * {@code GraphicsConfiguration} object is one of the
  75  * {@code GraphicsConfiguration} objects of the target screen
  76  * device.
  77  * <p>
  78  * In a virtual device multi-screen environment in which the desktop
  79  * area could span multiple physical screen devices, the bounds of all
  80  * configurations are relative to the virtual-coordinate system.  The
  81  * origin of the virtual-coordinate system is at the upper left-hand
  82  * corner of the primary physical screen.  Depending on the location
  83  * of the primary screen in the virtual device, negative coordinates
  84  * are possible, as shown in the following figure.
  85  * <p>
  86  * <img src="doc-files/MultiScreen.gif" alt="Diagram of virtual device
  87  * encompassing three physical screens and one primary physical screen. The
  88  * primary physical screen shows (0,0) coords while a different physical screen
  89  * shows (-80,-100) coords." style="margin: 7px 10px;">
  90  * <p>
  91  * In such an environment, when calling {@code setLocation},
  92  * you must pass a virtual coordinate to this method.  Similarly,
  93  * calling {@code getLocationOnScreen} on a {@code Frame}
  94  * returns virtual device coordinates.  Call the {@code getBounds}
  95  * method of a {@code GraphicsConfiguration} to find its origin in
  96  * the virtual coordinate system.
  97  * <p>
  98  * The following code sets the
  99  * location of the {@code Frame} at (10, 10) relative
 100  * to the origin of the physical screen of the corresponding
 101  * {@code GraphicsConfiguration}.  If the bounds of the
 102  * {@code GraphicsConfiguration} is not taken into account, the
 103  * {@code Frame} location would be set at (10, 10) relative to the
 104  * virtual-coordinate system and would appear on the primary physical
 105  * screen, which might be different from the physical screen of the
 106  * specified {@code GraphicsConfiguration}.
 107  *
 108  * <pre>
 109  *      Frame f = new Frame(GraphicsConfiguration gc);
 110  *      Rectangle bounds = gc.getBounds();
 111  *      f.setLocation(10 + bounds.x, 10 + bounds.y);
 112  * </pre>
 113  *
 114  * <p>
 115  * Frames are capable of generating the following types of
 116  * {@code WindowEvent}s:
 117  * <ul>
 118  * <li>{@code WINDOW_OPENED}
 119  * <li>{@code WINDOW_CLOSING}:
 120  *     <br>If the program doesn't
 121  *     explicitly hide or dispose the window while processing
 122  *     this event, the window close operation is canceled.
 123  * <li>{@code WINDOW_CLOSED}
 124  * <li>{@code WINDOW_ICONIFIED}
 125  * <li>{@code WINDOW_DEICONIFIED}
 126  * <li>{@code WINDOW_ACTIVATED}
 127  * <li>{@code WINDOW_DEACTIVATED}
 128  * <li>{@code WINDOW_GAINED_FOCUS}
 129  * <li>{@code WINDOW_LOST_FOCUS}
 130  * <li>{@code WINDOW_STATE_CHANGED}
 131  * </ul>
 132  *
 133  * @author      Sami Shaio
 134  * @see WindowEvent
 135  * @see Window#addWindowListener
 136  * @since       1.0
 137  */
 138 public class Frame extends Window implements MenuContainer {
 139 
 140     /* Note: These are being obsoleted;  programs should use the Cursor class
 141      * variables going forward. See Cursor and Component.setCursor.
 142      */
 143 
 144    /**
 145     * @deprecated   replaced by {@code Cursor.DEFAULT_CURSOR}.
 146     */
 147     @Deprecated
 148     public static final int     DEFAULT_CURSOR                  = Cursor.DEFAULT_CURSOR;
 149 
 150 
 151    /**
 152     * @deprecated   replaced by {@code Cursor.CROSSHAIR_CURSOR}.
 153     */
 154     @Deprecated
 155     public static final int     CROSSHAIR_CURSOR                = Cursor.CROSSHAIR_CURSOR;
 156 
 157    /**
 158     * @deprecated   replaced by {@code Cursor.TEXT_CURSOR}.
 159     */
 160     @Deprecated
 161     public static final int     TEXT_CURSOR                     = Cursor.TEXT_CURSOR;
 162 
 163    /**
 164     * @deprecated   replaced by {@code Cursor.WAIT_CURSOR}.
 165     */
 166     @Deprecated
 167     public static final int     WAIT_CURSOR                     = Cursor.WAIT_CURSOR;
 168 
 169    /**
 170     * @deprecated   replaced by {@code Cursor.SW_RESIZE_CURSOR}.
 171     */
 172     @Deprecated
 173     public static final int     SW_RESIZE_CURSOR                = Cursor.SW_RESIZE_CURSOR;
 174 
 175    /**
 176     * @deprecated   replaced by {@code Cursor.SE_RESIZE_CURSOR}.
 177     */
 178     @Deprecated
 179     public static final int     SE_RESIZE_CURSOR                = Cursor.SE_RESIZE_CURSOR;
 180 
 181    /**
 182     * @deprecated   replaced by {@code Cursor.NW_RESIZE_CURSOR}.
 183     */
 184     @Deprecated
 185     public static final int     NW_RESIZE_CURSOR                = Cursor.NW_RESIZE_CURSOR;
 186 
 187    /**
 188     * @deprecated   replaced by {@code Cursor.NE_RESIZE_CURSOR}.
 189     */
 190     @Deprecated
 191     public static final int     NE_RESIZE_CURSOR                = Cursor.NE_RESIZE_CURSOR;
 192 
 193    /**
 194     * @deprecated   replaced by {@code Cursor.N_RESIZE_CURSOR}.
 195     */
 196     @Deprecated
 197     public static final int     N_RESIZE_CURSOR                 = Cursor.N_RESIZE_CURSOR;
 198 
 199    /**
 200     * @deprecated   replaced by {@code Cursor.S_RESIZE_CURSOR}.
 201     */
 202     @Deprecated
 203     public static final int     S_RESIZE_CURSOR                 = Cursor.S_RESIZE_CURSOR;
 204 
 205    /**
 206     * @deprecated   replaced by {@code Cursor.W_RESIZE_CURSOR}.
 207     */
 208     @Deprecated
 209     public static final int     W_RESIZE_CURSOR                 = Cursor.W_RESIZE_CURSOR;
 210 
 211    /**
 212     * @deprecated   replaced by {@code Cursor.E_RESIZE_CURSOR}.
 213     */
 214     @Deprecated
 215     public static final int     E_RESIZE_CURSOR                 = Cursor.E_RESIZE_CURSOR;
 216 
 217    /**
 218     * @deprecated   replaced by {@code Cursor.HAND_CURSOR}.
 219     */
 220     @Deprecated
 221     public static final int     HAND_CURSOR                     = Cursor.HAND_CURSOR;
 222 
 223    /**
 224     * @deprecated   replaced by {@code Cursor.MOVE_CURSOR}.
 225     */
 226     @Deprecated
 227     public static final int     MOVE_CURSOR                     = Cursor.MOVE_CURSOR;
 228 
 229 
 230     /**
 231      * Frame is in the "normal" state.  This symbolic constant names a
 232      * frame state with all state bits cleared.
 233      * @see #setExtendedState(int)
 234      * @see #getExtendedState
 235      */
 236     public static final int NORMAL = 0;
 237 
 238     /**
 239      * This state bit indicates that frame is iconified.
 240      * @see #setExtendedState(int)
 241      * @see #getExtendedState
 242      */
 243     public static final int ICONIFIED = 1;
 244 
 245     /**
 246      * This state bit indicates that frame is maximized in the
 247      * horizontal direction.
 248      * @see #setExtendedState(int)
 249      * @see #getExtendedState
 250      * @since 1.4
 251      */
 252     public static final int MAXIMIZED_HORIZ = 2;
 253 
 254     /**
 255      * This state bit indicates that frame is maximized in the
 256      * vertical direction.
 257      * @see #setExtendedState(int)
 258      * @see #getExtendedState
 259      * @since 1.4
 260      */
 261     public static final int MAXIMIZED_VERT = 4;
 262 
 263     /**
 264      * This state bit mask indicates that frame is fully maximized
 265      * (that is both horizontally and vertically).  It is just a
 266      * convenience alias for
 267      * <code>MAXIMIZED_VERT&nbsp;|&nbsp;MAXIMIZED_HORIZ</code>.
 268      *
 269      * <p>Note that the correct test for frame being fully maximized is
 270      * <pre>
 271      *     (state &amp; Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH
 272      * </pre>
 273      *
 274      * <p>To test is frame is maximized in <em>some</em> direction use
 275      * <pre>
 276      *     (state &amp; Frame.MAXIMIZED_BOTH) != 0
 277      * </pre>
 278      *
 279      * @see #setExtendedState(int)
 280      * @see #getExtendedState
 281      * @since 1.4
 282      */
 283     public static final int MAXIMIZED_BOTH = MAXIMIZED_VERT | MAXIMIZED_HORIZ;
 284 
 285     /**
 286      * Maximized bounds for this frame.
 287      * @see     #setMaximizedBounds(Rectangle)
 288      * @see     #getMaximizedBounds
 289      * @serial
 290      * @since 1.4
 291      */
 292     Rectangle maximizedBounds;
 293 
 294 
 295     /**
 296      * This is the title of the frame.  It can be changed
 297      * at any time.  {@code title} can be null and if
 298      * this is the case the {@code title} = "".
 299      *
 300      * @serial
 301      * @see #getTitle
 302      * @see #setTitle(String)
 303      */
 304     String      title = "Untitled";
 305 
 306     /**
 307      * The frames menubar.  If {@code menuBar} = null
 308      * the frame will not have a menubar.
 309      *
 310      * @serial
 311      * @see #getMenuBar
 312      * @see #setMenuBar(MenuBar)
 313      */
 314     MenuBar     menuBar;
 315 
 316     /**
 317      * This field indicates whether the frame is resizable.
 318      * This property can be changed at any time.
 319      * {@code resizable} will be true if the frame is
 320      * resizable, otherwise it will be false.
 321      *
 322      * @serial
 323      * @see #isResizable()
 324      */
 325     boolean     resizable = true;
 326 
 327     /**
 328      * This field indicates whether the frame is undecorated.
 329      * This property can only be changed while the frame is not displayable.
 330      * {@code undecorated} will be true if the frame is
 331      * undecorated, otherwise it will be false.
 332      *
 333      * @serial
 334      * @see #setUndecorated(boolean)
 335      * @see #isUndecorated()
 336      * @see Component#isDisplayable()
 337      * @since 1.4
 338      */
 339     boolean undecorated = false;
 340 
 341     /**
 342      * {@code mbManagement} is only used by the Motif implementation.
 343      *
 344      * @serial
 345      */
 346     boolean     mbManagement = false;   /* used only by the Motif impl. */
 347 
 348     // XXX: uwe: abuse old field for now
 349     // will need to take care of serialization
 350     private int state = NORMAL;
 351 
 352     /*
 353      * The Windows owned by the Frame.
 354      * Note: in 1.2 this has been superseded by Window.ownedWindowList
 355      *
 356      * @serial
 357      * @see java.awt.Window#ownedWindowList
 358      */
 359     Vector<Window> ownedWindows;
 360 
 361     private static final String base = "frame";
 362     private static int nameCounter = 0;
 363 
 364     /*
 365      * JDK 1.1 serialVersionUID
 366      */
 367      private static final long serialVersionUID = 2673458971256075116L;
 368 
 369     static {
 370         /* ensure that the necessary native libraries are loaded */
 371         Toolkit.loadLibraries();
 372         if (!GraphicsEnvironment.isHeadless()) {
 373             initIDs();
 374         }
 375     }
 376 
 377     /**
 378      * Constructs a new instance of {@code Frame} that is
 379      * initially invisible.  The title of the {@code Frame}
 380      * is empty.
 381      * @exception HeadlessException when
 382      *     {@code GraphicsEnvironment.isHeadless()} returns {@code true}
 383      * @see java.awt.GraphicsEnvironment#isHeadless()
 384      * @see Component#setSize
 385      * @see Component#setVisible(boolean)
 386      */
 387     public Frame() throws HeadlessException {
 388         this("");
 389     }
 390 
 391     /**
 392      * Constructs a new, initially invisible {@code Frame} with the
 393      * specified {@code GraphicsConfiguration}.
 394      *
 395      * @param gc the {@code GraphicsConfiguration}
 396      * of the target screen device. If {@code gc}
 397      * is {@code null}, the system default
 398      * {@code GraphicsConfiguration} is assumed.
 399      * @exception IllegalArgumentException if
 400      * {@code gc} is not from a screen device.
 401      * @exception HeadlessException when
 402      *     {@code GraphicsEnvironment.isHeadless()} returns {@code true}
 403      * @see java.awt.GraphicsEnvironment#isHeadless()
 404      * @since     1.3
 405      */
 406     public Frame(GraphicsConfiguration gc) {
 407         this("", gc);
 408     }
 409 
 410     /**
 411      * Constructs a new, initially invisible {@code Frame} object
 412      * with the specified title.
 413      * @param title the title to be displayed in the frame's border.
 414      *              A {@code null} value
 415      *              is treated as an empty string, "".
 416      * @exception HeadlessException when
 417      *     {@code GraphicsEnvironment.isHeadless()} returns {@code true}
 418      * @see java.awt.GraphicsEnvironment#isHeadless()
 419      * @see java.awt.Component#setSize
 420      * @see java.awt.Component#setVisible(boolean)
 421      * @see java.awt.GraphicsConfiguration#getBounds
 422      */
 423     public Frame(String title) throws HeadlessException {
 424         init(title, null);
 425     }
 426 
 427     /**
 428      * Constructs a new, initially invisible {@code Frame} object
 429      * with the specified title and a
 430      * {@code GraphicsConfiguration}.
 431      * @param title the title to be displayed in the frame's border.
 432      *              A {@code null} value
 433      *              is treated as an empty string, "".
 434      * @param gc the {@code GraphicsConfiguration}
 435      * of the target screen device.  If {@code gc} is
 436      * {@code null}, the system default
 437      * {@code GraphicsConfiguration} is assumed.
 438      * @exception IllegalArgumentException if {@code gc}
 439      * is not from a screen device.
 440      * @exception HeadlessException when
 441      *     {@code GraphicsEnvironment.isHeadless()} returns {@code true}
 442      * @see java.awt.GraphicsEnvironment#isHeadless()
 443      * @see java.awt.Component#setSize
 444      * @see java.awt.Component#setVisible(boolean)
 445      * @see java.awt.GraphicsConfiguration#getBounds
 446      * @since 1.3
 447      */
 448     public Frame(String title, GraphicsConfiguration gc) {
 449         super(gc);
 450         init(title, gc);
 451     }
 452 
 453     private void init(String title, GraphicsConfiguration gc) {
 454         this.title = title;
 455         SunToolkit.checkAndSetPolicy(this);
 456     }
 457 
 458     /**
 459      * Construct a name for this component.  Called by getName() when the
 460      * name is null.
 461      */
 462     String constructComponentName() {
 463         synchronized (Frame.class) {
 464             return base + nameCounter++;
 465         }
 466     }
 467 
 468     /**
 469      * Makes this Frame displayable by connecting it to
 470      * a native screen resource.  Making a frame displayable will
 471      * cause any of its children to be made displayable.
 472      * This method is called internally by the toolkit and should
 473      * not be called directly by programs.
 474      * @see Component#isDisplayable
 475      * @see #removeNotify
 476      */
 477     public void addNotify() {
 478         synchronized (getTreeLock()) {
 479             if (peer == null) {
 480                 peer = getComponentFactory().createFrame(this);
 481             }
 482             FramePeer p = (FramePeer)peer;
 483             MenuBar menuBar = this.menuBar;
 484             if (menuBar != null) {
 485                 mbManagement = true;
 486                 menuBar.addNotify();
 487                 p.setMenuBar(menuBar);
 488             }
 489             p.setMaximizedBounds(maximizedBounds);
 490             super.addNotify();
 491         }
 492     }
 493 
 494     /**
 495      * Gets the title of the frame.  The title is displayed in the
 496      * frame's border.
 497      * @return    the title of this frame, or an empty string ("")
 498      *                if this frame doesn't have a title.
 499      * @see       #setTitle(String)
 500      */
 501     public String getTitle() {
 502         return title;
 503     }
 504 
 505     /**
 506      * Sets the title for this frame to the specified string.
 507      * @param title the title to be displayed in the frame's border.
 508      *              A {@code null} value
 509      *              is treated as an empty string, "".
 510      * @see      #getTitle
 511      */
 512     public void setTitle(String title) {
 513         String oldTitle = this.title;
 514         if (title == null) {
 515             title = "";
 516         }
 517 
 518 
 519         synchronized(this) {
 520             this.title = title;
 521             FramePeer peer = (FramePeer)this.peer;
 522             if (peer != null) {
 523                 peer.setTitle(title);
 524             }
 525         }
 526         firePropertyChange("title", oldTitle, title);
 527     }
 528 
 529     /**
 530      * Returns the image to be displayed as the icon for this frame.
 531      * <p>
 532      * This method is obsolete and kept for backward compatibility
 533      * only. Use {@link Window#getIconImages Window.getIconImages()} instead.
 534      * <p>
 535      * If a list of several images was specified as a Window's icon,
 536      * this method will return the first item of the list.
 537      *
 538      * @return    the icon image for this frame, or {@code null}
 539      *                    if this frame doesn't have an icon image.
 540      * @see       #setIconImage(Image)
 541      * @see       Window#getIconImages()
 542      * @see       Window#setIconImages
 543      */
 544     public Image getIconImage() {
 545         java.util.List<Image> icons = this.icons;
 546         if (icons != null) {
 547             if (icons.size() > 0) {
 548                 return icons.get(0);
 549             }
 550         }
 551         return null;
 552     }
 553 
 554     /**
 555      * {@inheritDoc}
 556      */
 557     public void setIconImage(Image image) {
 558         super.setIconImage(image);
 559     }
 560 
 561     /**
 562      * Gets the menu bar for this frame.
 563      * @return    the menu bar for this frame, or {@code null}
 564      *                   if this frame doesn't have a menu bar.
 565      * @see       #setMenuBar(MenuBar)
 566      */
 567     public MenuBar getMenuBar() {
 568         return menuBar;
 569     }
 570 
 571     /**
 572      * Sets the menu bar for this frame to the specified menu bar.
 573      * @param     mb the menu bar being set.
 574      *            If this parameter is {@code null} then any
 575      *            existing menu bar on this frame is removed.
 576      * @see       #getMenuBar
 577      */
 578     public void setMenuBar(MenuBar mb) {
 579         synchronized (getTreeLock()) {
 580             if (menuBar == mb) {
 581                 return;
 582             }
 583             if ((mb != null) && (mb.parent != null)) {
 584                 mb.parent.remove(mb);
 585             }
 586             if (menuBar != null) {
 587                 remove(menuBar);
 588             }
 589             menuBar = mb;
 590             if (menuBar != null) {
 591                 menuBar.parent = this;
 592 
 593                 FramePeer peer = (FramePeer)this.peer;
 594                 if (peer != null) {
 595                     mbManagement = true;
 596                     menuBar.addNotify();
 597                     invalidateIfValid();
 598                     peer.setMenuBar(menuBar);
 599                 }
 600             }
 601         }
 602     }
 603 
 604     /**
 605      * Indicates whether this frame is resizable by the user.
 606      * By default, all frames are initially resizable.
 607      * @return    {@code true} if the user can resize this frame;
 608      *                        {@code false} otherwise.
 609      * @see       java.awt.Frame#setResizable(boolean)
 610      */
 611     public boolean isResizable() {
 612         return resizable;
 613     }
 614 
 615     /**
 616      * Sets whether this frame is resizable by the user.
 617      * @param    resizable   {@code true} if this frame is resizable;
 618      *                       {@code false} otherwise.
 619      * @see      java.awt.Frame#isResizable
 620      */
 621     public void setResizable(boolean resizable) {
 622         boolean oldResizable = this.resizable;
 623         boolean testvalid = false;
 624 
 625         synchronized (this) {
 626             this.resizable = resizable;
 627             FramePeer peer = (FramePeer)this.peer;
 628             if (peer != null) {
 629                 peer.setResizable(resizable);
 630                 testvalid = true;
 631             }
 632         }
 633 
 634         // On some platforms, changing the resizable state affects
 635         // the insets of the Frame. If we could, we'd call invalidate()
 636         // from the peer, but we need to guarantee that we're not holding
 637         // the Frame lock when we call invalidate().
 638         if (testvalid) {
 639             invalidateIfValid();
 640         }
 641         firePropertyChange("resizable", oldResizable, resizable);
 642     }
 643 
 644 
 645     /**
 646      * Sets the state of this frame (obsolete).
 647      * <p>
 648      * In older versions of JDK a frame state could only be NORMAL or
 649      * ICONIFIED.  Since JDK 1.4 set of supported frame states is
 650      * expanded and frame state is represented as a bitwise mask.
 651      * <p>
 652      * For compatibility with applications developed
 653      * earlier this method still accepts
 654      * {@code Frame.NORMAL} and
 655      * {@code Frame.ICONIFIED} only.  The iconic
 656      * state of the frame is only changed, other aspects
 657      * of frame state are not affected by this method. If
 658      * the state passed to this method is neither {@code
 659      * Frame.NORMAL} nor {@code Frame.ICONIFIED} the
 660      * method performs no actions at all.
 661      * <p>Note that if the state is not supported on a
 662      * given platform, neither the state nor the return
 663      * value of the {@link #getState} method will be
 664      * changed. The application may determine whether a
 665      * specific state is supported via the {@link
 666      * java.awt.Toolkit#isFrameStateSupported} method.
 667      * <p><b>If the frame is currently visible on the
 668      * screen</b> (the {@link #isShowing} method returns
 669      * {@code true}), the developer should examine the
 670      * return value of the  {@link
 671      * java.awt.event.WindowEvent#getNewState} method of
 672      * the {@code WindowEvent} received through the
 673      * {@link java.awt.event.WindowStateListener} to
 674      * determine that the state has actually been
 675      * changed.
 676      * <p><b>If the frame is not visible on the
 677      * screen</b>, the events may or may not be
 678      * generated.  In this case the developer may assume
 679      * that the state changes immediately after this
 680      * method returns.  Later, when the {@code
 681      * setVisible(true)} method is invoked, the frame
 682      * will attempt to apply this state. Receiving any
 683      * {@link
 684      * java.awt.event.WindowEvent#WINDOW_STATE_CHANGED}
 685      * events is not guaranteed in this case also.
 686      *
 687      * @param state either {@code Frame.NORMAL} or
 688      *     {@code Frame.ICONIFIED}.
 689      * @see #setExtendedState(int)
 690      * @see java.awt.Window#addWindowStateListener
 691      */
 692     public synchronized void setState(int state) {
 693         int current = getExtendedState();
 694         if (state == ICONIFIED && (current & ICONIFIED) == 0) {
 695             setExtendedState(current | ICONIFIED);
 696         }
 697         else if (state == NORMAL && (current & ICONIFIED) != 0) {
 698             setExtendedState(current & ~ICONIFIED);
 699         }
 700     }
 701 
 702     /**
 703      * Sets the state of this frame. The state is
 704      * represented as a bitwise mask.
 705      * <ul>
 706      * <li>{@code NORMAL}
 707      * <br>Indicates that no state bits are set.
 708      * <li>{@code ICONIFIED}
 709      * <li>{@code MAXIMIZED_HORIZ}
 710      * <li>{@code MAXIMIZED_VERT}
 711      * <li>{@code MAXIMIZED_BOTH}
 712      * <br>Concatenates {@code MAXIMIZED_HORIZ}
 713      * and {@code MAXIMIZED_VERT}.
 714      * </ul>
 715      * <p>Note that if the state is not supported on a
 716      * given platform, neither the state nor the return
 717      * value of the {@link #getExtendedState} method will
 718      * be changed. The application may determine whether
 719      * a specific state is supported via the {@link
 720      * java.awt.Toolkit#isFrameStateSupported} method.
 721      * <p><b>If the frame is currently visible on the
 722      * screen</b> (the {@link #isShowing} method returns
 723      * {@code true}), the developer should examine the
 724      * return value of the {@link
 725      * java.awt.event.WindowEvent#getNewState} method of
 726      * the {@code WindowEvent} received through the
 727      * {@link java.awt.event.WindowStateListener} to
 728      * determine that the state has actually been
 729      * changed.
 730      * <p><b>If the frame is not visible on the
 731      * screen</b>, the events may or may not be
 732      * generated.  In this case the developer may assume
 733      * that the state changes immediately after this
 734      * method returns.  Later, when the {@code
 735      * setVisible(true)} method is invoked, the frame
 736      * will attempt to apply this state. Receiving any
 737      * {@link
 738      * java.awt.event.WindowEvent#WINDOW_STATE_CHANGED}
 739      * events is not guaranteed in this case also.
 740      *
 741      * @param state a bitwise mask of frame state constants
 742      * @since   1.4
 743      * @see java.awt.Window#addWindowStateListener
 744      */
 745     public void setExtendedState(int state) {
 746         if ( !isFrameStateSupported( state ) ) {
 747             return;
 748         }
 749         synchronized (getObjectLock()) {
 750             this.state = state;
 751         }
 752         // peer.setState must be called outside of object lock
 753         // synchronization block to avoid possible deadlock
 754         FramePeer peer = (FramePeer)this.peer;
 755         if (peer != null) {
 756             peer.setState(state);
 757         }
 758     }
 759     private boolean isFrameStateSupported(int state) {
 760         if( !getToolkit().isFrameStateSupported( state ) ) {
 761             // * Toolkit.isFrameStateSupported returns always false
 762             // on compound state even if all parts are supported;
 763             // * if part of state is not supported, state is not supported;
 764             // * MAXIMIZED_BOTH is not a compound state.
 765             if( ((state & ICONIFIED) != 0) &&
 766                 !getToolkit().isFrameStateSupported( ICONIFIED )) {
 767                 return false;
 768             }else {
 769                 state &= ~ICONIFIED;
 770             }
 771             return getToolkit().isFrameStateSupported( state );
 772         }
 773         return true;
 774     }
 775 
 776     /**
 777      * Gets the state of this frame (obsolete).
 778      * <p>
 779      * In older versions of JDK a frame state could only be NORMAL or
 780      * ICONIFIED.  Since JDK 1.4 set of supported frame states is
 781      * expanded and frame state is represented as a bitwise mask.
 782      * <p>
 783      * For compatibility with old programs this method still returns
 784      * {@code Frame.NORMAL} and {@code Frame.ICONIFIED} but
 785      * it only reports the iconic state of the frame, other aspects of
 786      * frame state are not reported by this method.
 787      *
 788      * @return  {@code Frame.NORMAL} or {@code Frame.ICONIFIED}.
 789      * @see     #setState(int)
 790      * @see     #getExtendedState
 791      */
 792     public synchronized int getState() {
 793         return (getExtendedState() & ICONIFIED) != 0 ? ICONIFIED : NORMAL;
 794     }
 795 
 796 
 797     /**
 798      * Gets the state of this frame. The state is
 799      * represented as a bitwise mask.
 800      * <ul>
 801      * <li>{@code NORMAL}
 802      * <br>Indicates that no state bits are set.
 803      * <li>{@code ICONIFIED}
 804      * <li>{@code MAXIMIZED_HORIZ}
 805      * <li>{@code MAXIMIZED_VERT}
 806      * <li>{@code MAXIMIZED_BOTH}
 807      * <br>Concatenates {@code MAXIMIZED_HORIZ}
 808      * and {@code MAXIMIZED_VERT}.
 809      * </ul>
 810      *
 811      * @return  a bitwise mask of frame state constants
 812      * @see     #setExtendedState(int)
 813      * @since 1.4
 814      */
 815     public int getExtendedState() {
 816         synchronized (getObjectLock()) {
 817             return state;
 818         }
 819     }
 820 
 821     static {
 822         AWTAccessor.setFrameAccessor(
 823             new AWTAccessor.FrameAccessor() {
 824                 public void setExtendedState(Frame frame, int state) {
 825                     synchronized(frame.getObjectLock()) {
 826                         frame.state = state;
 827                     }
 828                 }
 829                 public int getExtendedState(Frame frame) {
 830                     synchronized(frame.getObjectLock()) {
 831                         return frame.state;
 832                     }
 833                 }
 834                 public Rectangle getMaximizedBounds(Frame frame) {
 835                     synchronized(frame.getObjectLock()) {
 836                         return frame.maximizedBounds;
 837                     }
 838                 }
 839             }
 840         );
 841     }
 842 
 843     /**
 844      * Sets the maximized bounds for this frame.
 845      * <p>
 846      * When a frame is in maximized state the system supplies some
 847      * defaults bounds.  This method allows some or all of those
 848      * system supplied values to be overridden.
 849      * <p>
 850      * If {@code bounds} is {@code null}, accept bounds
 851      * supplied by the system.  If non-{@code null} you can
 852      * override some of the system supplied values while accepting
 853      * others by setting those fields you want to accept from system
 854      * to {@code Integer.MAX_VALUE}.
 855      * <p>
 856      * Note, the given maximized bounds are used as a hint for the native
 857      * system, because the underlying platform may not support setting the
 858      * location and/or size of the maximized windows.  If that is the case, the
 859      * provided values do not affect the appearance of the frame in the
 860      * maximized state.
 861      *
 862      * @param bounds  bounds for the maximized state
 863      * @see #getMaximizedBounds()
 864      * @since 1.4
 865      */
 866     public void setMaximizedBounds(Rectangle bounds) {
 867         synchronized(getObjectLock()) {
 868             this.maximizedBounds = bounds;
 869         }
 870         FramePeer peer = (FramePeer)this.peer;
 871         if (peer != null) {
 872             peer.setMaximizedBounds(bounds);
 873         }
 874     }
 875 
 876     /**
 877      * Gets maximized bounds for this frame.
 878      * Some fields may contain {@code Integer.MAX_VALUE} to indicate
 879      * that system supplied values for this field must be used.
 880      *
 881      * @return  maximized bounds for this frame;  may be {@code null}
 882      * @see     #setMaximizedBounds(Rectangle)
 883      * @since   1.4
 884      */
 885     public Rectangle getMaximizedBounds() {
 886         synchronized(getObjectLock()) {
 887             return maximizedBounds;
 888         }
 889     }
 890 
 891 
 892     /**
 893      * Disables or enables decorations for this frame.
 894      * <p>
 895      * This method can only be called while the frame is not displayable. To
 896      * make this frame decorated, it must be opaque and have the default shape,
 897      * otherwise the {@code IllegalComponentStateException} will be thrown.
 898      * Refer to {@link Window#setShape}, {@link Window#setOpacity} and {@link
 899      * Window#setBackground} for details
 900      *
 901      * @param  undecorated {@code true} if no frame decorations are to be
 902      *         enabled; {@code false} if frame decorations are to be enabled
 903      *
 904      * @throws IllegalComponentStateException if the frame is displayable
 905      * @throws IllegalComponentStateException if {@code undecorated} is
 906      *      {@code false}, and this frame does not have the default shape
 907      * @throws IllegalComponentStateException if {@code undecorated} is
 908      *      {@code false}, and this frame opacity is less than {@code 1.0f}
 909      * @throws IllegalComponentStateException if {@code undecorated} is
 910      *      {@code false}, and the alpha value of this frame background
 911      *      color is less than {@code 1.0f}
 912      *
 913      * @see    #isUndecorated
 914      * @see    Component#isDisplayable
 915      * @see    Window#getShape
 916      * @see    Window#getOpacity
 917      * @see    Window#getBackground
 918      * @see    javax.swing.JFrame#setDefaultLookAndFeelDecorated(boolean)
 919      *
 920      * @since 1.4
 921      */
 922     public void setUndecorated(boolean undecorated) {
 923         /* Make sure we don't run in the middle of peer creation.*/
 924         synchronized (getTreeLock()) {
 925             if (isDisplayable()) {
 926                 throw new IllegalComponentStateException("The frame is displayable.");
 927             }
 928             if (!undecorated) {
 929                 if (getOpacity() < 1.0f) {
 930                     throw new IllegalComponentStateException("The frame is not opaque");
 931                 }
 932                 if (getShape() != null) {
 933                     throw new IllegalComponentStateException("The frame does not have a default shape");
 934                 }
 935                 Color bg = getBackground();
 936                 if ((bg != null) && (bg.getAlpha() < 255)) {
 937                     throw new IllegalComponentStateException("The frame background color is not opaque");
 938                 }
 939             }
 940             this.undecorated = undecorated;
 941         }
 942     }
 943 
 944     /**
 945      * Indicates whether this frame is undecorated.
 946      * By default, all frames are initially decorated.
 947      * @return    {@code true} if frame is undecorated;
 948      *                        {@code false} otherwise.
 949      * @see       java.awt.Frame#setUndecorated(boolean)
 950      * @since 1.4
 951      */
 952     public boolean isUndecorated() {
 953         return undecorated;
 954     }
 955 
 956     /**
 957      * {@inheritDoc}
 958      */
 959     @Override
 960     public void setOpacity(float opacity) {
 961         synchronized (getTreeLock()) {
 962             if ((opacity < 1.0f) && !isUndecorated()) {
 963                 throw new IllegalComponentStateException("The frame is decorated");
 964             }
 965             super.setOpacity(opacity);
 966         }
 967     }
 968 
 969     /**
 970      * {@inheritDoc}
 971      */
 972     @Override
 973     public void setShape(Shape shape) {
 974         synchronized (getTreeLock()) {
 975             if ((shape != null) && !isUndecorated()) {
 976                 throw new IllegalComponentStateException("The frame is decorated");
 977             }
 978             super.setShape(shape);
 979         }
 980     }
 981 
 982     /**
 983      * {@inheritDoc}
 984      */
 985     @Override
 986     public void setBackground(Color bgColor) {
 987         synchronized (getTreeLock()) {
 988             if ((bgColor != null) && (bgColor.getAlpha() < 255) && !isUndecorated()) {
 989                 throw new IllegalComponentStateException("The frame is decorated");
 990             }
 991             super.setBackground(bgColor);
 992         }
 993     }
 994 
 995     /**
 996      * Removes the specified menu bar from this frame.
 997      * @param    m   the menu component to remove.
 998      *           If {@code m} is {@code null}, then
 999      *           no action is taken
1000      */
1001     public void remove(MenuComponent m) {
1002         if (m == null) {
1003             return;
1004         }
1005         synchronized (getTreeLock()) {
1006             if (m == menuBar) {
1007                 menuBar = null;
1008                 FramePeer peer = (FramePeer)this.peer;
1009                 if (peer != null) {
1010                     mbManagement = true;
1011                     invalidateIfValid();
1012                     peer.setMenuBar(null);
1013                     m.removeNotify();
1014                 }
1015                 m.parent = null;
1016             } else {
1017                 super.remove(m);
1018             }
1019         }
1020     }
1021 
1022     /**
1023      * Makes this Frame undisplayable by removing its connection
1024      * to its native screen resource. Making a Frame undisplayable
1025      * will cause any of its children to be made undisplayable.
1026      * This method is called by the toolkit internally and should
1027      * not be called directly by programs.
1028      * @see Component#isDisplayable
1029      * @see #addNotify
1030      */
1031     public void removeNotify() {
1032         synchronized (getTreeLock()) {
1033             FramePeer peer = (FramePeer)this.peer;
1034             if (peer != null) {
1035                 // get the latest Frame state before disposing
1036                 getState();
1037 
1038                 if (menuBar != null) {
1039                     mbManagement = true;
1040                     peer.setMenuBar(null);
1041                     menuBar.removeNotify();
1042                 }
1043             }
1044             super.removeNotify();
1045         }
1046     }
1047 
1048     void postProcessKeyEvent(KeyEvent e) {
1049         if (menuBar != null && menuBar.handleShortcut(e)) {
1050             e.consume();
1051             return;
1052         }
1053         super.postProcessKeyEvent(e);
1054     }
1055 
1056     /**
1057      * Returns a string representing the state of this {@code Frame}.
1058      * This method is intended to be used only for debugging purposes, and the
1059      * content and format of the returned string may vary between
1060      * implementations. The returned string may be empty but may not be
1061      * {@code null}.
1062      *
1063      * @return the parameter string of this frame
1064      */
1065     protected String paramString() {
1066         String str = super.paramString();
1067         if (title != null) {
1068             str += ",title=" + title;
1069         }
1070         if (resizable) {
1071             str += ",resizable";
1072         }
1073         int state = getExtendedState();
1074         if (state == NORMAL) {
1075             str += ",normal";
1076         }
1077         else {
1078             if ((state & ICONIFIED) != 0) {
1079                 str += ",iconified";
1080             }
1081             if ((state & MAXIMIZED_BOTH) == MAXIMIZED_BOTH) {
1082                 str += ",maximized";
1083             }
1084             else if ((state & MAXIMIZED_HORIZ) != 0) {
1085                 str += ",maximized_horiz";
1086             }
1087             else if ((state & MAXIMIZED_VERT) != 0) {
1088                 str += ",maximized_vert";
1089             }
1090         }
1091         return str;
1092     }
1093 
1094     /**
1095      * Sets the cursor for this frame to the specified type.
1096      *
1097      * @param  cursorType the cursor type
1098      * @deprecated As of JDK version 1.1,
1099      * replaced by {@code Component.setCursor(Cursor)}.
1100      */
1101     @Deprecated
1102     public void setCursor(int cursorType) {
1103         if (cursorType < DEFAULT_CURSOR || cursorType > MOVE_CURSOR) {
1104             throw new IllegalArgumentException("illegal cursor type");
1105         }
1106         setCursor(Cursor.getPredefinedCursor(cursorType));
1107     }
1108 
1109     /**
1110      * @deprecated As of JDK version 1.1,
1111      * replaced by {@code Component.getCursor()}.
1112      * @return the cursor type for this frame
1113      */
1114     @Deprecated
1115     public int getCursorType() {
1116         return (getCursor().getType());
1117     }
1118 
1119     /**
1120      * Returns an array of all {@code Frame}s created by this application.
1121      * If called from an applet, the array includes only the {@code Frame}s
1122      * accessible by that applet.
1123      * <p>
1124      * <b>Warning:</b> this method may return system created frames, such
1125      * as a shared, hidden frame which is used by Swing. Applications
1126      * should not assume the existence of these frames, nor should an
1127      * application assume anything about these frames such as component
1128      * positions, {@code LayoutManager}s or serialization.
1129      * <p>
1130      * <b>Note</b>: To obtain a list of all ownerless windows, including
1131      * ownerless {@code Dialog}s (introduced in release 1.6), use {@link
1132      * Window#getOwnerlessWindows Window.getOwnerlessWindows}.
1133      *
1134      * @return the array of all {@code Frame}s created by this application
1135      *
1136      * @see Window#getWindows()
1137      * @see Window#getOwnerlessWindows
1138      *
1139      * @since 1.2
1140      */
1141     public static Frame[] getFrames() {
1142         Window[] allWindows = Window.getWindows();
1143 
1144         int frameCount = 0;
1145         for (Window w : allWindows) {
1146             if (w instanceof Frame) {
1147                 frameCount++;
1148             }
1149         }
1150 
1151         Frame[] frames = new Frame[frameCount];
1152         int c = 0;
1153         for (Window w : allWindows) {
1154             if (w instanceof Frame) {
1155                 frames[c++] = (Frame)w;
1156             }
1157         }
1158 
1159         return frames;
1160     }
1161 
1162     /* Serialization support.  If there's a MenuBar we restore
1163      * its (transient) parent field here.  Likewise for top level
1164      * windows that are "owned" by this frame.
1165      */
1166 
1167     /**
1168      * {@code Frame}'s Serialized Data Version.
1169      *
1170      * @serial
1171      */
1172     private int frameSerializedDataVersion = 1;
1173 
1174     /**
1175      * Writes default serializable fields to stream.  Writes
1176      * an optional serializable icon {@code Image}, which is
1177      * available as of 1.4.
1178      *
1179      * @param s the {@code ObjectOutputStream} to write
1180      * @serialData an optional icon {@code Image}
1181      * @see java.awt.Image
1182      * @see #getIconImage
1183      * @see #setIconImage(Image)
1184      * @see #readObject(ObjectInputStream)
1185      */
1186     private void writeObject(ObjectOutputStream s)
1187       throws IOException
1188     {
1189         s.defaultWriteObject();
1190         if (icons != null && icons.size() > 0) {
1191             Image icon1 = icons.get(0);
1192             if (icon1 instanceof Serializable) {
1193                 s.writeObject(icon1);
1194                 return;
1195             }
1196         }
1197         s.writeObject(null);
1198     }
1199 
1200     /**
1201      * Reads the {@code ObjectInputStream}.  Tries
1202      * to read an icon {@code Image}, which is optional
1203      * data available as of 1.4.  If an icon {@code Image}
1204      * is not available, but anything other than an EOF
1205      * is detected, an {@code OptionalDataException}
1206      * will be thrown.
1207      * Unrecognized keys or values will be ignored.
1208      *
1209      * @param s the {@code ObjectInputStream} to read
1210      * @exception java.io.OptionalDataException if an icon {@code Image}
1211      *   is not available, but anything other than an EOF
1212      *   is detected
1213      * @exception HeadlessException if
1214      *   {@code GraphicsEnvironment.isHeadless} returns
1215      *   {@code true}
1216      * @see java.awt.GraphicsEnvironment#isHeadless()
1217      * @see java.awt.Image
1218      * @see #getIconImage
1219      * @see #setIconImage(Image)
1220      * @see #writeObject(ObjectOutputStream)
1221      */
1222     private void readObject(ObjectInputStream s)
1223       throws ClassNotFoundException, IOException, HeadlessException
1224     {
1225       // HeadlessException is thrown by Window's readObject
1226       s.defaultReadObject();
1227       try {
1228           Image icon = (Image) s.readObject();
1229           if (icons == null) {
1230               icons = new ArrayList<Image>();
1231               icons.add(icon);
1232           }
1233       } catch (java.io.OptionalDataException e) {
1234           // pre-1.4 instances will not have this optional data.
1235           // 1.6 and later instances serialize icons in the Window class
1236           // e.eof will be true to indicate that there is no more
1237           // data available for this object.
1238 
1239           // If e.eof is not true, throw the exception as it
1240           // might have been caused by unrelated reasons.
1241           if (!e.eof) {
1242               throw (e);
1243           }
1244       }
1245 
1246       if (menuBar != null)
1247         menuBar.parent = this;
1248 
1249       // Ensure 1.1 serialized Frames can read & hook-up
1250       // owned windows properly
1251       //
1252       if (ownedWindows != null) {
1253           for (int i = 0; i < ownedWindows.size(); i++) {
1254               connectOwnedWindow(ownedWindows.elementAt(i));
1255           }
1256           ownedWindows = null;
1257       }
1258     }
1259 
1260     /**
1261      * Initialize JNI field and method IDs
1262      */
1263     private static native void initIDs();
1264 
1265     /*
1266      * --- Accessibility Support ---
1267      *
1268      */
1269 
1270     /**
1271      * Gets the AccessibleContext associated with this Frame.
1272      * For frames, the AccessibleContext takes the form of an
1273      * AccessibleAWTFrame.
1274      * A new AccessibleAWTFrame instance is created if necessary.
1275      *
1276      * @return an AccessibleAWTFrame that serves as the
1277      *         AccessibleContext of this Frame
1278      * @since 1.3
1279      */
1280     public AccessibleContext getAccessibleContext() {
1281         if (accessibleContext == null) {
1282             accessibleContext = new AccessibleAWTFrame();
1283         }
1284         return accessibleContext;
1285     }
1286 
1287     /**
1288      * This class implements accessibility support for the
1289      * {@code Frame} class.  It provides an implementation of the
1290      * Java Accessibility API appropriate to frame user-interface elements.
1291      * @since 1.3
1292      */
1293     protected class AccessibleAWTFrame extends AccessibleAWTWindow
1294     {
1295         /*
1296          * JDK 1.3 serialVersionUID
1297          */
1298         private static final long serialVersionUID = -6172960752956030250L;
1299 
1300         /**
1301          * Get the role of this object.
1302          *
1303          * @return an instance of AccessibleRole describing the role of the
1304          * object
1305          * @see AccessibleRole
1306          */
1307         public AccessibleRole getAccessibleRole() {
1308             return AccessibleRole.FRAME;
1309         }
1310 
1311         /**
1312          * Get the state of this object.
1313          *
1314          * @return an instance of AccessibleStateSet containing the current
1315          * state set of the object
1316          * @see AccessibleState
1317          */
1318         public AccessibleStateSet getAccessibleStateSet() {
1319             AccessibleStateSet states = super.getAccessibleStateSet();
1320             if (getFocusOwner() != null) {
1321                 states.add(AccessibleState.ACTIVE);
1322             }
1323             if (isResizable()) {
1324                 states.add(AccessibleState.RESIZABLE);
1325             }
1326             return states;
1327         }
1328 
1329 
1330     } // inner class AccessibleAWTFrame
1331 
1332 }