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