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