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 ([email protected])
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: }
|