0001 /*
0002 * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025 package java.awt;
0026
0027 import java.awt.peer.DialogPeer;
0028 import java.awt.event.*;
0029 import java.io.ObjectInputStream;
0030 import java.io.IOException;
0031 import java.util.Iterator;
0032 import java.util.concurrent.atomic.AtomicLong;
0033 import java.security.AccessController;
0034 import java.security.PrivilegedAction;
0035 import javax.accessibility.*;
0036 import sun.awt.AppContext;
0037 import sun.awt.SunToolkit;
0038 import sun.awt.PeerEvent;
0039 import sun.awt.util.IdentityArrayList;
0040 import sun.awt.util.IdentityLinkedList;
0041 import sun.security.util.SecurityConstants;
0042
0043 /**
0044 * A Dialog is a top-level window with a title and a border
0045 * that is typically used to take some form of input from the user.
0046 *
0047 * The size of the dialog includes any area designated for the
0048 * border. The dimensions of the border area can be obtained
0049 * using the <code>getInsets</code> method, however, since
0050 * these dimensions are platform-dependent, a valid insets
0051 * value cannot be obtained until the dialog is made displayable
0052 * by either calling <code>pack</code> or <code>show</code>.
0053 * Since the border area is included in the overall size of the
0054 * dialog, the border effectively obscures a portion of the dialog,
0055 * constraining the area available for rendering and/or displaying
0056 * subcomponents to the rectangle which has an upper-left corner
0057 * location of <code>(insets.left, insets.top)</code>, and has a size of
0058 * <code>width - (insets.left + insets.right)</code> by
0059 * <code>height - (insets.top + insets.bottom)</code>.
0060 * <p>
0061 * The default layout for a dialog is <code>BorderLayout</code>.
0062 * <p>
0063 * A dialog may have its native decorations (i.e. Frame & Titlebar) turned off
0064 * with <code>setUndecorated</code>. This can only be done while the dialog
0065 * is not {@link Component#isDisplayable() displayable}.
0066 * <p>
0067 * A dialog may have another window as its owner when it's constructed. When
0068 * the owner window of a visible dialog is minimized, the dialog will
0069 * automatically be hidden from the user. When the owner window is subsequently
0070 * restored, the dialog is made visible to the user again.
0071 * <p>
0072 * In a multi-screen environment, you can create a <code>Dialog</code>
0073 * on a different screen device than its owner. See {@link java.awt.Frame} for
0074 * more information.
0075 * <p>
0076 * A dialog can be either modeless (the default) or modal. A modal
0077 * dialog is one which blocks input to some other top-level windows
0078 * in the application, except for any windows created with the dialog
0079 * as their owner. See <a href="doc-files/Modality.html">AWT Modality</a>
0080 * specification for details.
0081 * <p>
0082 * Dialogs are capable of generating the following
0083 * <code>WindowEvents</code>:
0084 * <code>WindowOpened</code>, <code>WindowClosing</code>,
0085 * <code>WindowClosed</code>, <code>WindowActivated</code>,
0086 * <code>WindowDeactivated</code>, <code>WindowGainedFocus</code>,
0087 * <code>WindowLostFocus</code>.
0088 *
0089 * @see WindowEvent
0090 * @see Window#addWindowListener
0091 *
0092 * @version 1.137, 06/05/07
0093 * @author Sami Shaio
0094 * @author Arthur van Hoff
0095 * @since JDK1.0
0096 */
0097 public class Dialog extends Window {
0098
0099 static {
0100 /* ensure that the necessary native libraries are loaded */
0101 Toolkit.loadLibraries();
0102 if (!GraphicsEnvironment.isHeadless()) {
0103 initIDs();
0104 }
0105 }
0106
0107 /**
0108 * A dialog's resizable property. Will be true
0109 * if the Dialog is to be resizable, otherwise
0110 * it will be false.
0111 *
0112 * @serial
0113 * @see #setResizable(boolean)
0114 */
0115 boolean resizable = true;
0116
0117 /**
0118 * This field indicates whether the dialog is undecorated.
0119 * This property can only be changed while the dialog is not displayable.
0120 * <code>undecorated</code> will be true if the dialog is
0121 * undecorated, otherwise it will be false.
0122 *
0123 * @serial
0124 * @see #setUndecorated(boolean)
0125 * @see #isUndecorated()
0126 * @see Component#isDisplayable()
0127 * @since 1.4
0128 */
0129 boolean undecorated = false;
0130
0131 /**
0132 * Modal dialogs block all input to some top-level windows.
0133 * Whether a particular window is blocked depends on dialog's type
0134 * of modality; this is called the "scope of blocking". The
0135 * <code>ModalityType</code> enum specifies modal types and their
0136 * associated scopes.
0137 *
0138 * @see Dialog#getModalityType
0139 * @see Dialog#setModalityType
0140 * @see Toolkit#isModalityTypeSupported
0141 *
0142 * @since 1.6
0143 */
0144 public static enum ModalityType {
0145 /**
0146 * <code>MODELESS</code> dialog doesn't block any top-level windows.
0147 */
0148 MODELESS,
0149 /**
0150 * A <code>DOCUMENT_MODAL</code> dialog blocks input to all top-level windows
0151 * from the same document except those from its own child hierarchy.
0152 * A document is a top-level window without an owner. It may contain child
0153 * windows that, together with the top-level window are treated as a single
0154 * solid document. Since every top-level window must belong to some
0155 * document, its root can be found as the top-nearest window without an owner.
0156 */
0157 DOCUMENT_MODAL,
0158 /**
0159 * An <code>APPLICATION_MODAL</code> dialog blocks all top-level windows
0160 * from the same Java application except those from its own child hierarchy.
0161 * If there are several applets launched in a browser, they can be
0162 * treated either as separate applications or a single one. This behavior
0163 * is implementation-dependent.
0164 */
0165 APPLICATION_MODAL,
0166 /**
0167 * A <code>TOOLKIT_MODAL</code> dialog blocks all top-level windows run
0168 * from the same toolkit except those from its own child hierarchy. If there
0169 * are several applets launched in a browser, all of them run with the same
0170 * toolkit; thus, a toolkit-modal dialog displayed by an applet may affect
0171 * other applets and all windows of the browser instance which embeds the
0172 * Java runtime environment for this toolkit.
0173 * Special <code>AWTPermission</code> "toolkitModality" must be granted to use
0174 * toolkit-modal dialogs. If a <code>TOOLKIT_MODAL</code> dialog is being created
0175 * and this permission is not granted, a <code>SecurityException</code> will be
0176 * thrown, and no dialog will be created. If a modality type is being changed
0177 * to <code>TOOLKIT_MODAL</code> and this permission is not granted, a
0178 * <code>SecurityException</code> will be thrown, and the modality type will
0179 * be left unchanged.
0180 */
0181 TOOLKIT_MODAL
0182 };
0183
0184 /**
0185 * Default modality type for modal dialogs. The default modality type is
0186 * <code>APPLICATION_MODAL</code>. Calling the oldstyle <code>setModal(true)</code>
0187 * is equal to <code>setModalityType(DEFAULT_MODALITY_TYPE)</code>.
0188 *
0189 * @see java.awt.Dialog.ModalityType
0190 * @see java.awt.Dialog#setModal
0191 *
0192 * @since 1.6
0193 */
0194 public final static ModalityType DEFAULT_MODALITY_TYPE = ModalityType.APPLICATION_MODAL;
0195
0196 /**
0197 * True if this dialog is modal, false is the dialog is modeless.
0198 * A modal dialog blocks user input to some application top-level
0199 * windows. This field is kept only for backwards compatibility. Use the
0200 * {@link Dialog.ModalityType ModalityType} enum instead.
0201 *
0202 * @serial
0203 *
0204 * @see #isModal
0205 * @see #setModal
0206 * @see #getModalityType
0207 * @see #setModalityType
0208 * @see ModalityType
0209 * @see ModalityType#MODELESS
0210 * @see #DEFAULT_MODALITY_TYPE
0211 */
0212 boolean modal;
0213
0214 /**
0215 * Modality type of this dialog. If the dialog's modality type is not
0216 * {@link Dialog.ModalityType#MODELESS ModalityType.MODELESS}, it blocks all
0217 * user input to some application top-level windows.
0218 *
0219 * @serial
0220 *
0221 * @see ModalityType
0222 * @see #getModalityType
0223 * @see #setModalityType
0224 *
0225 * @since 1.6
0226 */
0227 ModalityType modalityType;
0228
0229 /**
0230 * Any top-level window can be marked not to be blocked by modal
0231 * dialogs. This is called "modal exclusion". This enum specifies
0232 * the possible modal exclusion types.
0233 *
0234 * @see Window#getModalExclusionType
0235 * @see Window#setModalExclusionType
0236 * @see Toolkit#isModalExclusionTypeSupported
0237 *
0238 * @since 1.6
0239 */
0240 public static enum ModalExclusionType {
0241 /**
0242 * No modal exclusion.
0243 */
0244 NO_EXCLUDE,
0245 /**
0246 * <code>APPLICATION_EXCLUDE</code> indicates that a top-level window
0247 * won't be blocked by any application-modal dialogs. Also, it isn't
0248 * blocked by document-modal dialogs from outside of its child hierarchy.
0249 */
0250 APPLICATION_EXCLUDE,
0251 /**
0252 * <code>TOOLKIT_EXCLUDE</code> indicates that a top-level window
0253 * won't be blocked by application-modal or toolkit-modal dialogs. Also,
0254 * it isn't blocked by document-modal dialogs from outside of its
0255 * child hierarchy.
0256 * The "toolkitModality" <code>AWTPermission</code> must be granted
0257 * for this exclusion. If an exclusion property is being changed to
0258 * <code>TOOLKIT_EXCLUDE</code> and this permission is not granted, a
0259 * <code>SecurityEcxeption</code> will be thrown, and the exclusion
0260 * property will be left unchanged.
0261 */
0262 TOOLKIT_EXCLUDE
0263 };
0264
0265 /**
0266 * @since 1.6
0267 */
0268 private final static ModalExclusionType DEFAULT_MODAL_EXCLUSION_TYPE = ModalExclusionType.APPLICATION_EXCLUDE;
0269
0270 /* operations with this list should be synchronized on tree lock*/
0271 transient static IdentityArrayList<Dialog> modalDialogs = new IdentityArrayList<Dialog>();
0272
0273 transient IdentityArrayList<Window> blockedWindows = new IdentityArrayList<Window>();
0274
0275 /**
0276 * Specifies the title of the Dialog.
0277 * This field can be null.
0278 *
0279 * @serial
0280 * @see #getTitle()
0281 * @see #setTitle(String)
0282 */
0283 String title;
0284
0285 private transient volatile boolean keepBlockingEDT = false;
0286 private transient volatile boolean keepBlockingCT = false;
0287
0288 private transient ModalEventFilter modalFilter;
0289
0290 /*
0291 * Indicates that this dialog is being hidden. This flag is set to true at
0292 * the beginning of hide() and to false at the end of hide().
0293 *
0294 * @see #hide()
0295 * @see #hideAndDisposePreHandler()
0296 * @see #hideAndDisposeHandler()
0297 * @see #shouldBlock()
0298 */
0299 transient volatile boolean isInHide = false;
0300
0301 /*
0302 * Indicates that this dialog is being disposed. This flag is set to true at
0303 * the beginning of doDispose() and to false at the end of doDispose().
0304 *
0305 * @see #hide()
0306 * @see #hideAndDisposePreHandler()
0307 * @see #hideAndDisposeHandler()
0308 * @see #doDispose()
0309 */
0310 transient volatile boolean isInDispose = false;
0311
0312 private static final String base = "dialog";
0313 private static int nameCounter = 0;
0314
0315 /*
0316 * JDK 1.1 serialVersionUID
0317 */
0318 private static final long serialVersionUID = 5920926903803293709L;
0319
0320 /**
0321 * Constructs an initially invisible, modeless <code>Dialog</code> with
0322 * the specified owner <code>Frame</code> and an empty title.
0323 *
0324 * @param owner the owner of the dialog or <code>null</code> if
0325 * this dialog has no owner
0326 * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
0327 * <code>GraphicsConfiguration</code> is not from a screen device
0328 * @exception HeadlessException when
0329 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0330 *
0331 * @see java.awt.GraphicsEnvironment#isHeadless
0332 * @see Component#setSize
0333 * @see Component#setVisible
0334 */
0335 public Dialog(Frame owner) {
0336 this (owner, "", false);
0337 }
0338
0339 /**
0340 * Constructs an initially invisible <code>Dialog</code> with the specified
0341 * owner <code>Frame</code> and modality and an empty title.
0342 *
0343 * @param owner the owner of the dialog or <code>null</code> if
0344 * this dialog has no owner
0345 * @param modal specifes whether dialog blocks user input to other top-level
0346 * windows when shown. If <code>false</code>, the dialog is <code>MODELESS</code>;
0347 * if <code>true</code>, the modality type property is set to
0348 * <code>DEFAULT_MODALITY_TYPE</code>
0349 * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
0350 * <code>GraphicsConfiguration</code> is not from a screen device
0351 * @exception HeadlessException when
0352 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0353 *
0354 * @see java.awt.Dialog.ModalityType
0355 * @see java.awt.Dialog.ModalityType#MODELESS
0356 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
0357 * @see java.awt.Dialog#setModal
0358 * @see java.awt.Dialog#setModalityType
0359 * @see java.awt.GraphicsEnvironment#isHeadless
0360 */
0361 public Dialog(Frame owner, boolean modal) {
0362 this (owner, "", modal);
0363 }
0364
0365 /**
0366 * Constructs an initially invisible, modeless <code>Dialog</code> with
0367 * the specified owner <code>Frame</code> and title.
0368 *
0369 * @param owner the owner of the dialog or <code>null</code> if
0370 * this dialog has no owner
0371 * @param title the title of the dialog or <code>null</code> if this dialog
0372 * has no title
0373 * @exception IllegalArgumentException if the <code>owner</code>'s
0374 * <code>GraphicsConfiguration</code> is not from a screen device
0375 * @exception HeadlessException when
0376 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0377 *
0378 * @see java.awt.GraphicsEnvironment#isHeadless
0379 * @see Component#setSize
0380 * @see Component#setVisible
0381 */
0382 public Dialog(Frame owner, String title) {
0383 this (owner, title, false);
0384 }
0385
0386 /**
0387 * Constructs an initially invisible <code>Dialog</code> with the
0388 * specified owner <code>Frame</code>, title and modality.
0389 *
0390 * @param owner the owner of the dialog or <code>null</code> if
0391 * this dialog has no owner
0392 * @param title the title of the dialog or <code>null</code> if this dialog
0393 * has no title
0394 * @param modal specifes whether dialog blocks user input to other top-level
0395 * windows when shown. If <code>false</code>, the dialog is <code>MODELESS</code>;
0396 * if <code>true</code>, the modality type property is set to
0397 * <code>DEFAULT_MODALITY_TYPE</code>
0398 * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
0399 * <code>GraphicsConfiguration</code> is not from a screen device
0400 * @exception HeadlessException when
0401 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0402 *
0403 * @see java.awt.Dialog.ModalityType
0404 * @see java.awt.Dialog.ModalityType#MODELESS
0405 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
0406 * @see java.awt.Dialog#setModal
0407 * @see java.awt.Dialog#setModalityType
0408 * @see java.awt.GraphicsEnvironment#isHeadless
0409 * @see Component#setSize
0410 * @see Component#setVisible
0411 */
0412 public Dialog(Frame owner, String title, boolean modal) {
0413 this (owner, title, modal ? DEFAULT_MODALITY_TYPE
0414 : ModalityType.MODELESS);
0415 }
0416
0417 /**
0418 * Constructs an initially invisible <code>Dialog</code> with the specified owner
0419 * <code>Frame</code>, title, modality, and <code>GraphicsConfiguration</code>.
0420 * @param owner the owner of the dialog or <code>null</code> if this dialog
0421 * has no owner
0422 * @param title the title of the dialog or <code>null</code> if this dialog
0423 * has no title
0424 * @param modal specifes whether dialog blocks user input to other top-level
0425 * windows when shown. If <code>false</code>, the dialog is <code>MODELESS</code>;
0426 * if <code>true</code>, the modality type property is set to
0427 * <code>DEFAULT_MODALITY_TYPE</code>
0428 * @param gc the <code>GraphicsConfiguration</code> of the target screen device;
0429 * if <code>null</code>, the default system <code>GraphicsConfiguration</code>
0430 * is assumed
0431 * @exception java.lang.IllegalArgumentException if <code>gc</code>
0432 * is not from a screen device
0433 * @exception HeadlessException when
0434 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0435 *
0436 * @see java.awt.Dialog.ModalityType
0437 * @see java.awt.Dialog.ModalityType#MODELESS
0438 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
0439 * @see java.awt.Dialog#setModal
0440 * @see java.awt.Dialog#setModalityType
0441 * @see java.awt.GraphicsEnvironment#isHeadless
0442 * @see Component#setSize
0443 * @see Component#setVisible
0444 * @since 1.4
0445 */
0446 public Dialog(Frame owner, String title, boolean modal,
0447 GraphicsConfiguration gc) {
0448 this (owner, title, modal ? DEFAULT_MODALITY_TYPE
0449 : ModalityType.MODELESS, gc);
0450 }
0451
0452 /**
0453 * Constructs an initially invisible, modeless <code>Dialog</code> with
0454 * the specified owner <code>Dialog</code> and an empty title.
0455 *
0456 * @param owner the owner of the dialog or <code>null</code> if this
0457 * dialog has no owner
0458 * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
0459 * <code>GraphicsConfiguration</code> is not from a screen device
0460 * @exception HeadlessException when
0461 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0462 * @see java.awt.GraphicsEnvironment#isHeadless
0463 * @since 1.2
0464 */
0465 public Dialog(Dialog owner) {
0466 this (owner, "", false);
0467 }
0468
0469 /**
0470 * Constructs an initially invisible, modeless <code>Dialog</code>
0471 * with the specified owner <code>Dialog</code> and title.
0472 *
0473 * @param owner the owner of the dialog or <code>null</code> if this
0474 * has no owner
0475 * @param title the title of the dialog or <code>null</code> if this dialog
0476 * has no title
0477 * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
0478 * <code>GraphicsConfiguration</code> is not from a screen device
0479 * @exception HeadlessException when
0480 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0481 *
0482 * @see java.awt.GraphicsEnvironment#isHeadless
0483 * @since 1.2
0484 */
0485 public Dialog(Dialog owner, String title) {
0486 this (owner, title, false);
0487 }
0488
0489 /**
0490 * Constructs an initially invisible <code>Dialog</code> with the
0491 * specified owner <code>Dialog</code>, title, and modality.
0492 *
0493 * @param owner the owner of the dialog or <code>null</code> if this
0494 * dialog has no owner
0495 * @param title the title of the dialog or <code>null</code> if this
0496 * dialog has no title
0497 * @param modal specifes whether dialog blocks user input to other top-level
0498 * windows when shown. If <code>false</code>, the dialog is <code>MODELESS</code>;
0499 * if <code>true</code>, the modality type property is set to
0500 * <code>DEFAULT_MODALITY_TYPE</code>
0501 * @exception IllegalArgumentException if the <code>owner</code>'s
0502 * <code>GraphicsConfiguration</code> is not from a screen device
0503 * @exception HeadlessException when
0504 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0505 *
0506 * @see java.awt.Dialog.ModalityType
0507 * @see java.awt.Dialog.ModalityType#MODELESS
0508 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
0509 * @see java.awt.Dialog#setModal
0510 * @see java.awt.Dialog#setModalityType
0511 * @see java.awt.GraphicsEnvironment#isHeadless
0512 *
0513 * @since 1.2
0514 */
0515 public Dialog(Dialog owner, String title, boolean modal) {
0516 this (owner, title, modal ? DEFAULT_MODALITY_TYPE
0517 : ModalityType.MODELESS);
0518 }
0519
0520 /**
0521 * Constructs an initially invisible <code>Dialog</code> with the
0522 * specified owner <code>Dialog</code>, title, modality and
0523 * <code>GraphicsConfiguration</code>.
0524 *
0525 * @param owner the owner of the dialog or <code>null</code> if this
0526 * dialog has no owner
0527 * @param title the title of the dialog or <code>null</code> if this
0528 * dialog has no title
0529 * @param modal specifes whether dialog blocks user input to other top-level
0530 * windows when shown. If <code>false</code>, the dialog is <code>MODELESS</code>;
0531 * if <code>true</code>, the modality type property is set to
0532 * <code>DEFAULT_MODALITY_TYPE</code>
0533 * @param gc the <code>GraphicsConfiguration</code> of the target screen device;
0534 * if <code>null</code>, the default system <code>GraphicsConfiguration</code>
0535 * is assumed
0536 * @exception java.lang.IllegalArgumentException if <code>gc</code>
0537 * is not from a screen device
0538 * @exception HeadlessException when
0539 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0540 *
0541 * @see java.awt.Dialog.ModalityType
0542 * @see java.awt.Dialog.ModalityType#MODELESS
0543 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
0544 * @see java.awt.Dialog#setModal
0545 * @see java.awt.Dialog#setModalityType
0546 * @see java.awt.GraphicsEnvironment#isHeadless
0547 * @see Component#setSize
0548 * @see Component#setVisible
0549 *
0550 * @since 1.4
0551 */
0552 public Dialog(Dialog owner, String title, boolean modal,
0553 GraphicsConfiguration gc) {
0554 this (owner, title, modal ? DEFAULT_MODALITY_TYPE
0555 : ModalityType.MODELESS, gc);
0556 }
0557
0558 /**
0559 * Constructs an initially invisible, modeless <code>Dialog</code> with the
0560 * specified owner <code>Window</code> and an empty title.
0561 *
0562 * @param owner the owner of the dialog. The owner must be an instance of
0563 * {@link java.awt.Dialog Dialog}, {@link java.awt.Frame Frame}, any
0564 * of their descendents or <code>null</code>
0565 *
0566 * @exception java.lang.IllegalArgumentException if the <code>owner</code>
0567 * is not an instance of {@link java.awt.Dialog Dialog} or {@link
0568 * java.awt.Frame Frame}
0569 * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
0570 * <code>GraphicsConfiguration</code> is not from a screen device
0571 * @exception HeadlessException when
0572 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0573 *
0574 * @see java.awt.GraphicsEnvironment#isHeadless
0575 *
0576 * @since 1.6
0577 */
0578 public Dialog(Window owner) {
0579 this (owner, null, ModalityType.MODELESS);
0580 }
0581
0582 /**
0583 * Constructs an initially invisible, modeless <code>Dialog</code> with
0584 * the specified owner <code>Window</code> and title.
0585 *
0586 * @param owner the owner of the dialog. The owner must be an instance of
0587 * {@link java.awt.Dialog Dialog}, {@link java.awt.Frame Frame}, any
0588 * of their descendents or <code>null</code>
0589 * @param title the title of the dialog or <code>null</code> if this dialog
0590 * has no title
0591 *
0592 * @exception java.lang.IllegalArgumentException if the <code>owner</code>
0593 * is not an instance of {@link java.awt.Dialog Dialog} or {@link
0594 * java.awt.Frame Frame}
0595 * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
0596 * <code>GraphicsConfiguration</code> is not from a screen device
0597 * @exception HeadlessException when
0598 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0599 *
0600 * @see java.awt.GraphicsEnvironment#isHeadless
0601 *
0602 * @since 1.6
0603 */
0604 public Dialog(Window owner, String title) {
0605 this (owner, title, ModalityType.MODELESS);
0606 }
0607
0608 /**
0609 * Constructs an initially invisible <code>Dialog</code> with the
0610 * specified owner <code>Window</code> and modality and an empty title.
0611 *
0612 * @param owner the owner of the dialog. The owner must be an instance of
0613 * {@link java.awt.Dialog Dialog}, {@link java.awt.Frame Frame}, any
0614 * of their descendents or <code>null</code>
0615 * @param modalityType specifies whether dialog blocks input to other
0616 * windows when shown. <code>null</code> value and unsupported modality
0617 * types are equivalent to <code>MODELESS</code>
0618 *
0619 * @exception java.lang.IllegalArgumentException if the <code>owner</code>
0620 * is not an instance of {@link java.awt.Dialog Dialog} or {@link
0621 * java.awt.Frame Frame}
0622 * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
0623 * <code>GraphicsConfiguration</code> is not from a screen device
0624 * @exception HeadlessException when
0625 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0626 * @exception SecurityException if the calling thread does not have permission
0627 * to create modal dialogs with the given <code>modalityType</code>
0628 *
0629 * @see java.awt.Dialog.ModalityType
0630 * @see java.awt.Dialog#setModal
0631 * @see java.awt.Dialog#setModalityType
0632 * @see java.awt.GraphicsEnvironment#isHeadless
0633 * @see java.awt.Toolkit#isModalityTypeSupported
0634 *
0635 * @since 1.6
0636 */
0637 public Dialog(Window owner, ModalityType modalityType) {
0638 this (owner, null, modalityType);
0639 }
0640
0641 /**
0642 * Constructs an initially invisible <code>Dialog</code> with the
0643 * specified owner <code>Window</code>, title and modality.
0644 *
0645 * @param owner the owner of the dialog. The owner must be an instance of
0646 * {@link java.awt.Dialog Dialog}, {@link java.awt.Frame Frame}, any
0647 * of their descendents or <code>null</code>
0648 * @param title the title of the dialog or <code>null</code> if this dialog
0649 * has no title
0650 * @param modalityType specifies whether dialog blocks input to other
0651 * windows when shown. <code>null</code> value and unsupported modality
0652 * types are equivalent to <code>MODELESS</code>
0653 *
0654 * @exception java.lang.IllegalArgumentException if the <code>owner</code>
0655 * is not an instance of {@link java.awt.Dialog Dialog} or {@link
0656 * java.awt.Frame Frame}
0657 * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
0658 * <code>GraphicsConfiguration</code> is not from a screen device
0659 * @exception HeadlessException when
0660 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0661 * @exception SecurityException if the calling thread does not have permission
0662 * to create modal dialogs with the given <code>modalityType</code>
0663 *
0664 * @see java.awt.Dialog.ModalityType
0665 * @see java.awt.Dialog#setModal
0666 * @see java.awt.Dialog#setModalityType
0667 * @see java.awt.GraphicsEnvironment#isHeadless
0668 * @see java.awt.Toolkit#isModalityTypeSupported
0669 *
0670 * @since 1.6
0671 */
0672 public Dialog(Window owner, String title, ModalityType modalityType) {
0673 super (owner);
0674
0675 if ((owner != null) && !(owner instanceof Frame)
0676 && !(owner instanceof Dialog)) {
0677 throw new IllegalArgumentException("Wrong parent window");
0678 }
0679
0680 this .title = title;
0681 setModalityType(modalityType);
0682 SunToolkit.checkAndSetPolicy(this , false);
0683 }
0684
0685 /**
0686 * Constructs an initially invisible <code>Dialog</code> with the
0687 * specified owner <code>Window</code>, title, modality and
0688 * <code>GraphicsConfiguration</code>.
0689 *
0690 * @param owner the owner of the dialog. The owner must be an instance of
0691 * {@link java.awt.Dialog Dialog}, {@link java.awt.Frame Frame}, any
0692 * of their descendents or <code>null</code>
0693 * @param title the title of the dialog or <code>null</code> if this dialog
0694 * has no title
0695 * @param modalityType specifies whether dialog blocks input to other
0696 * windows when shown. <code>null</code> value and unsupported modality
0697 * types are equivalent to <code>MODELESS</code>
0698 * @param gc the <code>GraphicsConfiguration</code> of the target screen device;
0699 * if <code>null</code>, the default system <code>GraphicsConfiguration</code>
0700 * is assumed
0701 *
0702 * @exception java.lang.IllegalArgumentException if the <code>owner</code>
0703 * is not an instance of {@link java.awt.Dialog Dialog} or {@link
0704 * java.awt.Frame Frame}
0705 * @exception java.lang.IllegalArgumentException if <code>gc</code>
0706 * is not from a screen device
0707 * @exception HeadlessException when
0708 * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
0709 * @exception SecurityException if the calling thread does not have permission
0710 * to create modal dialogs with the given <code>modalityType</code>
0711 *
0712 * @see java.awt.Dialog.ModalityType
0713 * @see java.awt.Dialog#setModal
0714 * @see java.awt.Dialog#setModalityType
0715 * @see java.awt.GraphicsEnvironment#isHeadless
0716 * @see java.awt.Toolkit#isModalityTypeSupported
0717 *
0718 * @since 1.6
0719 */
0720 public Dialog(Window owner, String title,
0721 ModalityType modalityType, GraphicsConfiguration gc) {
0722 super (owner, gc);
0723
0724 if ((owner != null) && !(owner instanceof Frame)
0725 && !(owner instanceof Dialog)) {
0726 throw new IllegalArgumentException("wrong owner window");
0727 }
0728
0729 this .title = title;
0730 setModalityType(modalityType);
0731 SunToolkit.checkAndSetPolicy(this , false);
0732 }
0733
0734 /**
0735 * Construct a name for this component. Called by getName() when the
0736 * name is null.
0737 */
0738 String constructComponentName() {
0739 synchronized (Dialog.class) {
0740 return base + nameCounter++;
0741 }
0742 }
0743
0744 /**
0745 * Makes this Dialog displayable by connecting it to
0746 * a native screen resource. Making a dialog displayable will
0747 * cause any of its children to be made displayable.
0748 * This method is called internally by the toolkit and should
0749 * not be called directly by programs.
0750 * @see Component#isDisplayable
0751 * @see #removeNotify
0752 */
0753 public void addNotify() {
0754 synchronized (getTreeLock()) {
0755 if (parent != null && parent.getPeer() == null) {
0756 parent.addNotify();
0757 }
0758
0759 if (peer == null) {
0760 peer = getToolkit().createDialog(this );
0761 }
0762 super .addNotify();
0763 }
0764 }
0765
0766 /**
0767 * Indicates whether the dialog is modal.
0768 * <p>
0769 * This method is obsolete and is kept for backwards compatiblity only.
0770 * Use {@link #getModalityType getModalityType()} instead.
0771 *
0772 * @return <code>true</code> if this dialog window is modal;
0773 * <code>false</code> otherwise
0774 *
0775 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
0776 * @see java.awt.Dialog.ModalityType#MODELESS
0777 * @see java.awt.Dialog#setModal
0778 * @see java.awt.Dialog#getModalityType
0779 * @see java.awt.Dialog#setModalityType
0780 */
0781 public boolean isModal() {
0782 return isModal_NoClientCode();
0783 }
0784
0785 final boolean isModal_NoClientCode() {
0786 return modalityType != ModalityType.MODELESS;
0787 }
0788
0789 /**
0790 * Specifies whether this dialog should be modal.
0791 * <p>
0792 * This method is obsolete and is kept for backwards compatibility only.
0793 * Use {@link #setModalityType setModalityType()} instead.
0794 * <p>
0795 * Note: changing modality of the visible dialog may have no effect
0796 * until it is hidden and then shown again.
0797 *
0798 * @param modal specifies whether dialog blocks input to other windows
0799 * when shown; calling to <code>setModal(true)</code> is equivalent to
0800 * <code>setModalityType(Dialog.DEFAULT_MODALITY_TYPE)</code>, and
0801 * calling to <code>setModal(false)</code> is equvivalent to
0802 * <code>setModalityType(Dialog.ModalityType.MODELESS)</code>
0803 *
0804 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
0805 * @see java.awt.Dialog.ModalityType#MODELESS
0806 * @see java.awt.Dialog#isModal
0807 * @see java.awt.Dialog#getModalityType
0808 * @see java.awt.Dialog#setModalityType
0809 *
0810 * @since 1.1
0811 */
0812 public void setModal(boolean modal) {
0813 this .modal = modal;
0814 setModalityType(modal ? DEFAULT_MODALITY_TYPE
0815 : ModalityType.MODELESS);
0816 }
0817
0818 /**
0819 * Returns the modality type of this dialog.
0820 *
0821 * @return modality type of this dialog
0822 *
0823 * @see java.awt.Dialog#setModalityType
0824 *
0825 * @since 1.6
0826 */
0827 public ModalityType getModalityType() {
0828 return modalityType;
0829 }
0830
0831 /**
0832 * Sets the modality type for this dialog. See {@link
0833 * java.awt.Dialog.ModalityType ModalityType} for possible modality types.
0834 * <p>
0835 * If the given modality type is not supported, <code>MODELESS</code>
0836 * is used. You may want to call <code>getModalityType()</code> after calling
0837 * this method to ensure that the modality type has been set.
0838 * <p>
0839 * Note: changing modality of the visible dialog may have no effect
0840 * until it is hidden and then shown again.
0841 *
0842 * @param type specifies whether dialog blocks input to other
0843 * windows when shown. <code>null</code> value and unsupported modality
0844 * types are equivalent to <code>MODELESS</code>
0845 * @exception SecurityException if the calling thread does not have permission
0846 * to create modal dialogs with the given <code>modalityType</code>
0847 *
0848 * @see java.awt.Dialog#getModalityType
0849 * @see java.awt.Toolkit#isModalityTypeSupported
0850 *
0851 * @since 1.6
0852 */
0853 public void setModalityType(ModalityType type) {
0854 if (type == null) {
0855 type = Dialog.ModalityType.MODELESS;
0856 }
0857 if (!Toolkit.getDefaultToolkit().isModalityTypeSupported(type)) {
0858 type = Dialog.ModalityType.MODELESS;
0859 }
0860 if (modalityType == type) {
0861 return;
0862 }
0863 if (type == ModalityType.TOOLKIT_MODAL) {
0864 SecurityManager sm = System.getSecurityManager();
0865 if (sm != null) {
0866 sm
0867 .checkPermission(SecurityConstants.TOOLKIT_MODALITY_PERMISSION);
0868 }
0869 }
0870 modalityType = type;
0871 modal = (modalityType != ModalityType.MODELESS);
0872 }
0873
0874 /**
0875 * Gets the title of the dialog. The title is displayed in the
0876 * dialog's border.
0877 * @return the title of this dialog window. The title may be
0878 * <code>null</code>.
0879 * @see java.awt.Dialog#setTitle
0880 */
0881 public String getTitle() {
0882 return title;
0883 }
0884
0885 /**
0886 * Sets the title of the Dialog.
0887 * @param title the title displayed in the dialog's border;
0888 * a null value results in an empty title
0889 * @see #getTitle
0890 */
0891 public void setTitle(String title) {
0892 String oldTitle = this .title;
0893
0894 synchronized (this ) {
0895 this .title = title;
0896 DialogPeer peer = (DialogPeer) this .peer;
0897 if (peer != null) {
0898 peer.setTitle(title);
0899 }
0900 }
0901 firePropertyChange("title", oldTitle, title);
0902 }
0903
0904 /**
0905 * @return true if we actually showed, false if we just called toFront()
0906 */
0907 private boolean conditionalShow(Component toFocus, AtomicLong time) {
0908 boolean retval;
0909
0910 closeSplashScreen();
0911
0912 synchronized (getTreeLock()) {
0913 if (peer == null) {
0914 addNotify();
0915 }
0916 validate();
0917 if (visible) {
0918 toFront();
0919 retval = false;
0920 } else {
0921 visible = retval = true;
0922
0923 // check if this dialog should be modal blocked BEFORE calling peer.show(),
0924 // otherwise, a pair of FOCUS_GAINED and FOCUS_LOST may be mistakenly
0925 // generated for the dialog
0926 if (!isModal()) {
0927 checkShouldBeBlocked(this );
0928 } else {
0929 modalDialogs.add(this );
0930 modalShow();
0931 }
0932
0933 if (toFocus != null && time != null && isFocusable()
0934 && isEnabled() && !isModalBlocked()) {
0935 // keep the KeyEvents from being dispatched
0936 // until the focus has been transfered
0937 time.set(Toolkit.getEventQueue()
0938 .getMostRecentEventTimeEx());
0939 KeyboardFocusManager
0940 .getCurrentKeyboardFocusManager()
0941 .enqueueKeyEvents(time.get(), toFocus);
0942 }
0943
0944 peer.show(); // now guaranteed never to block
0945 if (isModalBlocked()) {
0946 modalBlocker.toFront();
0947 }
0948
0949 setLocationByPlatform(false);
0950 for (int i = 0; i < ownedWindowList.size(); i++) {
0951 Window child = ownedWindowList.elementAt(i).get();
0952 if ((child != null) && child.showWithParent) {
0953 child.show();
0954 child.showWithParent = false;
0955 } // endif
0956 } // endfor
0957 Window.updateChildFocusableWindowState(this );
0958
0959 createHierarchyEvents(
0960 HierarchyEvent.HIERARCHY_CHANGED,
0961 this ,
0962 parent,
0963 HierarchyEvent.SHOWING_CHANGED,
0964 Toolkit
0965 .enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
0966 if (componentListener != null
0967 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0
0968 || Toolkit
0969 .enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
0970 ComponentEvent e = new ComponentEvent(this ,
0971 ComponentEvent.COMPONENT_SHOWN);
0972 Toolkit.getEventQueue().postEvent(e);
0973 }
0974 }
0975 }
0976
0977 if (retval && (state & OPENED) == 0) {
0978 postWindowEvent(WindowEvent.WINDOW_OPENED);
0979 state |= OPENED;
0980 }
0981
0982 return retval;
0983 }
0984
0985 /**
0986 * Shows or hides this {@code Dialog} depending on the value of parameter
0987 * {@code b}.
0988 * @param b if {@code true}, makes the {@code Dialog} visible,
0989 * otherwise hides the {@code Dialog}.
0990 * If the dialog and/or its owner
0991 * are not yet displayable, both are made displayable. The
0992 * dialog will be validated prior to being made visible.
0993 * If {@code false}, hides the {@code Dialog} and then causes {@code setVisible(true)}
0994 * to return if it is currently blocked.
0995 * <p>
0996 * <b>Notes for modal dialogs</b>.
0997 * <ul>
0998 * <li>{@code setVisible(true)}: If the dialog is not already
0999 * visible, this call will not return until the dialog is
1000 * hidden by calling {@code setVisible(false)} or
1001 * {@code dispose}.
1002 * <li>{@code setVisible(false)}: Hides the dialog and then
1003 * returns on {@code setVisible(true)} if it is currently blocked.
1004 * <li>It is OK to call this method from the event dispatching
1005 * thread because the toolkit ensures that other events are
1006 * not blocked while this method is blocked.
1007 * </ul>
1008 * @see java.awt.Window#setVisible
1009 * @see java.awt.Window#dispose
1010 * @see java.awt.Component#isDisplayable
1011 * @see java.awt.Component#validate
1012 * @see java.awt.Dialog#isModal
1013 */
1014 public void setVisible(boolean b) {
1015 super .setVisible(b);
1016 }
1017
1018 /**
1019 * Stores the app context on which event dispatch thread the dialog
1020 * is being shown. Initialized in show(), used in hideAndDisposeHandler()
1021 */
1022 transient private AppContext showAppContext;
1023
1024 /**
1025 * Makes the {@code Dialog} visible. If the dialog and/or its owner
1026 * are not yet displayable, both are made displayable. The
1027 * dialog will be validated prior to being made visible.
1028 * If the dialog is already visible, this will bring the dialog
1029 * to the front.
1030 * <p>
1031 * If the dialog is modal and is not already visible, this call
1032 * will not return until the dialog is hidden by calling hide or
1033 * dispose. It is permissible to show modal dialogs from the event
1034 * dispatching thread because the toolkit will ensure that another
1035 * event pump runs while the one which invoked this method is blocked.
1036 * @see Component#hide
1037 * @see Component#isDisplayable
1038 * @see Component#validate
1039 * @see #isModal
1040 * @see Window#setVisible(boolean)
1041 * @deprecated As of JDK version 1.5, replaced by
1042 * {@link #setVisible(boolean) setVisible(boolean)}.
1043 */
1044 @Deprecated
1045 public void show() {
1046 beforeFirstShow = false;
1047 if (!isModal()) {
1048 conditionalShow(null, null);
1049 } else {
1050 // Set this variable before calling conditionalShow(). That
1051 // way, if the Dialog is hidden right after being shown, we
1052 // won't mistakenly block this thread.
1053 keepBlockingEDT = true;
1054 keepBlockingCT = true;
1055
1056 // Store the app context on which this dialog is being shown.
1057 // Event dispatch thread of this app context will be sleeping until
1058 // we wake it by any event from hideAndDisposeHandler().
1059 showAppContext = AppContext.getAppContext();
1060
1061 AtomicLong time = new AtomicLong();
1062 Component predictedFocusOwner = null;
1063 try {
1064 predictedFocusOwner = getMostRecentFocusOwner();
1065 if (conditionalShow(predictedFocusOwner, time)) {
1066 // We have two mechanisms for blocking: 1. If we're on the
1067 // EventDispatchThread, start a new event pump. 2. If we're
1068 // on any other thread, call wait() on the treelock.
1069
1070 modalFilter = ModalEventFilter
1071 .createFilterForDialog(this );
1072
1073 final Runnable pumpEventsForFilter = new Runnable() {
1074 public void run() {
1075 EventDispatchThread dispatchThread = (EventDispatchThread) Thread
1076 .currentThread();
1077 dispatchThread.pumpEventsForFilter(
1078 new Conditional() {
1079 public boolean evaluate() {
1080 synchronized (getTreeLock()) {
1081 return keepBlockingEDT
1082 && windowClosingException == null;
1083 }
1084 }
1085 }, modalFilter);
1086 }
1087 };
1088
1089 // if this dialog is toolkit-modal, the filter should be added
1090 // to all EDTs (for all AppContexts)
1091 if (modalityType == ModalityType.TOOLKIT_MODAL) {
1092 Iterator it = AppContext.getAppContexts()
1093 .iterator();
1094 while (it.hasNext()) {
1095 AppContext appContext = (AppContext) it
1096 .next();
1097 if (appContext == showAppContext) {
1098 continue;
1099 }
1100 EventQueue eventQueue = (EventQueue) appContext
1101 .get(AppContext.EVENT_QUEUE_KEY);
1102 // it may occur that EDT for appContext hasn't been started yet, so
1103 // we post an empty invocation event to trigger EDT initialization
1104 Runnable createEDT = new Runnable() {
1105 public void run() {
1106 };
1107 };
1108 eventQueue.postEvent(new InvocationEvent(
1109 this , createEDT));
1110 EventDispatchThread edt = eventQueue
1111 .getDispatchThread();
1112 edt.addEventFilter(modalFilter);
1113 }
1114 }
1115
1116 modalityPushed();
1117 try {
1118 if (EventQueue.isDispatchThread()) {
1119 /*
1120 * dispose SequencedEvent we are dispatching on current
1121 * AppContext, to prevent us from hang.
1122 *
1123 */
1124 // BugId 4531693 (son@sparc.spb.su)
1125 SequencedEvent currentSequencedEvent = KeyboardFocusManager
1126 .getCurrentKeyboardFocusManager()
1127 .getCurrentSequencedEvent();
1128 if (currentSequencedEvent != null) {
1129 currentSequencedEvent.dispose();
1130 }
1131
1132 /*
1133 * Event processing is done inside doPrivileged block so that
1134 * it wouldn't matter even if user code is on the stack
1135 * Fix for BugId 6300270
1136 */
1137
1138 AccessController
1139 .doPrivileged(new PrivilegedAction() {
1140 public Object run() {
1141 pumpEventsForFilter.run();
1142 return null;
1143 }
1144 });
1145 } else {
1146 synchronized (getTreeLock()) {
1147 Toolkit
1148 .getEventQueue()
1149 .postEvent(
1150 new PeerEvent(
1151 this ,
1152 pumpEventsForFilter,
1153 PeerEvent.PRIORITY_EVENT));
1154 while (keepBlockingCT
1155 && windowClosingException == null) {
1156 try {
1157 getTreeLock().wait();
1158 } catch (InterruptedException e) {
1159 break;
1160 }
1161 }
1162 }
1163 }
1164 } finally {
1165 modalityPopped();
1166 }
1167
1168 // if this dialog is toolkit-modal, its filter must be removed
1169 // from all EDTs (for all AppContexts)
1170 if (modalityType == ModalityType.TOOLKIT_MODAL) {
1171 Iterator it = AppContext.getAppContexts()
1172 .iterator();
1173 while (it.hasNext()) {
1174 AppContext appContext = (AppContext) it
1175 .next();
1176 if (appContext == showAppContext) {
1177 continue;
1178 }
1179 EventQueue eventQueue = (EventQueue) appContext
1180 .get(AppContext.EVENT_QUEUE_KEY);
1181 EventDispatchThread edt = eventQueue
1182 .getDispatchThread();
1183 edt.removeEventFilter(modalFilter);
1184 }
1185 }
1186
1187 if (windowClosingException != null) {
1188 windowClosingException.fillInStackTrace();
1189 throw windowClosingException;
1190 }
1191 }
1192 } finally {
1193 if (predictedFocusOwner != null) {
1194 // Restore normal key event dispatching
1195 KeyboardFocusManager
1196 .getCurrentKeyboardFocusManager()
1197 .dequeueKeyEvents(time.get(),
1198 predictedFocusOwner);
1199 }
1200 }
1201 }
1202 }
1203
1204 final void modalityPushed() {
1205 Toolkit tk = Toolkit.getDefaultToolkit();
1206 if (tk instanceof SunToolkit) {
1207 SunToolkit stk = (SunToolkit) tk;
1208 stk.notifyModalityPushed(this );
1209 }
1210 }
1211
1212 final void modalityPopped() {
1213 Toolkit tk = Toolkit.getDefaultToolkit();
1214 if (tk instanceof SunToolkit) {
1215 SunToolkit stk = (SunToolkit) tk;
1216 stk.notifyModalityPopped(this );
1217 }
1218 }
1219
1220 void interruptBlocking() {
1221 if (isModal()) {
1222 disposeImpl();
1223 } else if (windowClosingException != null) {
1224 windowClosingException.fillInStackTrace();
1225 windowClosingException.printStackTrace();
1226 windowClosingException = null;
1227 }
1228 }
1229
1230 final class WakingRunnable implements Runnable {
1231 public void run() {
1232 synchronized (getTreeLock()) {
1233 keepBlockingCT = false;
1234 getTreeLock().notifyAll();
1235 }
1236 }
1237 }
1238
1239 private void hideAndDisposePreHandler() {
1240 isInHide = true;
1241 synchronized (getTreeLock()) {
1242 if (keepBlockingEDT) {
1243 modalHide();
1244 // dialog can be shown and then disposed before its
1245 // modal filter is created
1246 if (modalFilter != null) {
1247 modalFilter.disable();
1248 }
1249 modalDialogs.remove(this );
1250 }
1251 }
1252 }
1253
1254 private void hideAndDisposeHandler() {
1255 synchronized (getTreeLock()) {
1256 if (keepBlockingEDT) {
1257 keepBlockingEDT = false;
1258 PeerEvent wakingEvent = new PeerEvent(this ,
1259 new WakingRunnable(), PeerEvent.PRIORITY_EVENT);
1260 AppContext curAppContext = AppContext.getAppContext();
1261 if (showAppContext != curAppContext) {
1262 // Wake up event dispatch thread on which the dialog was
1263 // initially shown
1264 SunToolkit.postEvent(showAppContext, wakingEvent);
1265 showAppContext = null;
1266 } else {
1267 Toolkit.getEventQueue().postEvent(wakingEvent);
1268 }
1269 }
1270 }
1271 isInHide = false;
1272 }
1273
1274 /**
1275 * Hides the Dialog and then causes {@code show} to return if it is currently
1276 * blocked.
1277 * @see Window#show
1278 * @see Window#dispose
1279 * @see Window#setVisible(boolean)
1280 * @deprecated As of JDK version 1.5, replaced by
1281 * {@link #setVisible(boolean) setVisible(boolean)}.
1282 */
1283 @Deprecated
1284 public void hide() {
1285 hideAndDisposePreHandler();
1286 super .hide();
1287 // fix for 5048370: if hide() is called from super.doDispose(), then
1288 // hideAndDisposeHandler() should not be called here as it will be called
1289 // at the end of doDispose()
1290 if (!isInDispose) {
1291 hideAndDisposeHandler();
1292 }
1293 }
1294
1295 /**
1296 * Disposes the Dialog and then causes show() to return if it is currently
1297 * blocked.
1298 */
1299 void doDispose() {
1300 // fix for 5048370: set isInDispose flag to true to prevent calling
1301 // to hideAndDisposeHandler() from hide()
1302 isInDispose = true;
1303 super .doDispose();
1304 hideAndDisposeHandler();
1305 isInDispose = false;
1306 }
1307
1308 /**
1309 * {@inheritDoc}
1310 * <p>
1311 * If this dialog is modal and blocks some windows, then all of them are
1312 * also sent to the back to keep them below the blocking dialog.
1313 *
1314 * @see java.awt.Window#toBack
1315 */
1316 public void toBack() {
1317 super .toBack();
1318 if (visible) {
1319 synchronized (getTreeLock()) {
1320 for (Window w : blockedWindows) {
1321 w.toBack_NoClientCode();
1322 }
1323 }
1324 }
1325 }
1326
1327 /**
1328 * Indicates whether this dialog is resizable by the user.
1329 * By default, all dialogs are initially resizable.
1330 * @return <code>true</code> if the user can resize the dialog;
1331 * <code>false</code> otherwise.
1332 * @see java.awt.Dialog#setResizable
1333 */
1334 public boolean isResizable() {
1335 return resizable;
1336 }
1337
1338 /**
1339 * Sets whether this dialog is resizable by the user.
1340 * @param resizable <code>true</code> if the user can
1341 * resize this dialog; <code>false</code> otherwise.
1342 * @see java.awt.Dialog#isResizable
1343 */
1344 public void setResizable(boolean resizable) {
1345 boolean testvalid = false;
1346
1347 synchronized (this ) {
1348 this .resizable = resizable;
1349 DialogPeer peer = (DialogPeer) this .peer;
1350 if (peer != null) {
1351 peer.setResizable(resizable);
1352 testvalid = true;
1353 }
1354 }
1355
1356 // On some platforms, changing the resizable state affects
1357 // the insets of the Dialog. If we could, we'd call invalidate()
1358 // from the peer, but we need to guarantee that we're not holding
1359 // the Dialog lock when we call invalidate().
1360 if (testvalid && valid) {
1361 invalidate();
1362 }
1363 }
1364
1365 /**
1366 * Disables or enables decorations for this dialog.
1367 * This method can only be called while the dialog is not displayable.
1368 * @param undecorated <code>true</code> if no dialog decorations are
1369 * to be enabled;
1370 * <code>false</code> if dialog decorations are to be enabled.
1371 * @throws <code>IllegalComponentStateException</code> if the dialog
1372 * is displayable.
1373 * @see #isUndecorated
1374 * @see Component#isDisplayable
1375 * @since 1.4
1376 */
1377 public void setUndecorated(boolean undecorated) {
1378 /* Make sure we don't run in the middle of peer creation.*/
1379 synchronized (getTreeLock()) {
1380 if (isDisplayable()) {
1381 throw new IllegalComponentStateException(
1382 "The dialog is displayable.");
1383 }
1384 this .undecorated = undecorated;
1385 }
1386 }
1387
1388 /**
1389 * Indicates whether this dialog is undecorated.
1390 * By default, all dialogs are initially decorated.
1391 * @return <code>true</code> if dialog is undecorated;
1392 * <code>false</code> otherwise.
1393 * @see java.awt.Dialog#setUndecorated
1394 * @since 1.4
1395 */
1396 public boolean isUndecorated() {
1397 return undecorated;
1398 }
1399
1400 /**
1401 * Returns a string representing the state of this dialog. This
1402 * method is intended to be used only for debugging purposes, and the
1403 * content and format of the returned string may vary between
1404 * implementations. The returned string may be empty but may not be
1405 * <code>null</code>.
1406 *
1407 * @return the parameter string of this dialog window.
1408 */
1409 protected String paramString() {
1410 String str = super .paramString() + "," + modalityType;
1411 if (title != null) {
1412 str += ",title=" + title;
1413 }
1414 return str;
1415 }
1416
1417 /**
1418 * Initialize JNI field and method IDs
1419 */
1420 private static native void initIDs();
1421
1422 /*
1423 * --- Modality support ---
1424 *
1425 */
1426
1427 /*
1428 * This method is called only for modal dialogs.
1429 *
1430 * Goes through the list of all visible top-level windows and
1431 * divide them into three distinct groups: blockers of this dialog,
1432 * blocked by this dialog and all others. Then blocks this dialog
1433 * by first met dialog from the first group (if any) and blocks all
1434 * the windows from the second group.
1435 */
1436 void modalShow() {
1437 // find all the dialogs that block this one
1438 IdentityArrayList<Dialog> blockers = new IdentityArrayList<Dialog>();
1439 for (Dialog d : modalDialogs) {
1440 if (d.shouldBlock(this )) {
1441 Window w = d;
1442 while ((w != null) && (w != this )) {
1443 w = (Window) (w.getOwner_NoClientCode());
1444 }
1445 if ((w == this )
1446 || !shouldBlock(d)
1447 || (modalityType.compareTo(d.getModalityType()) < 0)) {
1448 blockers.add(d);
1449 }
1450 }
1451 }
1452
1453 // add all blockers' blockers to blockers :)
1454 for (int i = 0; i < blockers.size(); i++) {
1455 Dialog blocker = blockers.get(i);
1456 if (blocker.isModalBlocked()) {
1457 Dialog blockerBlocker = blocker.getModalBlocker();
1458 if (!blockers.contains(blockerBlocker)) {
1459 blockers.add(i + 1, blockerBlocker);
1460 }
1461 }
1462 }
1463
1464 if (blockers.size() > 0) {
1465 blockers.get(0).blockWindow(this );
1466 }
1467
1468 // find all windows from blockers' hierarchies
1469 IdentityArrayList<Window> blockersHierarchies = new IdentityArrayList<Window>(
1470 blockers);
1471 int k = 0;
1472 while (k < blockersHierarchies.size()) {
1473 Window w = blockersHierarchies.get(k);
1474 Window[] ownedWindows = w.getOwnedWindows_NoClientCode();
1475 for (Window win : ownedWindows) {
1476 blockersHierarchies.add(win);
1477 }
1478 k++;
1479 }
1480
1481 java.util.List<Window> toBlock = new IdentityLinkedList<Window>();
1482 // block all windows from scope of blocking except from blockers' hierarchies
1483 IdentityArrayList<Window> unblockedWindows = Window
1484 .getAllUnblockedWindows();
1485 for (Window w : unblockedWindows) {
1486 if (shouldBlock(w) && !blockersHierarchies.contains(w)) {
1487 if ((w instanceof Dialog)
1488 && ((Dialog) w).isModal_NoClientCode()) {
1489 Dialog wd = (Dialog) w;
1490 if (wd.shouldBlock(this )
1491 && (modalDialogs.indexOf(wd) > modalDialogs
1492 .indexOf(this ))) {
1493 continue;
1494 }
1495 }
1496 toBlock.add(w);
1497 }
1498 }
1499 blockWindows(toBlock);
1500
1501 if (!isModalBlocked()) {
1502 updateChildrenBlocking();
1503 }
1504 }
1505
1506 /*
1507 * This method is called only for modal dialogs.
1508 *
1509 * Unblocks all the windows blocked by this modal dialog. After
1510 * each of them has been unblocked, it is checked to be blocked by
1511 * any other modal dialogs.
1512 */
1513 void modalHide() {
1514 // we should unblock all the windows first...
1515 IdentityArrayList<Window> save = new IdentityArrayList<Window>();
1516 int blockedWindowsCount = blockedWindows.size();
1517 for (int i = 0; i < blockedWindowsCount; i++) {
1518 Window w = blockedWindows.get(0);
1519 save.add(w);
1520 unblockWindow(w); // also removes w from blockedWindows
1521 }
1522 // ... and only after that check if they should be blocked
1523 // by another dialogs
1524 for (int i = 0; i < blockedWindowsCount; i++) {
1525 Window w = save.get(i);
1526 if ((w instanceof Dialog)
1527 && ((Dialog) w).isModal_NoClientCode()) {
1528 Dialog d = (Dialog) w;
1529 d.modalShow();
1530 } else {
1531 checkShouldBeBlocked(w);
1532 }
1533 }
1534 }
1535
1536 /*
1537 * Returns whether the given top-level window should be blocked by
1538 * this dialog. Note, that the given window can be also a modal dialog
1539 * and it should block this dialog, but this method do not take such
1540 * situations into consideration (such checks are performed in the
1541 * modalShow() and modalHide() methods).
1542 *
1543 * This method should be called on the getTreeLock() lock.
1544 */
1545 boolean shouldBlock(Window w) {
1546 if (!isVisible_NoClientCode()
1547 || (!w.isVisible_NoClientCode() && !w.isInShow)
1548 || isInHide || (w == this ) || !isModal_NoClientCode()) {
1549 return false;
1550 }
1551 if ((w instanceof Dialog) && ((Dialog) w).isInHide) {
1552 return false;
1553 }
1554 // check if w is from children hierarchy
1555 // fix for 6271546: we should also take into consideration child hierarchies
1556 // of this dialog's blockers
1557 Window blockerToCheck = this ;
1558 while (blockerToCheck != null) {
1559 Component c = w;
1560 while ((c != null) && (c != blockerToCheck)) {
1561 c = c.getParent_NoClientCode();
1562 }
1563 if (c == blockerToCheck) {
1564 return false;
1565 }
1566 blockerToCheck = blockerToCheck.getModalBlocker();
1567 }
1568 switch (modalityType) {
1569 case MODELESS:
1570 return false;
1571 case DOCUMENT_MODAL:
1572 if (w
1573 .isModalExcluded(ModalExclusionType.APPLICATION_EXCLUDE)) {
1574 // application- and toolkit-excluded windows are not blocked by
1575 // document-modal dialogs from outside their children hierarchy
1576 Component c = this ;
1577 while ((c != null) && (c != w)) {
1578 c = c.getParent_NoClientCode();
1579 }
1580 return c == w;
1581 } else {
1582 return getDocumentRoot() == w.getDocumentRoot();
1583 }
1584 case APPLICATION_MODAL:
1585 return !w
1586 .isModalExcluded(ModalExclusionType.APPLICATION_EXCLUDE)
1587 && (appContext == w.appContext);
1588 case TOOLKIT_MODAL:
1589 return !w
1590 .isModalExcluded(ModalExclusionType.TOOLKIT_EXCLUDE);
1591 }
1592
1593 return false;
1594 }
1595
1596 /*
1597 * Adds the given top-level window to the list of blocked
1598 * windows for this dialog and marks it as modal blocked.
1599 * If the window is already blocked by some modal dialog,
1600 * does nothing.
1601 */
1602 void blockWindow(Window w) {
1603 if (!w.isModalBlocked()) {
1604 w.setModalBlocked(this , true, true);
1605 blockedWindows.add(w);
1606 }
1607 }
1608
1609 void blockWindows(java.util.List<Window> toBlock) {
1610 DialogPeer dpeer = (DialogPeer) peer;
1611 if (dpeer == null) {
1612 return;
1613 }
1614 Iterator<Window> it = toBlock.iterator();
1615 while (it.hasNext()) {
1616 Window w = it.next();
1617 if (!w.isModalBlocked()) {
1618 w.setModalBlocked(this , true, false);
1619 } else {
1620 it.remove();
1621 }
1622 }
1623 dpeer.blockWindows(toBlock);
1624 blockedWindows.addAll(toBlock);
1625 }
1626
1627 /*
1628 * Removes the given top-level window from the list of blocked
1629 * windows for this dialog and marks it as unblocked. If the
1630 * window is not modal blocked, does nothing.
1631 */
1632 void unblockWindow(Window w) {
1633 if (w.isModalBlocked() && blockedWindows.contains(w)) {
1634 blockedWindows.remove(w);
1635 w.setModalBlocked(this , false, true);
1636 }
1637 }
1638
1639 /*
1640 * Checks if any other modal dialog D blocks the given window.
1641 * If such D exists, mark the window as blocked by D.
1642 */
1643 static void checkShouldBeBlocked(Window w) {
1644 synchronized (w.getTreeLock()) {
1645 for (int i = 0; i < modalDialogs.size(); i++) {
1646 Dialog modalDialog = modalDialogs.get(i);
1647 if (modalDialog.shouldBlock(w)) {
1648 modalDialog.blockWindow(w);
1649 break;
1650 }
1651 }
1652 }
1653 }
1654
1655 private void readObject(ObjectInputStream s)
1656 throws ClassNotFoundException, IOException,
1657 HeadlessException {
1658 GraphicsEnvironment.checkHeadless();
1659 s.defaultReadObject();
1660
1661 // in 1.5 or earlier modalityType was absent, so use "modal" instead
1662 if (modalityType == null) {
1663 setModal(modal);
1664 }
1665
1666 blockedWindows = new IdentityArrayList();
1667 }
1668
1669 /*
1670 * --- Accessibility Support ---
1671 *
1672 */
1673
1674 /**
1675 * Gets the AccessibleContext associated with this Dialog.
1676 * For dialogs, the AccessibleContext takes the form of an
1677 * AccessibleAWTDialog.
1678 * A new AccessibleAWTDialog instance is created if necessary.
1679 *
1680 * @return an AccessibleAWTDialog that serves as the
1681 * AccessibleContext of this Dialog
1682 * @since 1.3
1683 */
1684 public AccessibleContext getAccessibleContext() {
1685 if (accessibleContext == null) {
1686 accessibleContext = new AccessibleAWTDialog();
1687 }
1688 return accessibleContext;
1689 }
1690
1691 /**
1692 * This class implements accessibility support for the
1693 * <code>Dialog</code> class. It provides an implementation of the
1694 * Java Accessibility API appropriate to dialog user-interface elements.
1695 * @since 1.3
1696 */
1697 protected class AccessibleAWTDialog extends AccessibleAWTWindow {
1698 /*
1699 * JDK 1.3 serialVersionUID
1700 */
1701 private static final long serialVersionUID = 4837230331833941201L;
1702
1703 /**
1704 * Get the role of this object.
1705 *
1706 * @return an instance of AccessibleRole describing the role of the
1707 * object
1708 * @see AccessibleRole
1709 */
1710 public AccessibleRole getAccessibleRole() {
1711 return AccessibleRole.DIALOG;
1712 }
1713
1714 /**
1715 * Get the state of this object.
1716 *
1717 * @return an instance of AccessibleStateSet containing the current
1718 * state set of the object
1719 * @see AccessibleState
1720 */
1721 public AccessibleStateSet getAccessibleStateSet() {
1722 AccessibleStateSet states = super .getAccessibleStateSet();
1723 if (getFocusOwner() != null) {
1724 states.add(AccessibleState.ACTIVE);
1725 }
1726 if (isModal()) {
1727 states.add(AccessibleState.MODAL);
1728 }
1729 if (isResizable()) {
1730 states.add(AccessibleState.RESIZABLE);
1731 }
1732 return states;
1733 }
1734
1735 } // inner class AccessibleAWTDialog
1736 }
|