1 /*
   2  * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.awt;
  26 
  27 import java.awt.peer.DialogPeer;
  28 import java.awt.event.*;
  29 import java.io.ObjectInputStream;
  30 import java.io.IOException;
  31 import java.util.Iterator;
  32 import java.util.concurrent.atomic.AtomicLong;
  33 import java.security.AccessController;
  34 import java.security.PrivilegedAction;
  35 import javax.accessibility.*;
  36 import sun.awt.AppContext;
  37 import sun.awt.SunToolkit;
  38 import sun.awt.PeerEvent;
  39 import sun.awt.util.IdentityArrayList;
  40 import sun.awt.util.IdentityLinkedList;
  41 import sun.security.util.SecurityConstants;
  42 import java.security.AccessControlException;
  43 
  44 /**
  45  * A Dialog is a top-level window with a title and a border
  46  * that is typically used to take some form of input from the user.
  47  *
  48  * The size of the dialog includes any area designated for the
  49  * border.  The dimensions of the border area can be obtained
  50  * using the <code>getInsets</code> method, however, since
  51  * these dimensions are platform-dependent, a valid insets
  52  * value cannot be obtained until the dialog is made displayable
  53  * by either calling <code>pack</code> or <code>show</code>.
  54  * Since the border area is included in the overall size of the
  55  * dialog, the border effectively obscures a portion of the dialog,
  56  * constraining the area available for rendering and/or displaying
  57  * subcomponents to the rectangle which has an upper-left corner
  58  * location of <code>(insets.left, insets.top)</code>, and has a size of
  59  * <code>width - (insets.left + insets.right)</code> by
  60  * <code>height - (insets.top + insets.bottom)</code>.
  61  * <p>
  62  * The default layout for a dialog is <code>BorderLayout</code>.
  63  * <p>
  64  * A dialog may have its native decorations (i.e. Frame & Titlebar) turned off
  65  * with <code>setUndecorated</code>.  This can only be done while the dialog
  66  * is not {@link Component#isDisplayable() displayable}.
  67  * <p>
  68  * A dialog may have another window as its owner when it's constructed.  When
  69  * the owner window of a visible dialog is minimized, the dialog will
  70  * automatically be hidden from the user. When the owner window is subsequently
  71  * restored, the dialog is made visible to the user again.
  72  * <p>
  73  * In a multi-screen environment, you can create a <code>Dialog</code>
  74  * on a different screen device than its owner.  See {@link java.awt.Frame} for
  75  * more information.
  76  * <p>
  77  * A dialog can be either modeless (the default) or modal.  A modal
  78  * dialog is one which blocks input to some other top-level windows
  79  * in the application, except for any windows created with the dialog
  80  * as their owner. See <a href="doc-files/Modality.html">AWT Modality</a>
  81  * specification for details.
  82  * <p>
  83  * Dialogs are capable of generating the following
  84  * <code>WindowEvents</code>:
  85  * <code>WindowOpened</code>, <code>WindowClosing</code>,
  86  * <code>WindowClosed</code>, <code>WindowActivated</code>,
  87  * <code>WindowDeactivated</code>, <code>WindowGainedFocus</code>,
  88  * <code>WindowLostFocus</code>.
  89  *
  90  * @see WindowEvent
  91  * @see Window#addWindowListener
  92  *
  93  * @author      Sami Shaio
  94  * @author      Arthur van Hoff
  95  * @since       JDK1.0
  96  */
  97 public class Dialog extends Window {
  98 
  99     static {
 100         /* ensure that the necessary native libraries are loaded */
 101         Toolkit.loadLibraries();
 102         if (!GraphicsEnvironment.isHeadless()) {
 103             initIDs();
 104         }
 105     }
 106 
 107     /**
 108      * A dialog's resizable property. Will be true
 109      * if the Dialog is to be resizable, otherwise
 110      * it will be false.
 111      *
 112      * @serial
 113      * @see #setResizable(boolean)
 114      */
 115     boolean resizable = true;
 116 
 117 
 118     /**
 119      * This field indicates whether the dialog is undecorated.
 120      * This property can only be changed while the dialog is not displayable.
 121      * <code>undecorated</code> will be true if the dialog is
 122      * undecorated, otherwise it will be false.
 123      *
 124      * @serial
 125      * @see #setUndecorated(boolean)
 126      * @see #isUndecorated()
 127      * @see Component#isDisplayable()
 128      * @since 1.4
 129      */
 130     boolean undecorated = false;
 131 
 132     private transient boolean initialized = false;
 133 
 134     /**
 135      * Modal dialogs block all input to some top-level windows.
 136      * Whether a particular window is blocked depends on dialog's type
 137      * of modality; this is called the "scope of blocking". The
 138      * <code>ModalityType</code> enum specifies modal types and their
 139      * associated scopes.
 140      *
 141      * @see Dialog#getModalityType
 142      * @see Dialog#setModalityType
 143      * @see Toolkit#isModalityTypeSupported
 144      *
 145      * @since 1.6
 146      */
 147     public static enum ModalityType {
 148         /**
 149          * <code>MODELESS</code> dialog doesn't block any top-level windows.
 150          */
 151         MODELESS,
 152         /**
 153          * A <code>DOCUMENT_MODAL</code> dialog blocks input to all top-level windows
 154          * from the same document except those from its own child hierarchy.
 155          * A document is a top-level window without an owner. It may contain child
 156          * windows that, together with the top-level window are treated as a single
 157          * solid document. Since every top-level window must belong to some
 158          * document, its root can be found as the top-nearest window without an owner.
 159          */
 160         DOCUMENT_MODAL,
 161         /**
 162          * An <code>APPLICATION_MODAL</code> dialog blocks all top-level windows
 163          * from the same Java application except those from its own child hierarchy.
 164          * If there are several applets launched in a browser, they can be
 165          * treated either as separate applications or a single one. This behavior
 166          * is implementation-dependent.
 167          */
 168         APPLICATION_MODAL,
 169         /**
 170          * A <code>TOOLKIT_MODAL</code> dialog blocks all top-level windows run
 171          * from the same toolkit except those from its own child hierarchy. If there
 172          * are several applets launched in a browser, all of them run with the same
 173          * toolkit; thus, a toolkit-modal dialog displayed by an applet may affect
 174          * other applets and all windows of the browser instance which embeds the
 175          * Java runtime environment for this toolkit.
 176          * Special <code>AWTPermission</code> "toolkitModality" must be granted to use
 177          * toolkit-modal dialogs. If a <code>TOOLKIT_MODAL</code> dialog is being created
 178          * and this permission is not granted, a <code>SecurityException</code> will be
 179          * thrown, and no dialog will be created. If a modality type is being changed
 180          * to <code>TOOLKIT_MODAL</code> and this permission is not granted, a
 181          * <code>SecurityException</code> will be thrown, and the modality type will
 182          * be left unchanged.
 183          */
 184         TOOLKIT_MODAL
 185     };
 186 
 187     /**
 188      * Default modality type for modal dialogs. The default modality type is
 189      * <code>APPLICATION_MODAL</code>. Calling the oldstyle <code>setModal(true)</code>
 190      * is equal to <code>setModalityType(DEFAULT_MODALITY_TYPE)</code>.
 191      *
 192      * @see java.awt.Dialog.ModalityType
 193      * @see java.awt.Dialog#setModal
 194      *
 195      * @since 1.6
 196      */
 197     public final static ModalityType DEFAULT_MODALITY_TYPE = ModalityType.APPLICATION_MODAL;
 198 
 199     /**
 200      * True if this dialog is modal, false is the dialog is modeless.
 201      * A modal dialog blocks user input to some application top-level
 202      * windows. This field is kept only for backwards compatibility. Use the
 203      * {@link Dialog.ModalityType ModalityType} enum instead.
 204      *
 205      * @serial
 206      *
 207      * @see #isModal
 208      * @see #setModal
 209      * @see #getModalityType
 210      * @see #setModalityType
 211      * @see ModalityType
 212      * @see ModalityType#MODELESS
 213      * @see #DEFAULT_MODALITY_TYPE
 214      */
 215     boolean modal;
 216 
 217     /**
 218      * Modality type of this dialog. If the dialog's modality type is not
 219      * {@link Dialog.ModalityType#MODELESS ModalityType.MODELESS}, it blocks all
 220      * user input to some application top-level windows.
 221      *
 222      * @serial
 223      *
 224      * @see ModalityType
 225      * @see #getModalityType
 226      * @see #setModalityType
 227      *
 228      * @since 1.6
 229      */
 230     ModalityType modalityType;
 231 
 232     /**
 233      * Any top-level window can be marked not to be blocked by modal
 234      * dialogs. This is called "modal exclusion". This enum specifies
 235      * the possible modal exclusion types.
 236      *
 237      * @see Window#getModalExclusionType
 238      * @see Window#setModalExclusionType
 239      * @see Toolkit#isModalExclusionTypeSupported
 240      *
 241      * @since 1.6
 242      */
 243     public static enum ModalExclusionType {
 244         /**
 245          * No modal exclusion.
 246          */
 247         NO_EXCLUDE,
 248         /**
 249          * <code>APPLICATION_EXCLUDE</code> indicates that a top-level window
 250          * won't be blocked by any application-modal dialogs. Also, it isn't
 251          * blocked by document-modal dialogs from outside of its child hierarchy.
 252          */
 253         APPLICATION_EXCLUDE,
 254         /**
 255          * <code>TOOLKIT_EXCLUDE</code> indicates that a top-level window
 256          * won't be blocked by  application-modal or toolkit-modal dialogs. Also,
 257          * it isn't blocked by document-modal dialogs from outside of its
 258          * child hierarchy.
 259          * The "toolkitModality" <code>AWTPermission</code> must be granted
 260          * for this exclusion. If an exclusion property is being changed to
 261          * <code>TOOLKIT_EXCLUDE</code> and this permission is not granted, a
 262          * <code>SecurityEcxeption</code> will be thrown, and the exclusion
 263          * property will be left unchanged.
 264          */
 265         TOOLKIT_EXCLUDE
 266     };
 267 
 268     /* operations with this list should be synchronized on tree lock*/
 269     transient static IdentityArrayList<Dialog> modalDialogs = new IdentityArrayList<Dialog>();
 270 
 271     transient IdentityArrayList<Window> blockedWindows = new IdentityArrayList<Window>();
 272 
 273     /**
 274      * Specifies the title of the Dialog.
 275      * This field can be null.
 276      *
 277      * @serial
 278      * @see #getTitle()
 279      * @see #setTitle(String)
 280      */
 281     String title;
 282 
 283     private transient ModalEventFilter modalFilter;
 284     private transient volatile SecondaryLoop secondaryLoop;
 285 
 286     /*
 287      * Indicates that this dialog is being hidden. This flag is set to true at
 288      * the beginning of hide() and to false at the end of hide().
 289      *
 290      * @see #hide()
 291      * @see #hideAndDisposePreHandler()
 292      * @see #hideAndDisposeHandler()
 293      * @see #shouldBlock()
 294      */
 295     transient volatile boolean isInHide = false;
 296 
 297     /*
 298      * Indicates that this dialog is being disposed. This flag is set to true at
 299      * the beginning of doDispose() and to false at the end of doDispose().
 300      *
 301      * @see #hide()
 302      * @see #hideAndDisposePreHandler()
 303      * @see #hideAndDisposeHandler()
 304      * @see #doDispose()
 305      */
 306     transient volatile boolean isInDispose = false;
 307 
 308     private static final String base = "dialog";
 309     private static int nameCounter = 0;
 310 
 311     /*
 312      * JDK 1.1 serialVersionUID
 313      */
 314     private static final long serialVersionUID = 5920926903803293709L;
 315 
 316     /**
 317      * Constructs an initially invisible, modeless <code>Dialog</code> with
 318      * the specified owner <code>Frame</code> and an empty title.
 319      *
 320      * @param owner the owner of the dialog or <code>null</code> if
 321      *     this dialog has no owner
 322      * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
 323      *    <code>GraphicsConfiguration</code> is not from a screen device
 324      * @exception HeadlessException when
 325      *    <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 326      *
 327      * @see java.awt.GraphicsEnvironment#isHeadless
 328      * @see Component#setSize
 329      * @see Component#setVisible
 330      */
 331      public Dialog(Frame owner) {
 332          this(owner, "", false);
 333      }
 334 
 335     /**
 336      * Constructs an initially invisible <code>Dialog</code> with the specified
 337      * owner <code>Frame</code> and modality and an empty title.
 338      *
 339      * @param owner the owner of the dialog or <code>null</code> if
 340      *     this dialog has no owner
 341      * @param modal specifes whether dialog blocks user input to other top-level
 342      *     windows when shown. If <code>false</code>, the dialog is <code>MODELESS</code>;
 343      *     if <code>true</code>, the modality type property is set to
 344      *     <code>DEFAULT_MODALITY_TYPE</code>
 345      * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
 346      *    <code>GraphicsConfiguration</code> is not from a screen device
 347      * @exception HeadlessException when
 348      *     <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 349      *
 350      * @see java.awt.Dialog.ModalityType
 351      * @see java.awt.Dialog.ModalityType#MODELESS
 352      * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
 353      * @see java.awt.Dialog#setModal
 354      * @see java.awt.Dialog#setModalityType
 355      * @see java.awt.GraphicsEnvironment#isHeadless
 356      */
 357      public Dialog(Frame owner, boolean modal) {
 358          this(owner, "", modal);
 359      }
 360 
 361     /**
 362      * Constructs an initially invisible, modeless <code>Dialog</code> with
 363      * the specified owner <code>Frame</code> and title.
 364      *
 365      * @param owner the owner of the dialog or <code>null</code> if
 366      *     this dialog has no owner
 367      * @param title the title of the dialog or <code>null</code> if this dialog
 368      *     has no title
 369      * @exception IllegalArgumentException if the <code>owner</code>'s
 370      *     <code>GraphicsConfiguration</code> is not from a screen device
 371      * @exception HeadlessException when
 372      *     <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 373      *
 374      * @see java.awt.GraphicsEnvironment#isHeadless
 375      * @see Component#setSize
 376      * @see Component#setVisible
 377      */
 378      public Dialog(Frame owner, String title) {
 379          this(owner, title, false);
 380      }
 381 
 382     /**
 383      * Constructs an initially invisible <code>Dialog</code> with the
 384      * specified owner <code>Frame</code>, title and modality.
 385      *
 386      * @param owner the owner of the dialog or <code>null</code> if
 387      *     this dialog has no owner
 388      * @param title the title of the dialog or <code>null</code> if this dialog
 389      *     has no title
 390      * @param modal specifes whether dialog blocks user input to other top-level
 391      *     windows when shown. If <code>false</code>, the dialog is <code>MODELESS</code>;
 392      *     if <code>true</code>, the modality type property is set to
 393      *     <code>DEFAULT_MODALITY_TYPE</code>
 394      * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
 395      *    <code>GraphicsConfiguration</code> is not from a screen device
 396      * @exception HeadlessException when
 397      *    <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 398      *
 399      * @see java.awt.Dialog.ModalityType
 400      * @see java.awt.Dialog.ModalityType#MODELESS
 401      * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
 402      * @see java.awt.Dialog#setModal
 403      * @see java.awt.Dialog#setModalityType
 404      * @see java.awt.GraphicsEnvironment#isHeadless
 405      * @see Component#setSize
 406      * @see Component#setVisible
 407      */
 408      public Dialog(Frame owner, String title, boolean modal) {
 409          this(owner, title, modal ? DEFAULT_MODALITY_TYPE : ModalityType.MODELESS);
 410      }
 411 
 412     /**
 413      * Constructs an initially invisible <code>Dialog</code> with the specified owner
 414      * <code>Frame</code>, title, modality, and <code>GraphicsConfiguration</code>.
 415      * @param owner the owner of the dialog or <code>null</code> if this dialog
 416      *     has no owner
 417      * @param title the title of the dialog or <code>null</code> if this dialog
 418      *     has no title
 419      * @param modal specifes whether dialog blocks user input to other top-level
 420      *     windows when shown. If <code>false</code>, the dialog is <code>MODELESS</code>;
 421      *     if <code>true</code>, the modality type property is set to
 422      *     <code>DEFAULT_MODALITY_TYPE</code>
 423      * @param gc the <code>GraphicsConfiguration</code> of the target screen device;
 424      *     if <code>null</code>, the default system <code>GraphicsConfiguration</code>
 425      *     is assumed
 426      * @exception java.lang.IllegalArgumentException if <code>gc</code>
 427      *     is not from a screen device
 428      * @exception HeadlessException when
 429      *     <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 430      *
 431      * @see java.awt.Dialog.ModalityType
 432      * @see java.awt.Dialog.ModalityType#MODELESS
 433      * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
 434      * @see java.awt.Dialog#setModal
 435      * @see java.awt.Dialog#setModalityType
 436      * @see java.awt.GraphicsEnvironment#isHeadless
 437      * @see Component#setSize
 438      * @see Component#setVisible
 439      * @since 1.4
 440      */
 441      public Dialog(Frame owner, String title, boolean modal,
 442                    GraphicsConfiguration gc) {
 443          this(owner, title, modal ? DEFAULT_MODALITY_TYPE : ModalityType.MODELESS, gc);
 444      }
 445 
 446     /**
 447      * Constructs an initially invisible, modeless <code>Dialog</code> with
 448      * the specified owner <code>Dialog</code> and an empty title.
 449      *
 450      * @param owner the owner of the dialog or <code>null</code> if this
 451      *     dialog has no owner
 452      * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
 453      *     <code>GraphicsConfiguration</code> is not from a screen device
 454      * @exception HeadlessException when
 455      *     <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 456      * @see java.awt.GraphicsEnvironment#isHeadless
 457      * @since 1.2
 458      */
 459      public Dialog(Dialog owner) {
 460          this(owner, "", false);
 461      }
 462 
 463     /**
 464      * Constructs an initially invisible, modeless <code>Dialog</code>
 465      * with the specified owner <code>Dialog</code> and title.
 466      *
 467      * @param owner the owner of the dialog or <code>null</code> if this
 468      *     has no owner
 469      * @param title the title of the dialog or <code>null</code> if this dialog
 470      *     has no title
 471      * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
 472      *     <code>GraphicsConfiguration</code> is not from a screen device
 473      * @exception HeadlessException when
 474      *     <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 475      *
 476      * @see java.awt.GraphicsEnvironment#isHeadless
 477      * @since 1.2
 478      */
 479      public Dialog(Dialog owner, String title) {
 480          this(owner, title, false);
 481      }
 482 
 483     /**
 484      * Constructs an initially invisible <code>Dialog</code> with the
 485      * specified owner <code>Dialog</code>, title, and modality.
 486      *
 487      * @param owner the owner of the dialog or <code>null</code> if this
 488      *     dialog has no owner
 489      * @param title the title of the dialog or <code>null</code> if this
 490      *     dialog has no title
 491      * @param modal specifes whether dialog blocks user input to other top-level
 492      *     windows when shown. If <code>false</code>, the dialog is <code>MODELESS</code>;
 493      *     if <code>true</code>, the modality type property is set to
 494      *     <code>DEFAULT_MODALITY_TYPE</code>
 495      * @exception IllegalArgumentException if the <code>owner</code>'s
 496      *    <code>GraphicsConfiguration</code> is not from a screen device
 497      * @exception HeadlessException when
 498      *    <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 499      *
 500      * @see java.awt.Dialog.ModalityType
 501      * @see java.awt.Dialog.ModalityType#MODELESS
 502      * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
 503      * @see java.awt.Dialog#setModal
 504      * @see java.awt.Dialog#setModalityType
 505      * @see java.awt.GraphicsEnvironment#isHeadless
 506      *
 507      * @since 1.2
 508      */
 509      public Dialog(Dialog owner, String title, boolean modal) {
 510          this(owner, title, modal ? DEFAULT_MODALITY_TYPE : ModalityType.MODELESS);
 511      }
 512 
 513     /**
 514      * Constructs an initially invisible <code>Dialog</code> with the
 515      * specified owner <code>Dialog</code>, title, modality and
 516      * <code>GraphicsConfiguration</code>.
 517      *
 518      * @param owner the owner of the dialog or <code>null</code> if this
 519      *     dialog has no owner
 520      * @param title the title of the dialog or <code>null</code> if this
 521      *     dialog has no title
 522      * @param modal specifes whether dialog blocks user input to other top-level
 523      *     windows when shown. If <code>false</code>, the dialog is <code>MODELESS</code>;
 524      *     if <code>true</code>, the modality type property is set to
 525      *     <code>DEFAULT_MODALITY_TYPE</code>
 526      * @param gc the <code>GraphicsConfiguration</code> of the target screen device;
 527      *     if <code>null</code>, the default system <code>GraphicsConfiguration</code>
 528      *     is assumed
 529      * @exception java.lang.IllegalArgumentException if <code>gc</code>
 530      *    is not from a screen device
 531      * @exception HeadlessException when
 532      *    <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 533      *
 534      * @see java.awt.Dialog.ModalityType
 535      * @see java.awt.Dialog.ModalityType#MODELESS
 536      * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE
 537      * @see java.awt.Dialog#setModal
 538      * @see java.awt.Dialog#setModalityType
 539      * @see java.awt.GraphicsEnvironment#isHeadless
 540      * @see Component#setSize
 541      * @see Component#setVisible
 542      *
 543      * @since 1.4
 544      */
 545      public Dialog(Dialog owner, String title, boolean modal,
 546                    GraphicsConfiguration gc) {
 547          this(owner, title, modal ? DEFAULT_MODALITY_TYPE : ModalityType.MODELESS, gc);
 548      }
 549 
 550     /**
 551      * Constructs an initially invisible, modeless <code>Dialog</code> with the
 552      * specified owner <code>Window</code> and an empty title.
 553      *
 554      * @param owner the owner of the dialog. The owner must be an instance of
 555      *     {@link java.awt.Dialog Dialog}, {@link java.awt.Frame Frame}, any
 556      *     of their descendents or <code>null</code>
 557      *
 558      * @exception java.lang.IllegalArgumentException if the <code>owner</code>
 559      *     is not an instance of {@link java.awt.Dialog Dialog} or {@link
 560      *     java.awt.Frame Frame}
 561      * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
 562      *     <code>GraphicsConfiguration</code> is not from a screen device
 563      * @exception HeadlessException when
 564      *     <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 565      *
 566      * @see java.awt.GraphicsEnvironment#isHeadless
 567      *
 568      * @since 1.6
 569      */
 570     public Dialog(Window owner) {
 571         this(owner, "", ModalityType.MODELESS);
 572     }
 573 
 574     /**
 575      * Constructs an initially invisible, modeless <code>Dialog</code> with
 576      * the specified owner <code>Window</code> and title.
 577      *
 578      * @param owner the owner of the dialog. The owner must be an instance of
 579      *    {@link java.awt.Dialog Dialog}, {@link java.awt.Frame Frame}, any
 580      *    of their descendents or <code>null</code>
 581      * @param title the title of the dialog or <code>null</code> if this dialog
 582      *    has no title
 583      *
 584      * @exception java.lang.IllegalArgumentException if the <code>owner</code>
 585      *    is not an instance of {@link java.awt.Dialog Dialog} or {@link
 586      *    java.awt.Frame Frame}
 587      * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
 588      *    <code>GraphicsConfiguration</code> is not from a screen device
 589      * @exception HeadlessException when
 590      *    <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 591      *
 592      * @see java.awt.GraphicsEnvironment#isHeadless
 593      *
 594      * @since 1.6
 595      */
 596     public Dialog(Window owner, String title) {
 597         this(owner, title, ModalityType.MODELESS);
 598     }
 599 
 600     /**
 601      * Constructs an initially invisible <code>Dialog</code> with the
 602      * specified owner <code>Window</code> and modality and an empty title.
 603      *
 604      * @param owner the owner of the dialog. The owner must be an instance of
 605      *    {@link java.awt.Dialog Dialog}, {@link java.awt.Frame Frame}, any
 606      *    of their descendents or <code>null</code>
 607      * @param modalityType specifies whether dialog blocks input to other
 608      *    windows when shown. <code>null</code> value and unsupported modality
 609      *    types are equivalent to <code>MODELESS</code>
 610      *
 611      * @exception java.lang.IllegalArgumentException if the <code>owner</code>
 612      *    is not an instance of {@link java.awt.Dialog Dialog} or {@link
 613      *    java.awt.Frame Frame}
 614      * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
 615      *    <code>GraphicsConfiguration</code> is not from a screen device
 616      * @exception HeadlessException when
 617      *    <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 618      * @exception SecurityException if the calling thread does not have permission
 619      *    to create modal dialogs with the given <code>modalityType</code>
 620      *
 621      * @see java.awt.Dialog.ModalityType
 622      * @see java.awt.Dialog#setModal
 623      * @see java.awt.Dialog#setModalityType
 624      * @see java.awt.GraphicsEnvironment#isHeadless
 625      * @see java.awt.Toolkit#isModalityTypeSupported
 626      *
 627      * @since 1.6
 628      */
 629     public Dialog(Window owner, ModalityType modalityType) {
 630         this(owner, "", modalityType);
 631     }
 632 
 633     /**
 634      * Constructs an initially invisible <code>Dialog</code> with the
 635      * specified owner <code>Window</code>, title and modality.
 636      *
 637      * @param owner the owner of the dialog. The owner must be an instance of
 638      *     {@link java.awt.Dialog Dialog}, {@link java.awt.Frame Frame}, any
 639      *     of their descendents or <code>null</code>
 640      * @param title the title of the dialog or <code>null</code> if this dialog
 641      *     has no title
 642      * @param modalityType specifies whether dialog blocks input to other
 643      *    windows when shown. <code>null</code> value and unsupported modality
 644      *    types are equivalent to <code>MODELESS</code>
 645      *
 646      * @exception java.lang.IllegalArgumentException if the <code>owner</code>
 647      *     is not an instance of {@link java.awt.Dialog Dialog} or {@link
 648      *     java.awt.Frame Frame}
 649      * @exception java.lang.IllegalArgumentException if the <code>owner</code>'s
 650      *     <code>GraphicsConfiguration</code> is not from a screen device
 651      * @exception HeadlessException when
 652      *     <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 653      * @exception SecurityException if the calling thread does not have permission
 654      *     to create modal dialogs with the given <code>modalityType</code>
 655      *
 656      * @see java.awt.Dialog.ModalityType
 657      * @see java.awt.Dialog#setModal
 658      * @see java.awt.Dialog#setModalityType
 659      * @see java.awt.GraphicsEnvironment#isHeadless
 660      * @see java.awt.Toolkit#isModalityTypeSupported
 661      *
 662      * @since 1.6
 663      */
 664     public Dialog(Window owner, String title, ModalityType modalityType) {
 665         super(owner);
 666 
 667         if ((owner != null) &&
 668             !(owner instanceof Frame) &&
 669             !(owner instanceof Dialog))
 670         {
 671             throw new IllegalArgumentException("Wrong parent window");
 672         }
 673 
 674         this.title = title;
 675         setModalityType(modalityType);
 676         SunToolkit.checkAndSetPolicy(this);
 677         initialized = true;
 678     }
 679 
 680     /**
 681      * Constructs an initially invisible <code>Dialog</code> with the
 682      * specified owner <code>Window</code>, title, modality and
 683      * <code>GraphicsConfiguration</code>.
 684      *
 685      * @param owner the owner of the dialog. The owner must be an instance of
 686      *     {@link java.awt.Dialog Dialog}, {@link java.awt.Frame Frame}, any
 687      *     of their descendents or <code>null</code>
 688      * @param title the title of the dialog or <code>null</code> if this dialog
 689      *     has no title
 690      * @param modalityType specifies whether dialog blocks input to other
 691      *    windows when shown. <code>null</code> value and unsupported modality
 692      *    types are equivalent to <code>MODELESS</code>
 693      * @param gc the <code>GraphicsConfiguration</code> of the target screen device;
 694      *     if <code>null</code>, the default system <code>GraphicsConfiguration</code>
 695      *     is assumed
 696      *
 697      * @exception java.lang.IllegalArgumentException if the <code>owner</code>
 698      *     is not an instance of {@link java.awt.Dialog Dialog} or {@link
 699      *     java.awt.Frame Frame}
 700      * @exception java.lang.IllegalArgumentException if <code>gc</code>
 701      *     is not from a screen device
 702      * @exception HeadlessException when
 703      *     <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
 704      * @exception SecurityException if the calling thread does not have permission
 705      *     to create modal dialogs with the given <code>modalityType</code>
 706      *
 707      * @see java.awt.Dialog.ModalityType
 708      * @see java.awt.Dialog#setModal
 709      * @see java.awt.Dialog#setModalityType
 710      * @see java.awt.GraphicsEnvironment#isHeadless
 711      * @see java.awt.Toolkit#isModalityTypeSupported
 712      *
 713      * @since 1.6
 714      */
 715     public Dialog(Window owner, String title, ModalityType modalityType,
 716                   GraphicsConfiguration gc) {
 717         super(owner, gc);
 718 
 719         if ((owner != null) &&
 720             !(owner instanceof Frame) &&
 721             !(owner instanceof Dialog))
 722         {
 723             throw new IllegalArgumentException("wrong owner window");
 724         }
 725 
 726         this.title = title;
 727         setModalityType(modalityType);
 728         SunToolkit.checkAndSetPolicy(this);
 729         initialized = true;
 730     }
 731 
 732     /**
 733      * Construct a name for this component.  Called by getName() when the
 734      * name is null.
 735      */
 736     String constructComponentName() {
 737         synchronized (Dialog.class) {
 738             return base + nameCounter++;
 739         }
 740     }
 741 
 742     /**
 743      * Makes this Dialog displayable by connecting it to
 744      * a native screen resource.  Making a dialog displayable will
 745      * cause any of its children to be made displayable.
 746      * This method is called internally by the toolkit and should
 747      * not be called directly by programs.
 748      * @see Component#isDisplayable
 749      * @see #removeNotify
 750      */
 751     public void addNotify() {
 752         synchronized (getTreeLock()) {
 753             if (parent != null && parent.getPeer() == null) {
 754                 parent.addNotify();
 755             }
 756 
 757             if (peer == null) {
 758                 peer = getToolkit().createDialog(this);
 759             }
 760             super.addNotify();
 761         }
 762     }
 763 
 764     /**
 765      * Indicates whether the dialog is modal.
 766      * <p>
 767      * This method is obsolete and is kept for backwards compatiblity only.
 768      * Use {@link #getModalityType getModalityType()} instead.
 769      *
 770      * @return    <code>true</code> if this dialog window is modal;
 771      *            <code>false</code> otherwise
 772      *
 773      * @see       java.awt.Dialog#DEFAULT_MODALITY_TYPE
 774      * @see       java.awt.Dialog.ModalityType#MODELESS
 775      * @see       java.awt.Dialog#setModal
 776      * @see       java.awt.Dialog#getModalityType
 777      * @see       java.awt.Dialog#setModalityType
 778      */
 779     public boolean isModal() {
 780         return isModal_NoClientCode();
 781     }
 782     final boolean isModal_NoClientCode() {
 783         return modalityType != ModalityType.MODELESS;
 784     }
 785 
 786     /**
 787      * Specifies whether this dialog should be modal.
 788      * <p>
 789      * This method is obsolete and is kept for backwards compatibility only.
 790      * Use {@link #setModalityType setModalityType()} instead.
 791      * <p>
 792      * Note: changing modality of the visible dialog may have no effect
 793      * until it is hidden and then shown again.
 794      *
 795      * @param modal specifies whether dialog blocks input to other windows
 796      *     when shown; calling to <code>setModal(true)</code> is equivalent to
 797      *     <code>setModalityType(Dialog.DEFAULT_MODALITY_TYPE)</code>, and
 798      *     calling to <code>setModal(false)</code> is equvivalent to
 799      *     <code>setModalityType(Dialog.ModalityType.MODELESS)</code>
 800      *
 801      * @see       java.awt.Dialog#DEFAULT_MODALITY_TYPE
 802      * @see       java.awt.Dialog.ModalityType#MODELESS
 803      * @see       java.awt.Dialog#isModal
 804      * @see       java.awt.Dialog#getModalityType
 805      * @see       java.awt.Dialog#setModalityType
 806      *
 807      * @since     1.1
 808      */
 809     public void setModal(boolean modal) {
 810         this.modal = modal;
 811         setModalityType(modal ? DEFAULT_MODALITY_TYPE : ModalityType.MODELESS);
 812     }
 813 
 814     /**
 815      * Returns the modality type of this dialog.
 816      *
 817      * @return modality type of this dialog
 818      *
 819      * @see java.awt.Dialog#setModalityType
 820      *
 821      * @since 1.6
 822      */
 823     public ModalityType getModalityType() {
 824         return modalityType;
 825     }
 826 
 827     /**
 828      * Sets the modality type for this dialog. See {@link
 829      * java.awt.Dialog.ModalityType ModalityType} for possible modality types.
 830      * <p>
 831      * If the given modality type is not supported, <code>MODELESS</code>
 832      * is used. You may want to call <code>getModalityType()</code> after calling
 833      * this method to ensure that the modality type has been set.
 834      * <p>
 835      * Note: changing modality of the visible dialog may have no effect
 836      * until it is hidden and then shown again.
 837      *
 838      * @param type specifies whether dialog blocks input to other
 839      *     windows when shown. <code>null</code> value and unsupported modality
 840      *     types are equivalent to <code>MODELESS</code>
 841      * @exception SecurityException if the calling thread does not have permission
 842      *     to create modal dialogs with the given <code>modalityType</code>
 843      *
 844      * @see       java.awt.Dialog#getModalityType
 845      * @see       java.awt.Toolkit#isModalityTypeSupported
 846      *
 847      * @since     1.6
 848      */
 849     public void setModalityType(ModalityType type) {
 850         if (type == null) {
 851             type = Dialog.ModalityType.MODELESS;
 852         }
 853         if (!Toolkit.getDefaultToolkit().isModalityTypeSupported(type)) {
 854             type = Dialog.ModalityType.MODELESS;
 855         }
 856         if (modalityType == type) {
 857             return;
 858         }
 859 
 860         checkModalityPermission(type);
 861 
 862         modalityType = type;
 863         modal = (modalityType != ModalityType.MODELESS);
 864     }
 865 
 866     /**
 867      * Gets the title of the dialog. The title is displayed in the
 868      * dialog's border.
 869      * @return    the title of this dialog window. The title may be
 870      *            <code>null</code>.
 871      * @see       java.awt.Dialog#setTitle
 872      */
 873     public String getTitle() {
 874         return title;
 875     }
 876 
 877     /**
 878      * Sets the title of the Dialog.
 879      * @param title the title displayed in the dialog's border;
 880          * a null value results in an empty title
 881      * @see #getTitle
 882      */
 883     public void setTitle(String title) {
 884         String oldTitle = this.title;
 885 
 886         synchronized(this) {
 887             this.title = title;
 888             DialogPeer peer = (DialogPeer)this.peer;
 889             if (peer != null) {
 890                 peer.setTitle(title);
 891             }
 892         }
 893         firePropertyChange("title", oldTitle, title);
 894     }
 895 
 896     /**
 897      * @return true if we actually showed, false if we just called toFront()
 898      */
 899     private boolean conditionalShow(Component toFocus, AtomicLong time) {
 900         boolean retval;
 901 
 902         closeSplashScreen();
 903 
 904         synchronized (getTreeLock()) {
 905             if (peer == null) {
 906                 addNotify();
 907             }
 908             validateUnconditionally();
 909             if (visible) {
 910                 toFront();
 911                 retval = false;
 912             } else {
 913                 visible = retval = true;
 914 
 915                 // check if this dialog should be modal blocked BEFORE calling peer.show(),
 916                 // otherwise, a pair of FOCUS_GAINED and FOCUS_LOST may be mistakenly
 917                 // generated for the dialog
 918                 if (!isModal()) {
 919                     checkShouldBeBlocked(this);
 920                 } else {
 921                     modalDialogs.add(this);
 922                     modalShow();
 923                 }
 924 
 925                 if (toFocus != null && time != null && isFocusable() &&
 926                     isEnabled() && !isModalBlocked()) {
 927                     // keep the KeyEvents from being dispatched
 928                     // until the focus has been transfered
 929                     time.set(Toolkit.getEventQueue().getMostRecentEventTimeEx());
 930                     KeyboardFocusManager.getCurrentKeyboardFocusManager().
 931                         enqueueKeyEvents(time.get(), toFocus);
 932                 }
 933 
 934                 // This call is required as the show() method of the Dialog class
 935                 // does not invoke the super.show(). So wried... :(
 936                 mixOnShowing();
 937 
 938                 peer.setVisible(true); // now guaranteed never to block
 939                 if (isModalBlocked()) {
 940                     modalBlocker.toFront();
 941                 }
 942 
 943                 setLocationByPlatform(false);
 944                 for (int i = 0; i < ownedWindowList.size(); i++) {
 945                     Window child = ownedWindowList.elementAt(i).get();
 946                     if ((child != null) && child.showWithParent) {
 947                         child.show();
 948                         child.showWithParent = false;
 949                     }       // endif
 950                 }   // endfor
 951                 Window.updateChildFocusableWindowState(this);
 952 
 953                 createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,
 954                                       this, parent,
 955                                       HierarchyEvent.SHOWING_CHANGED,
 956                                       Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
 957                 if (componentListener != null ||
 958                         (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
 959                         Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
 960                     ComponentEvent e =
 961                         new ComponentEvent(this, ComponentEvent.COMPONENT_SHOWN);
 962                     Toolkit.getEventQueue().postEvent(e);
 963                 }
 964             }
 965         }
 966 
 967         if (retval && (state & OPENED) == 0) {
 968             postWindowEvent(WindowEvent.WINDOW_OPENED);
 969             state |= OPENED;
 970         }
 971 
 972         return retval;
 973     }
 974 
 975     /**
 976      * Shows or hides this {@code Dialog} depending on the value of parameter
 977      * {@code b}.
 978      * @param b if {@code true}, makes the {@code Dialog} visible,
 979      * otherwise hides the {@code Dialog}.
 980      * If the dialog and/or its owner
 981      * are not yet displayable, both are made displayable.  The
 982      * dialog will be validated prior to being made visible.
 983      * If {@code false}, hides the {@code Dialog} and then causes {@code setVisible(true)}
 984      * to return if it is currently blocked.
 985      * <p>
 986      * <b>Notes for modal dialogs</b>.
 987      * <ul>
 988      * <li>{@code setVisible(true)}:  If the dialog is not already
 989      * visible, this call will not return until the dialog is
 990      * hidden by calling {@code setVisible(false)} or
 991      * {@code dispose}.
 992      * <li>{@code setVisible(false)}:  Hides the dialog and then
 993      * returns on {@code setVisible(true)} if it is currently blocked.
 994      * <li>It is OK to call this method from the event dispatching
 995      * thread because the toolkit ensures that other events are
 996      * not blocked while this method is blocked.
 997      * </ul>
 998      * @see java.awt.Window#setVisible
 999      * @see java.awt.Window#dispose
1000      * @see java.awt.Component#isDisplayable
1001      * @see java.awt.Component#validate
1002      * @see java.awt.Dialog#isModal
1003      */
1004     public void setVisible(boolean b) {
1005         super.setVisible(b);
1006     }
1007 
1008    /**
1009      * Makes the {@code Dialog} visible. If the dialog and/or its owner
1010      * are not yet displayable, both are made displayable.  The
1011      * dialog will be validated prior to being made visible.
1012      * If the dialog is already visible, this will bring the dialog
1013      * to the front.
1014      * <p>
1015      * If the dialog is modal and is not already visible, this call
1016      * will not return until the dialog is hidden by calling hide or
1017      * dispose. It is permissible to show modal dialogs from the event
1018      * dispatching thread because the toolkit will ensure that another
1019      * event pump runs while the one which invoked this method is blocked.
1020      * @see Component#hide
1021      * @see Component#isDisplayable
1022      * @see Component#validate
1023      * @see #isModal
1024      * @see Window#setVisible(boolean)
1025      * @deprecated As of JDK version 1.5, replaced by
1026      * {@link #setVisible(boolean) setVisible(boolean)}.
1027      */
1028     @Deprecated
1029     public void show() {
1030         if (!initialized) throw new IllegalStateException(
1031             "The dialog component has not been initialized properly");
1032 
1033         beforeFirstShow = false;
1034         if (!isModal()) {
1035             conditionalShow(null, null);
1036         } else {
1037             AppContext showAppContext = AppContext.getAppContext();
1038 
1039             AtomicLong time = new AtomicLong();
1040             Component predictedFocusOwner = null;
1041             try {
1042                 predictedFocusOwner = getMostRecentFocusOwner();
1043                 if (conditionalShow(predictedFocusOwner, time)) {
1044                     modalFilter = ModalEventFilter.createFilterForDialog(this);
1045                     final Conditional cond = new Conditional() {
1046                         @Override
1047                         public boolean evaluate() {
1048                             return windowClosingException == null;
1049                         }
1050                     };
1051 
1052                     // if this dialog is toolkit-modal, the filter should be added
1053                     // to all EDTs (for all AppContexts)
1054                     if (modalityType == ModalityType.TOOLKIT_MODAL) {
1055                         Iterator it = AppContext.getAppContexts().iterator();
1056                         while (it.hasNext()) {
1057                             AppContext appContext = (AppContext)it.next();
1058                             if (appContext == showAppContext) {
1059                                 continue;
1060                             }
1061                             EventQueue eventQueue = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
1062                             // it may occur that EDT for appContext hasn't been started yet, so
1063                             // we post an empty invocation event to trigger EDT initialization
1064                             Runnable createEDT = new Runnable() {
1065                                 public void run() {};
1066                             };
1067                             eventQueue.postEvent(new InvocationEvent(this, createEDT));
1068                             EventDispatchThread edt = eventQueue.getDispatchThread();
1069                             edt.addEventFilter(modalFilter);
1070                         }
1071                     }
1072 
1073                     modalityPushed();
1074                     try {
1075                         final EventQueue eventQueue = AccessController.doPrivileged(
1076                             new PrivilegedAction<EventQueue>() {
1077                                 public EventQueue run() {
1078                                     return Toolkit.getDefaultToolkit().getSystemEventQueue();
1079                                 }
1080                         });
1081                         secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0);
1082                         if (!secondaryLoop.enter()) {
1083                             secondaryLoop = null;
1084                         }
1085                     } finally {
1086                         modalityPopped();
1087                     }
1088 
1089                     // if this dialog is toolkit-modal, its filter must be removed
1090                     // from all EDTs (for all AppContexts)
1091                     if (modalityType == ModalityType.TOOLKIT_MODAL) {
1092                         Iterator it = AppContext.getAppContexts().iterator();
1093                         while (it.hasNext()) {
1094                             AppContext appContext = (AppContext)it.next();
1095                             if (appContext == showAppContext) {
1096                                 continue;
1097                             }
1098                             EventQueue eventQueue = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
1099                             EventDispatchThread edt = eventQueue.getDispatchThread();
1100                             edt.removeEventFilter(modalFilter);
1101                         }
1102                     }
1103 
1104                     if (windowClosingException != null) {
1105                         windowClosingException.fillInStackTrace();
1106                         throw windowClosingException;
1107                     }
1108                 }
1109             } finally {
1110                 if (predictedFocusOwner != null) {
1111                     // Restore normal key event dispatching
1112                     KeyboardFocusManager.getCurrentKeyboardFocusManager().
1113                         dequeueKeyEvents(time.get(), predictedFocusOwner);
1114                 }
1115             }
1116         }
1117     }
1118 
1119     final void modalityPushed() {
1120         Toolkit tk = Toolkit.getDefaultToolkit();
1121         if (tk instanceof SunToolkit) {
1122             SunToolkit stk = (SunToolkit)tk;
1123             stk.notifyModalityPushed(this);
1124         }
1125     }
1126 
1127     final void modalityPopped() {
1128         Toolkit tk = Toolkit.getDefaultToolkit();
1129         if (tk instanceof SunToolkit) {
1130             SunToolkit stk = (SunToolkit)tk;
1131             stk.notifyModalityPopped(this);
1132         }
1133     }
1134 
1135     void interruptBlocking() {
1136         if (isModal()) {
1137             disposeImpl();
1138         } else if (windowClosingException != null) {
1139             windowClosingException.fillInStackTrace();
1140             windowClosingException.printStackTrace();
1141             windowClosingException = null;
1142         }
1143     }
1144 
1145     private void hideAndDisposePreHandler() {
1146         isInHide = true;
1147         synchronized (getTreeLock()) {
1148             if (secondaryLoop != null) {
1149                 modalHide();
1150                 // dialog can be shown and then disposed before its
1151                 // modal filter is created
1152                 if (modalFilter != null) {
1153                     modalFilter.disable();
1154                 }
1155                 modalDialogs.remove(this);
1156             }
1157         }
1158     }
1159     private void hideAndDisposeHandler() {
1160         if (secondaryLoop != null) {
1161             secondaryLoop.exit();
1162             secondaryLoop = null;
1163         }
1164         isInHide = false;
1165     }
1166 
1167     /**
1168      * Hides the Dialog and then causes {@code show} to return if it is currently
1169      * blocked.
1170      * @see Window#show
1171      * @see Window#dispose
1172      * @see Window#setVisible(boolean)
1173      * @deprecated As of JDK version 1.5, replaced by
1174      * {@link #setVisible(boolean) setVisible(boolean)}.
1175      */
1176     @Deprecated
1177     public void hide() {
1178         hideAndDisposePreHandler();
1179         super.hide();
1180         // fix for 5048370: if hide() is called from super.doDispose(), then
1181         // hideAndDisposeHandler() should not be called here as it will be called
1182         // at the end of doDispose()
1183         if (!isInDispose) {
1184             hideAndDisposeHandler();
1185         }
1186     }
1187 
1188     /**
1189      * Disposes the Dialog and then causes show() to return if it is currently
1190      * blocked.
1191      */
1192     void doDispose() {
1193         // fix for 5048370: set isInDispose flag to true to prevent calling
1194         // to hideAndDisposeHandler() from hide()
1195         isInDispose = true;
1196         super.doDispose();
1197         hideAndDisposeHandler();
1198         isInDispose = false;
1199     }
1200 
1201     /**
1202      * {@inheritDoc}
1203      * <p>
1204      * If this dialog is modal and blocks some windows, then all of them are
1205      * also sent to the back to keep them below the blocking dialog.
1206      *
1207      * @see java.awt.Window#toBack
1208      */
1209     public void toBack() {
1210         super.toBack();
1211         if (visible) {
1212             synchronized (getTreeLock()) {
1213                 for (Window w : blockedWindows) {
1214                     w.toBack_NoClientCode();
1215                 }
1216             }
1217         }
1218     }
1219 
1220     /**
1221      * Indicates whether this dialog is resizable by the user.
1222      * By default, all dialogs are initially resizable.
1223      * @return    <code>true</code> if the user can resize the dialog;
1224      *            <code>false</code> otherwise.
1225      * @see       java.awt.Dialog#setResizable
1226      */
1227     public boolean isResizable() {
1228         return resizable;
1229     }
1230 
1231     /**
1232      * Sets whether this dialog is resizable by the user.
1233      * @param     resizable <code>true</code> if the user can
1234      *                 resize this dialog; <code>false</code> otherwise.
1235      * @see       java.awt.Dialog#isResizable
1236      */
1237     public void setResizable(boolean resizable) {
1238         boolean testvalid = false;
1239 
1240         synchronized (this) {
1241             this.resizable = resizable;
1242             DialogPeer peer = (DialogPeer)this.peer;
1243             if (peer != null) {
1244                 peer.setResizable(resizable);
1245                 testvalid = true;
1246             }
1247         }
1248 
1249         // On some platforms, changing the resizable state affects
1250         // the insets of the Dialog. If we could, we'd call invalidate()
1251         // from the peer, but we need to guarantee that we're not holding
1252         // the Dialog lock when we call invalidate().
1253         if (testvalid) {
1254             invalidateIfValid();
1255         }
1256     }
1257 
1258 
1259     /**
1260      * Disables or enables decorations for this dialog.
1261      * <p>
1262      * This method can only be called while the dialog is not displayable. To
1263      * make this dialog decorated, it must be opaque and have the default shape,
1264      * otherwise the {@code IllegalComponentStateException} will be thrown.
1265      * Refer to {@link Window#setShape}, {@link Window#setOpacity} and {@link
1266      * Window#setBackground} for details
1267      *
1268      * @param  undecorated {@code true} if no dialog decorations are to be
1269      *         enabled; {@code false} if dialog decorations are to be enabled
1270      *
1271      * @throws IllegalComponentStateException if the dialog is displayable
1272      * @throws IllegalComponentStateException if {@code undecorated} is
1273      *      {@code false}, and this dialog does not have the default shape
1274      * @throws IllegalComponentStateException if {@code undecorated} is
1275      *      {@code false}, and this dialog opacity is less than {@code 1.0f}
1276      * @throws IllegalComponentStateException if {@code undecorated} is
1277      *      {@code false}, and the alpha value of this dialog background
1278      *      color is less than {@code 1.0f}
1279      *
1280      * @see    #isUndecorated
1281      * @see    Component#isDisplayable
1282      * @see    Window#getShape
1283      * @see    Window#getOpacity
1284      * @see    Window#getBackground
1285      *
1286      * @since 1.4
1287      */
1288     public void setUndecorated(boolean undecorated) {
1289         /* Make sure we don't run in the middle of peer creation.*/
1290         synchronized (getTreeLock()) {
1291             if (isDisplayable()) {
1292                 throw new IllegalComponentStateException("The dialog is displayable.");
1293             }
1294             if (!undecorated) {
1295                 if (getOpacity() < 1.0f) {
1296                     throw new IllegalComponentStateException("The dialog is not opaque");
1297                 }
1298                 if (getShape() != null) {
1299                     throw new IllegalComponentStateException("The dialog does not have a default shape");
1300                 }
1301                 Color bg = getBackground();
1302                 if ((bg != null) && (bg.getAlpha() < 255)) {
1303                     throw new IllegalComponentStateException("The dialog background color is not opaque");
1304                 }
1305             }
1306             this.undecorated = undecorated;
1307         }
1308     }
1309 
1310     /**
1311      * Indicates whether this dialog is undecorated.
1312      * By default, all dialogs are initially decorated.
1313      * @return    <code>true</code> if dialog is undecorated;
1314      *                        <code>false</code> otherwise.
1315      * @see       java.awt.Dialog#setUndecorated
1316      * @since 1.4
1317      */
1318     public boolean isUndecorated() {
1319         return undecorated;
1320     }
1321 
1322     /**
1323      * {@inheritDoc}
1324      */
1325     @Override
1326     public void setOpacity(float opacity) {
1327         synchronized (getTreeLock()) {
1328             if ((opacity < 1.0f) && !isUndecorated()) {
1329                 throw new IllegalComponentStateException("The dialog is decorated");
1330             }
1331             super.setOpacity(opacity);
1332         }
1333     }
1334 
1335     /**
1336      * {@inheritDoc}
1337      */
1338     @Override
1339     public void setShape(Shape shape) {
1340         synchronized (getTreeLock()) {
1341             if ((shape != null) && !isUndecorated()) {
1342                 throw new IllegalComponentStateException("The dialog is decorated");
1343             }
1344             super.setShape(shape);
1345         }
1346     }
1347 
1348     /**
1349      * {@inheritDoc}
1350      */
1351     @Override
1352     public void setBackground(Color bgColor) {
1353         synchronized (getTreeLock()) {
1354             if ((bgColor != null) && (bgColor.getAlpha() < 255) && !isUndecorated()) {
1355                 throw new IllegalComponentStateException("The dialog is decorated");
1356             }
1357             super.setBackground(bgColor);
1358         }
1359     }
1360 
1361     /**
1362      * Returns a string representing the state of this dialog. This
1363      * method is intended to be used only for debugging purposes, and the
1364      * content and format of the returned string may vary between
1365      * implementations. The returned string may be empty but may not be
1366      * <code>null</code>.
1367      *
1368      * @return    the parameter string of this dialog window.
1369      */
1370     protected String paramString() {
1371         String str = super.paramString() + "," + modalityType;
1372         if (title != null) {
1373             str += ",title=" + title;
1374         }
1375         return str;
1376     }
1377 
1378     /**
1379      * Initialize JNI field and method IDs
1380      */
1381     private static native void initIDs();
1382 
1383     /*
1384      * --- Modality support ---
1385      *
1386      */
1387 
1388     /*
1389      * This method is called only for modal dialogs.
1390      *
1391      * Goes through the list of all visible top-level windows and
1392      * divide them into three distinct groups: blockers of this dialog,
1393      * blocked by this dialog and all others. Then blocks this dialog
1394      * by first met dialog from the first group (if any) and blocks all
1395      * the windows from the second group.
1396      */
1397     void modalShow() {
1398         // find all the dialogs that block this one
1399         IdentityArrayList<Dialog> blockers = new IdentityArrayList<Dialog>();
1400         for (Dialog d : modalDialogs) {
1401             if (d.shouldBlock(this)) {
1402                 Window w = d;
1403                 while ((w != null) && (w != this)) {
1404                     w = (Window)(w.getOwner_NoClientCode());
1405                 }
1406                 if ((w == this) || !shouldBlock(d) || (modalityType.compareTo(d.getModalityType()) < 0)) {
1407                     blockers.add(d);
1408                 }
1409             }
1410         }
1411 
1412         // add all blockers' blockers to blockers :)
1413         for (int i = 0; i < blockers.size(); i++) {
1414             Dialog blocker = blockers.get(i);
1415             if (blocker.isModalBlocked()) {
1416                 Dialog blockerBlocker = blocker.getModalBlocker();
1417                 if (!blockers.contains(blockerBlocker)) {
1418                     blockers.add(i + 1, blockerBlocker);
1419                 }
1420             }
1421         }
1422 
1423         if (blockers.size() > 0) {
1424             blockers.get(0).blockWindow(this);
1425         }
1426 
1427         // find all windows from blockers' hierarchies
1428         IdentityArrayList<Window> blockersHierarchies = new IdentityArrayList<Window>(blockers);
1429         int k = 0;
1430         while (k < blockersHierarchies.size()) {
1431             Window w = blockersHierarchies.get(k);
1432             Window[] ownedWindows = w.getOwnedWindows_NoClientCode();
1433             for (Window win : ownedWindows) {
1434                 blockersHierarchies.add(win);
1435             }
1436             k++;
1437         }
1438 
1439         java.util.List<Window> toBlock = new IdentityLinkedList<Window>();
1440         // block all windows from scope of blocking except from blockers' hierarchies
1441         IdentityArrayList<Window> unblockedWindows = Window.getAllUnblockedWindows();
1442         for (Window w : unblockedWindows) {
1443             if (shouldBlock(w) && !blockersHierarchies.contains(w)) {
1444                 if ((w instanceof Dialog) && ((Dialog)w).isModal_NoClientCode()) {
1445                     Dialog wd = (Dialog)w;
1446                     if (wd.shouldBlock(this) && (modalDialogs.indexOf(wd) > modalDialogs.indexOf(this))) {
1447                         continue;
1448                     }
1449                 }
1450                 toBlock.add(w);
1451             }
1452         }
1453         blockWindows(toBlock);
1454 
1455         if (!isModalBlocked()) {
1456             updateChildrenBlocking();
1457         }
1458     }
1459 
1460     /*
1461      * This method is called only for modal dialogs.
1462      *
1463      * Unblocks all the windows blocked by this modal dialog. After
1464      * each of them has been unblocked, it is checked to be blocked by
1465      * any other modal dialogs.
1466      */
1467     void modalHide() {
1468         // we should unblock all the windows first...
1469         IdentityArrayList<Window> save = new IdentityArrayList<Window>();
1470         int blockedWindowsCount = blockedWindows.size();
1471         for (int i = 0; i < blockedWindowsCount; i++) {
1472             Window w = blockedWindows.get(0);
1473             save.add(w);
1474             unblockWindow(w); // also removes w from blockedWindows
1475         }
1476         // ... and only after that check if they should be blocked
1477         // by another dialogs
1478         for (int i = 0; i < blockedWindowsCount; i++) {
1479             Window w = save.get(i);
1480             if ((w instanceof Dialog) && ((Dialog)w).isModal_NoClientCode()) {
1481                 Dialog d = (Dialog)w;
1482                 d.modalShow();
1483             } else {
1484                 checkShouldBeBlocked(w);
1485             }
1486         }
1487     }
1488 
1489     /*
1490      * Returns whether the given top-level window should be blocked by
1491      * this dialog. Note, that the given window can be also a modal dialog
1492      * and it should block this dialog, but this method do not take such
1493      * situations into consideration (such checks are performed in the
1494      * modalShow() and modalHide() methods).
1495      *
1496      * This method should be called on the getTreeLock() lock.
1497      */
1498     boolean shouldBlock(Window w) {
1499         if (!isVisible_NoClientCode() ||
1500             (!w.isVisible_NoClientCode() && !w.isInShow) ||
1501             isInHide ||
1502             (w == this) ||
1503             !isModal_NoClientCode())
1504         {
1505             return false;
1506         }
1507         if ((w instanceof Dialog) && ((Dialog)w).isInHide) {
1508             return false;
1509         }
1510         // check if w is from children hierarchy
1511         // fix for 6271546: we should also take into consideration child hierarchies
1512         // of this dialog's blockers
1513         Window blockerToCheck = this;
1514         while (blockerToCheck != null) {
1515             Component c = w;
1516             while ((c != null) && (c != blockerToCheck)) {
1517                 c = c.getParent_NoClientCode();
1518             }
1519             if (c == blockerToCheck) {
1520                 return false;
1521             }
1522             blockerToCheck = blockerToCheck.getModalBlocker();
1523         }
1524         switch (modalityType) {
1525             case MODELESS:
1526                 return false;
1527             case DOCUMENT_MODAL:
1528                 if (w.isModalExcluded(ModalExclusionType.APPLICATION_EXCLUDE)) {
1529                     // application- and toolkit-excluded windows are not blocked by
1530                     // document-modal dialogs from outside their children hierarchy
1531                     Component c = this;
1532                     while ((c != null) && (c != w)) {
1533                         c = c.getParent_NoClientCode();
1534                     }
1535                     return c == w;
1536                 } else {
1537                     return getDocumentRoot() == w.getDocumentRoot();
1538                 }
1539             case APPLICATION_MODAL:
1540                 return !w.isModalExcluded(ModalExclusionType.APPLICATION_EXCLUDE) &&
1541                     (appContext == w.appContext);
1542             case TOOLKIT_MODAL:
1543                 return !w.isModalExcluded(ModalExclusionType.TOOLKIT_EXCLUDE);
1544         }
1545 
1546         return false;
1547     }
1548 
1549     /*
1550      * Adds the given top-level window to the list of blocked
1551      * windows for this dialog and marks it as modal blocked.
1552      * If the window is already blocked by some modal dialog,
1553      * does nothing.
1554      */
1555     void blockWindow(Window w) {
1556         if (!w.isModalBlocked()) {
1557             w.setModalBlocked(this, true, true);
1558             blockedWindows.add(w);
1559         }
1560     }
1561 
1562     void blockWindows(java.util.List<Window> toBlock) {
1563         DialogPeer dpeer = (DialogPeer)peer;
1564         if (dpeer == null) {
1565             return;
1566         }
1567         Iterator<Window> it = toBlock.iterator();
1568         while (it.hasNext()) {
1569             Window w = it.next();
1570             if (!w.isModalBlocked()) {
1571                 w.setModalBlocked(this, true, false);
1572             } else {
1573                 it.remove();
1574             }
1575         }
1576         dpeer.blockWindows(toBlock);
1577         blockedWindows.addAll(toBlock);
1578     }
1579 
1580     /*
1581      * Removes the given top-level window from the list of blocked
1582      * windows for this dialog and marks it as unblocked. If the
1583      * window is not modal blocked, does nothing.
1584      */
1585     void unblockWindow(Window w) {
1586         if (w.isModalBlocked() && blockedWindows.contains(w)) {
1587             blockedWindows.remove(w);
1588             w.setModalBlocked(this, false, true);
1589         }
1590     }
1591 
1592     /*
1593      * Checks if any other modal dialog D blocks the given window.
1594      * If such D exists, mark the window as blocked by D.
1595      */
1596     static void checkShouldBeBlocked(Window w) {
1597         synchronized (w.getTreeLock()) {
1598             for (int i = 0; i < modalDialogs.size(); i++) {
1599                 Dialog modalDialog = modalDialogs.get(i);
1600                 if (modalDialog.shouldBlock(w)) {
1601                     modalDialog.blockWindow(w);
1602                     break;
1603                 }
1604             }
1605         }
1606     }
1607 
1608     private void checkModalityPermission(ModalityType mt) {
1609         if (mt == ModalityType.TOOLKIT_MODAL) {
1610             SecurityManager sm = System.getSecurityManager();
1611             if (sm != null) {
1612                 sm.checkPermission(
1613                     SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION
1614                 );
1615             }
1616         }
1617     }
1618 
1619     private void readObject(ObjectInputStream s)
1620         throws ClassNotFoundException, IOException, HeadlessException
1621     {
1622         GraphicsEnvironment.checkHeadless();
1623 
1624         java.io.ObjectInputStream.GetField fields =
1625                     s.readFields();
1626 
1627         ModalityType localModalityType = (ModalityType)fields.get("modalityType", null);
1628 
1629         try {
1630             checkModalityPermission(localModalityType);
1631         } catch (AccessControlException ace) {
1632             localModalityType = DEFAULT_MODALITY_TYPE;
1633         }
1634 
1635         // in 1.5 or earlier modalityType was absent, so use "modal" instead
1636         if (localModalityType == null) {
1637             this.modal = fields.get("modal", false);
1638             setModal(modal);
1639         } else {
1640             this.modalityType = localModalityType;
1641         }
1642 
1643         this.resizable = fields.get("resizable", true);
1644         this.undecorated = fields.get("undecorated", false);
1645         this.title = (String)fields.get("title", "");
1646 
1647         blockedWindows = new IdentityArrayList();
1648 
1649         SunToolkit.checkAndSetPolicy(this);
1650 
1651         initialized = true;
1652 
1653     }
1654 
1655     /*
1656      * --- Accessibility Support ---
1657      *
1658      */
1659 
1660     /**
1661      * Gets the AccessibleContext associated with this Dialog.
1662      * For dialogs, the AccessibleContext takes the form of an
1663      * AccessibleAWTDialog.
1664      * A new AccessibleAWTDialog instance is created if necessary.
1665      *
1666      * @return an AccessibleAWTDialog that serves as the
1667      *         AccessibleContext of this Dialog
1668      * @since 1.3
1669      */
1670     public AccessibleContext getAccessibleContext() {
1671         if (accessibleContext == null) {
1672             accessibleContext = new AccessibleAWTDialog();
1673         }
1674         return accessibleContext;
1675     }
1676 
1677     /**
1678      * This class implements accessibility support for the
1679      * <code>Dialog</code> class.  It provides an implementation of the
1680      * Java Accessibility API appropriate to dialog user-interface elements.
1681      * @since 1.3
1682      */
1683     protected class AccessibleAWTDialog extends AccessibleAWTWindow
1684     {
1685         /*
1686          * JDK 1.3 serialVersionUID
1687          */
1688         private static final long serialVersionUID = 4837230331833941201L;
1689 
1690         /**
1691          * Get the role of this object.
1692          *
1693          * @return an instance of AccessibleRole describing the role of the
1694          * object
1695          * @see AccessibleRole
1696          */
1697         public AccessibleRole getAccessibleRole() {
1698             return AccessibleRole.DIALOG;
1699         }
1700 
1701         /**
1702          * Get the state of this object.
1703          *
1704          * @return an instance of AccessibleStateSet containing the current
1705          * state set of the object
1706          * @see AccessibleState
1707          */
1708         public AccessibleStateSet getAccessibleStateSet() {
1709             AccessibleStateSet states = super.getAccessibleStateSet();
1710             if (getFocusOwner() != null) {
1711                 states.add(AccessibleState.ACTIVE);
1712             }
1713             if (isModal()) {
1714                 states.add(AccessibleState.MODAL);
1715             }
1716             if (isResizable()) {
1717                 states.add(AccessibleState.RESIZABLE);
1718             }
1719             return states;
1720         }
1721 
1722     } // inner class AccessibleAWTDialog
1723 }