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