blob: c94803c4c4dfc2d26297e24b809fb37352b317e5 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package javax.swing;
26
27import java.awt.*;
28import java.awt.event.*;
29import java.beans.PropertyChangeListener;
30import java.util.Locale;
31import java.util.Vector;
32import java.io.Serializable;
33
34import javax.accessibility.*;
35
36/**
37 * A <code>JWindow</code> is a container that can be displayed anywhere on the
38 * user's desktop. It does not have the title bar, window-management buttons,
39 * or other trimmings associated with a <code>JFrame</code>, but it is still a
40 * "first-class citizen" of the user's desktop, and can exist anywhere
41 * on it.
42 * <p>
43 * The <code>JWindow</code> component contains a <code>JRootPane</code>
44 * as its only child. The <code>contentPane</code> should be the parent
45 * of any children of the <code>JWindow</code>.
46 * As a conveniance <code>add</code> and its variants, <code>remove</code> and
47 * <code>setLayout</code> have been overridden to forward to the
48 * <code>contentPane</code> as necessary. This means you can write:
49 * <pre>
50 * window.add(child);
51 * </pre>
52 * And the child will be added to the contentPane.
53 * The <code>contentPane</code> will always be non-<code>null</code>.
54 * Attempting to set it to <code>null</code> will cause the <code>JWindow</code>
55 * to throw an exception. The default <code>contentPane</code> will have a
56 * <code>BorderLayout</code> manager set on it.
57 * Refer to {@link javax.swing.RootPaneContainer}
58 * for details on adding, removing and setting the <code>LayoutManager</code>
59 * of a <code>JWindow</code>.
60 * <p>
61 * Please see the {@link JRootPane} documentation for a complete description of
62 * the <code>contentPane</code>, <code>glassPane</code>, and
63 * <code>layeredPane</code> components.
64 * <p>
65 * In a multi-screen environment, you can create a <code>JWindow</code>
66 * on a different screen device. See {@link java.awt.Window} for more
67 * information.
68 * <p>
69 * <strong>Warning:</strong> Swing is not thread safe. For more
70 * information see <a
71 * href="package-summary.html#threading">Swing's Threading
72 * Policy</a>.
73 * <p>
74 * <strong>Warning:</strong>
75 * Serialized objects of this class will not be compatible with
76 * future Swing releases. The current serialization support is
77 * appropriate for short term storage or RMI between applications running
78 * the same version of Swing. As of 1.4, support for long term storage
79 * of all JavaBeans<sup><font size="-2">TM</font></sup>
80 * has been added to the <code>java.beans</code> package.
81 * Please see {@link java.beans.XMLEncoder}.
82 *
83 * @see JRootPane
84 *
85 * @beaninfo
86 * attribute: isContainer true
87 * attribute: containerDelegate getContentPane
88 * description: A toplevel window which has no system border or controls.
89 *
90 * @author David Kloba
91 */
92public class JWindow extends Window implements Accessible,
93 RootPaneContainer,
94 TransferHandler.HasGetTransferHandler
95{
96 /**
97 * The <code>JRootPane</code> instance that manages the
98 * <code>contentPane</code>
99 * and optional <code>menuBar</code> for this frame, as well as the
100 * <code>glassPane</code>.
101 *
102 * @see #getRootPane
103 * @see #setRootPane
104 */
105 protected JRootPane rootPane;
106
107 /**
108 * If true then calls to <code>add</code> and <code>setLayout</code>
109 * will be forwarded to the <code>contentPane</code>. This is initially
110 * false, but is set to true when the <code>JWindow</code> is constructed.
111 *
112 * @see #isRootPaneCheckingEnabled
113 * @see #setRootPaneCheckingEnabled
114 * @see javax.swing.RootPaneContainer
115 */
116 protected boolean rootPaneCheckingEnabled = false;
117
118 /**
119 * The <code>TransferHandler</code> for this window.
120 */
121 private TransferHandler transferHandler;
122
123 /**
124 * Creates a window with no specified owner. This window will not be
125 * focusable.
126 * <p>
127 * This constructor sets the component's locale property to the value
128 * returned by <code>JComponent.getDefaultLocale</code>.
129 *
130 * @throws HeadlessException if
131 * <code>GraphicsEnvironment.isHeadless()</code> returns true.
132 * @see java.awt.GraphicsEnvironment#isHeadless
133 * @see #isFocusableWindow
134 * @see JComponent#getDefaultLocale
135 */
136 public JWindow() {
137 this((Frame)null);
138 }
139
140 /**
141 * Creates a window with the specified <code>GraphicsConfiguration</code>
142 * of a screen device. This window will not be focusable.
143 * <p>
144 * This constructor sets the component's locale property to the value
145 * returned by <code>JComponent.getDefaultLocale</code>.
146 *
147 * @param gc the <code>GraphicsConfiguration</code> that is used
148 * to construct the new window with; if gc is <code>null</code>,
149 * the system default <code>GraphicsConfiguration</code>
150 * is assumed
151 * @throws HeadlessException If
152 * <code>GraphicsEnvironment.isHeadless()</code> returns true.
153 * @throws IllegalArgumentException if <code>gc</code> is not from
154 * a screen device.
155 *
156 * @see java.awt.GraphicsEnvironment#isHeadless
157 * @see #isFocusableWindow
158 * @see JComponent#getDefaultLocale
159 *
160 * @since 1.3
161 */
162 public JWindow(GraphicsConfiguration gc) {
163 this(null, gc);
164 super.setFocusableWindowState(false);
165 }
166
167 /**
168 * Creates a window with the specified owner frame.
169 * If <code>owner</code> is <code>null</code>, the shared owner
170 * will be used and this window will not be focusable. Also,
171 * this window will not be focusable unless its owner is showing
172 * on the screen.
173 * <p>
174 * This constructor sets the component's locale property to the value
175 * returned by <code>JComponent.getDefaultLocale</code>.
176 *
177 * @param owner the frame from which the window is displayed
178 * @throws HeadlessException if GraphicsEnvironment.isHeadless()
179 * returns true.
180 * @see java.awt.GraphicsEnvironment#isHeadless
181 * @see #isFocusableWindow
182 * @see JComponent#getDefaultLocale
183 */
184 public JWindow(Frame owner) {
185 super(owner == null? SwingUtilities.getSharedOwnerFrame() : owner);
186 if (owner == null) {
187 WindowListener ownerShutdownListener =
188 (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener();
189 addWindowListener(ownerShutdownListener);
190 }
191 windowInit();
192 }
193
194 /**
195 * Creates a window with the specified owner window. This window
196 * will not be focusable unless its owner is showing on the screen.
197 * If <code>owner</code> is <code>null</code>, the shared owner
198 * will be used and this window will not be focusable.
199 * <p>
200 * This constructor sets the component's locale property to the value
201 * returned by <code>JComponent.getDefaultLocale</code>.
202 *
203 * @param owner the window from which the window is displayed
204 * @throws HeadlessException if
205 * <code>GraphicsEnvironment.isHeadless()</code> returns true.
206 * @see java.awt.GraphicsEnvironment#isHeadless
207 * @see #isFocusableWindow
208 * @see JComponent#getDefaultLocale
209 */
210 public JWindow(Window owner) {
211 super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() :
212 owner);
213 if (owner == null) {
214 WindowListener ownerShutdownListener =
215 (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener();
216 addWindowListener(ownerShutdownListener);
217 }
218 windowInit();
219 }
220
221 /**
222 * Creates a window with the specified owner window and
223 * <code>GraphicsConfiguration</code> of a screen device. If
224 * <code>owner</code> is <code>null</code>, the shared owner will be used
225 * and this window will not be focusable.
226 * <p>
227 * This constructor sets the component's locale property to the value
228 * returned by <code>JComponent.getDefaultLocale</code>.
229 *
230 * @param owner the window from which the window is displayed
231 * @param gc the <code>GraphicsConfiguration</code> that is used
232 * to construct the new window with; if gc is <code>null</code>,
233 * the system default <code>GraphicsConfiguration</code>
234 * is assumed, unless <code>owner</code> is also null, in which
235 * case the <code>GraphicsConfiguration</code> from the
236 * shared owner frame will be used.
237 * @throws HeadlessException if
238 * <code>GraphicsEnvironment.isHeadless()</code> returns true.
239 * @throws IllegalArgumentException if <code>gc</code> is not from
240 * a screen device.
241 *
242 * @see java.awt.GraphicsEnvironment#isHeadless
243 * @see #isFocusableWindow
244 * @see JComponent#getDefaultLocale
245 *
246 * @since 1.3
247 */
248 public JWindow(Window owner, GraphicsConfiguration gc) {
249 super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() :
250 owner, gc);
251 if (owner == null) {
252 WindowListener ownerShutdownListener =
253 (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener();
254 addWindowListener(ownerShutdownListener);
255 }
256 windowInit();
257 }
258
259 /**
260 * Called by the constructors to init the <code>JWindow</code> properly.
261 */
262 protected void windowInit() {
263 setLocale( JComponent.getDefaultLocale() );
264 setRootPane(createRootPane());
265 setRootPaneCheckingEnabled(true);
266 sun.awt.SunToolkit.checkAndSetPolicy(this, true);
267 }
268
269 /**
270 * Called by the constructor methods to create the default
271 * <code>rootPane</code>.
272 */
273 protected JRootPane createRootPane() {
274 JRootPane rp = new JRootPane();
275 // NOTE: this uses setOpaque vs LookAndFeel.installProperty as there
276 // is NO reason for the RootPane not to be opaque. For painting to
277 // work the contentPane must be opaque, therefor the RootPane can
278 // also be opaque.
279 rp.setOpaque(true);
280 return rp;
281 }
282
283 /**
284 * Returns whether calls to <code>add</code> and
285 * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
286 *
287 * @return true if <code>add</code> and <code>setLayout</code>
288 * are fowarded; false otherwise
289 *
290 * @see #addImpl
291 * @see #setLayout
292 * @see #setRootPaneCheckingEnabled
293 * @see javax.swing.RootPaneContainer
294 */
295 protected boolean isRootPaneCheckingEnabled() {
296 return rootPaneCheckingEnabled;
297 }
298
299 /**
300 * Sets the {@code transferHandler} property, which is a mechanism to
301 * support transfer of data into this component. Use {@code null}
302 * if the component does not support data transfer operations.
303 * <p>
304 * If the system property {@code suppressSwingDropSupport} is {@code false}
305 * (the default) and the current drop target on this component is either
306 * {@code null} or not a user-set drop target, this method will change the
307 * drop target as follows: If {@code newHandler} is {@code null} it will
308 * clear the drop target. If not {@code null} it will install a new
309 * {@code DropTarget}.
310 * <p>
311 * Note: When used with {@code JWindow}, {@code TransferHandler} only
312 * provides data import capability, as the data export related methods
313 * are currently typed to {@code JComponent}.
314 * <p>
315 * Please see
316 * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html">
317 * How to Use Drag and Drop and Data Transfer</a>, a section in
318 * <em>The Java Tutorial</em>, for more information.
319 *
320 * @param newHandler the new {@code TransferHandler}
321 *
322 * @see TransferHandler
323 * @see #getTransferHandler
324 * @see java.awt.Component#setDropTarget
325 * @since 1.6
326 *
327 * @beaninfo
328 * bound: true
329 * hidden: true
330 * description: Mechanism for transfer of data into the component
331 */
332 public void setTransferHandler(TransferHandler newHandler) {
333 TransferHandler oldHandler = transferHandler;
334 transferHandler = newHandler;
335 SwingUtilities.installSwingDropTargetAsNecessary(this, transferHandler);
336 firePropertyChange("transferHandler", oldHandler, newHandler);
337 }
338
339 /**
340 * Gets the <code>transferHandler</code> property.
341 *
342 * @return the value of the <code>transferHandler</code> property
343 *
344 * @see TransferHandler
345 * @see #setTransferHandler
346 * @since 1.6
347 */
348 public TransferHandler getTransferHandler() {
349 return transferHandler;
350 }
351
352 /**
353 * Calls <code>paint(g)</code>. This method was overridden to
354 * prevent an unnecessary call to clear the background.
355 *
356 * @param g the <code>Graphics</code> context in which to paint
357 */
358 public void update(Graphics g) {
359 paint(g);
360 }
361
362 /**
363 * Sets whether calls to <code>add</code> and
364 * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
365 *
366 * @param enabled true if <code>add</code> and <code>setLayout</code>
367 * are forwarded, false if they should operate directly on the
368 * <code>JWindow</code>.
369 *
370 * @see #addImpl
371 * @see #setLayout
372 * @see #isRootPaneCheckingEnabled
373 * @see javax.swing.RootPaneContainer
374 * @beaninfo
375 * hidden: true
376 * description: Whether the add and setLayout methods are forwarded
377 */
378 protected void setRootPaneCheckingEnabled(boolean enabled) {
379 rootPaneCheckingEnabled = enabled;
380 }
381
382
383 /**
384 * Adds the specified child <code>Component</code>.
385 * This method is overridden to conditionally forward calls to the
386 * <code>contentPane</code>.
387 * By default, children are added to the <code>contentPane</code> instead
388 * of the frame, refer to {@link javax.swing.RootPaneContainer} for
389 * details.
390 *
391 * @param comp the component to be enhanced
392 * @param constraints the constraints to be respected
393 * @param index the index
394 * @exception IllegalArgumentException if <code>index</code> is invalid
395 * @exception IllegalArgumentException if adding the container's parent
396 * to itself
397 * @exception IllegalArgumentException if adding a window to a container
398 *
399 * @see #setRootPaneCheckingEnabled
400 * @see javax.swing.RootPaneContainer
401 */
402 protected void addImpl(Component comp, Object constraints, int index)
403 {
404 if(isRootPaneCheckingEnabled()) {
405 getContentPane().add(comp, constraints, index);
406 }
407 else {
408 super.addImpl(comp, constraints, index);
409 }
410 }
411
412 /**
413 * Removes the specified component from the container. If
414 * <code>comp</code> is not the <code>rootPane</code>, this will forward
415 * the call to the <code>contentPane</code>. This will do nothing if
416 * <code>comp</code> is not a child of the <code>JWindow</code> or
417 * <code>contentPane</code>.
418 *
419 * @param comp the component to be removed
420 * @throws NullPointerException if <code>comp</code> is null
421 * @see #add
422 * @see javax.swing.RootPaneContainer
423 */
424 public void remove(Component comp) {
425 if (comp == rootPane) {
426 super.remove(comp);
427 } else {
428 getContentPane().remove(comp);
429 }
430 }
431
432
433 /**
434 * Sets the <code>LayoutManager</code>.
435 * Overridden to conditionally forward the call to the
436 * <code>contentPane</code>.
437 * Refer to {@link javax.swing.RootPaneContainer} for
438 * more information.
439 *
440 * @param manager the <code>LayoutManager</code>
441 * @see #setRootPaneCheckingEnabled
442 * @see javax.swing.RootPaneContainer
443 */
444 public void setLayout(LayoutManager manager) {
445 if(isRootPaneCheckingEnabled()) {
446 getContentPane().setLayout(manager);
447 }
448 else {
449 super.setLayout(manager);
450 }
451 }
452
453
454 /**
455 * Returns the <code>rootPane</code> object for this window.
456 * @return the <code>rootPane</code> property for this window
457 *
458 * @see #setRootPane
459 * @see RootPaneContainer#getRootPane
460 */
461 public JRootPane getRootPane() {
462 return rootPane;
463 }
464
465
466 /**
467 * Sets the new <code>rootPane</code> object for this window.
468 * This method is called by the constructor.
469 *
470 * @param root the new <code>rootPane</code> property
471 * @see #getRootPane
472 *
473 * @beaninfo
474 * hidden: true
475 * description: the RootPane object for this window.
476 */
477 protected void setRootPane(JRootPane root) {
478 if(rootPane != null) {
479 remove(rootPane);
480 }
481 rootPane = root;
482 if(rootPane != null) {
483 boolean checkingEnabled = isRootPaneCheckingEnabled();
484 try {
485 setRootPaneCheckingEnabled(false);
486 add(rootPane, BorderLayout.CENTER);
487 }
488 finally {
489 setRootPaneCheckingEnabled(checkingEnabled);
490 }
491 }
492 }
493
494
495 /**
496 * Returns the <code>Container</code> which is the <code>contentPane</code>
497 * for this window.
498 *
499 * @return the <code>contentPane</code> property
500 * @see #setContentPane
501 * @see RootPaneContainer#getContentPane
502 */
503 public Container getContentPane() {
504 return getRootPane().getContentPane();
505 }
506
507 /**
508 * Sets the <code>contentPane</code> property for this window.
509 * This method is called by the constructor.
510 *
511 * @param contentPane the new <code>contentPane</code>
512 *
513 * @exception IllegalComponentStateException (a runtime
514 * exception) if the content pane parameter is <code>null</code>
515 * @see #getContentPane
516 * @see RootPaneContainer#setContentPane
517 *
518 * @beaninfo
519 * hidden: true
520 * description: The client area of the window where child
521 * components are normally inserted.
522 */
523 public void setContentPane(Container contentPane) {
524 getRootPane().setContentPane(contentPane);
525 }
526
527 /**
528 * Returns the <code>layeredPane</code> object for this window.
529 *
530 * @return the <code>layeredPane</code> property
531 * @see #setLayeredPane
532 * @see RootPaneContainer#getLayeredPane
533 */
534 public JLayeredPane getLayeredPane() {
535 return getRootPane().getLayeredPane();
536 }
537
538 /**
539 * Sets the <code>layeredPane</code> property.
540 * This method is called by the constructor.
541 *
542 * @param layeredPane the new <code>layeredPane</code> object
543 *
544 * @exception IllegalComponentStateException (a runtime
545 * exception) if the content pane parameter is <code>null</code>
546 * @see #getLayeredPane
547 * @see RootPaneContainer#setLayeredPane
548 *
549 * @beaninfo
550 * hidden: true
551 * description: The pane which holds the various window layers.
552 */
553 public void setLayeredPane(JLayeredPane layeredPane) {
554 getRootPane().setLayeredPane(layeredPane);
555 }
556
557 /**
558 * Returns the <code>glassPane Component</code> for this window.
559 *
560 * @return the <code>glassPane</code> property
561 * @see #setGlassPane
562 * @see RootPaneContainer#getGlassPane
563 */
564 public Component getGlassPane() {
565 return getRootPane().getGlassPane();
566 }
567
568 /**
569 * Sets the <code>glassPane</code> property.
570 * This method is called by the constructor.
571 * @param glassPane the <code>glassPane</code> object for this window
572 *
573 * @see #getGlassPane
574 * @see RootPaneContainer#setGlassPane
575 *
576 * @beaninfo
577 * hidden: true
578 * description: A transparent pane used for menu rendering.
579 */
580 public void setGlassPane(Component glassPane) {
581 getRootPane().setGlassPane(glassPane);
582 }
583
584 /**
585 * {@inheritDoc}
586 *
587 * @since 1.6
588 */
589 public Graphics getGraphics() {
590 JComponent.getGraphicsInvoked(this);
591 return super.getGraphics();
592 }
593
594 /**
595 * Repaints the specified rectangle of this component within
596 * <code>time</code> milliseconds. Refer to <code>RepaintManager</code>
597 * for details on how the repaint is handled.
598 *
599 * @param time maximum time in milliseconds before update
600 * @param x the <i>x</i> coordinate
601 * @param y the <i>y</i> coordinate
602 * @param width the width
603 * @param height the height
604 * @see RepaintManager
605 * @since 1.6
606 */
607 public void repaint(long time, int x, int y, int width, int height) {
608 if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
609 RepaintManager.currentManager(this).addDirtyRegion(
610 this, x, y, width, height);
611 }
612 else {
613 super.repaint(time, x, y, width, height);
614 }
615 }
616
617 /**
618 * Returns a string representation of this <code>JWindow</code>.
619 * This method
620 * is intended to be used only for debugging purposes, and the
621 * content and format of the returned string may vary between
622 * implementations. The returned string may be empty but may not
623 * be <code>null</code>.
624 *
625 * @return a string representation of this <code>JWindow</code>
626 */
627 protected String paramString() {
628 String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
629 "true" : "false");
630
631 return super.paramString() +
632 ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
633 }
634
635
636/////////////////
637// Accessibility support
638////////////////
639
640 /** The accessible context property. */
641 protected AccessibleContext accessibleContext = null;
642
643 /**
644 * Gets the AccessibleContext associated with this JWindow.
645 * For JWindows, the AccessibleContext takes the form of an
646 * AccessibleJWindow.
647 * A new AccessibleJWindow instance is created if necessary.
648 *
649 * @return an AccessibleJWindow that serves as the
650 * AccessibleContext of this JWindow
651 */
652 public AccessibleContext getAccessibleContext() {
653 if (accessibleContext == null) {
654 accessibleContext = new AccessibleJWindow();
655 }
656 return accessibleContext;
657 }
658
659
660 /**
661 * This class implements accessibility support for the
662 * <code>JWindow</code> class. It provides an implementation of the
663 * Java Accessibility API appropriate to window user-interface
664 * elements.
665 */
666 protected class AccessibleJWindow extends AccessibleAWTWindow {
667 // everything is in the new parent, AccessibleAWTWindow
668 }
669
670}