1 /* 2 * Copyright (c) 1995, 2008, 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, false); 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, false); 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 validate(); 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().getMostRecentEventTimeEx()); 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 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 EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); 1071 secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0); 1072 if (!secondaryLoop.enter()) { 1073 secondaryLoop = null; 1074 } 1075 } finally { 1076 modalityPopped(); 1077 } 1078 1079 // if this dialog is toolkit-modal, its filter must be removed 1080 // from all EDTs (for all AppContexts) 1081 if (modalityType == ModalityType.TOOLKIT_MODAL) { 1082 Iterator it = AppContext.getAppContexts().iterator(); 1083 while (it.hasNext()) { 1084 AppContext appContext = (AppContext)it.next(); 1085 if (appContext == showAppContext) { 1086 continue; 1087 } 1088 EventQueue eventQueue = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY); 1089 EventDispatchThread edt = eventQueue.getDispatchThread(); 1090 edt.removeEventFilter(modalFilter); 1091 } 1092 } 1093 1094 if (windowClosingException != null) { 1095 windowClosingException.fillInStackTrace(); 1096 throw windowClosingException; 1097 } 1098 } 1099 } finally { 1100 if (predictedFocusOwner != null) { 1101 // Restore normal key event dispatching 1102 KeyboardFocusManager.getCurrentKeyboardFocusManager(). 1103 dequeueKeyEvents(time.get(), predictedFocusOwner); 1104 } 1105 } 1106 } 1107 } 1108 1109 final void modalityPushed() { 1110 Toolkit tk = Toolkit.getDefaultToolkit(); 1111 if (tk instanceof SunToolkit) { 1112 SunToolkit stk = (SunToolkit)tk; 1113 stk.notifyModalityPushed(this); 1114 } 1115 } 1116 1117 final void modalityPopped() { 1118 Toolkit tk = Toolkit.getDefaultToolkit(); 1119 if (tk instanceof SunToolkit) { 1120 SunToolkit stk = (SunToolkit)tk; 1121 stk.notifyModalityPopped(this); 1122 } 1123 } 1124 1125 void interruptBlocking() { 1126 if (isModal()) { 1127 disposeImpl(); 1128 } else if (windowClosingException != null) { 1129 windowClosingException.fillInStackTrace(); 1130 windowClosingException.printStackTrace(); 1131 windowClosingException = null; 1132 } 1133 } 1134 1135 private void hideAndDisposePreHandler() { 1136 isInHide = true; 1137 synchronized (getTreeLock()) { 1138 if (secondaryLoop != null) { 1139 modalHide(); 1140 // dialog can be shown and then disposed before its 1141 // modal filter is created 1142 if (modalFilter != null) { 1143 modalFilter.disable(); 1144 } 1145 modalDialogs.remove(this); 1146 } 1147 } 1148 } 1149 private void hideAndDisposeHandler() { 1150 if (secondaryLoop != null) { 1151 secondaryLoop.exit(); 1152 secondaryLoop = null; 1153 } 1154 isInHide = false; 1155 } 1156 1157 /** 1158 * Hides the Dialog and then causes {@code show} to return if it is currently 1159 * blocked. 1160 * @see Window#show 1161 * @see Window#dispose 1162 * @see Window#setVisible(boolean) 1163 * @deprecated As of JDK version 1.5, replaced by 1164 * {@link #setVisible(boolean) setVisible(boolean)}. 1165 */ 1166 @Deprecated 1167 public void hide() { 1168 hideAndDisposePreHandler(); 1169 super.hide(); 1170 // fix for 5048370: if hide() is called from super.doDispose(), then 1171 // hideAndDisposeHandler() should not be called here as it will be called 1172 // at the end of doDispose() 1173 if (!isInDispose) { 1174 hideAndDisposeHandler(); 1175 } 1176 } 1177 1178 /** 1179 * Disposes the Dialog and then causes show() to return if it is currently 1180 * blocked. 1181 */ 1182 void doDispose() { 1183 // fix for 5048370: set isInDispose flag to true to prevent calling 1184 // to hideAndDisposeHandler() from hide() 1185 isInDispose = true; 1186 super.doDispose(); 1187 hideAndDisposeHandler(); 1188 isInDispose = false; 1189 } 1190 1191 /** 1192 * {@inheritDoc} 1193 * <p> 1194 * If this dialog is modal and blocks some windows, then all of them are 1195 * also sent to the back to keep them below the blocking dialog. 1196 * 1197 * @see java.awt.Window#toBack 1198 */ 1199 public void toBack() { 1200 super.toBack(); 1201 if (visible) { 1202 synchronized (getTreeLock()) { 1203 for (Window w : blockedWindows) { 1204 w.toBack_NoClientCode(); 1205 } 1206 } 1207 } 1208 } 1209 1210 /** 1211 * Indicates whether this dialog is resizable by the user. 1212 * By default, all dialogs are initially resizable. 1213 * @return <code>true</code> if the user can resize the dialog; 1214 * <code>false</code> otherwise. 1215 * @see java.awt.Dialog#setResizable 1216 */ 1217 public boolean isResizable() { 1218 return resizable; 1219 } 1220 1221 /** 1222 * Sets whether this dialog is resizable by the user. 1223 * @param resizable <code>true</code> if the user can 1224 * resize this dialog; <code>false</code> otherwise. 1225 * @see java.awt.Dialog#isResizable 1226 */ 1227 public void setResizable(boolean resizable) { 1228 boolean testvalid = false; 1229 1230 synchronized (this) { 1231 this.resizable = resizable; 1232 DialogPeer peer = (DialogPeer)this.peer; 1233 if (peer != null) { 1234 peer.setResizable(resizable); 1235 testvalid = true; 1236 } 1237 } 1238 1239 // On some platforms, changing the resizable state affects 1240 // the insets of the Dialog. If we could, we'd call invalidate() 1241 // from the peer, but we need to guarantee that we're not holding 1242 // the Dialog lock when we call invalidate(). 1243 if (testvalid) { 1244 invalidateIfValid(); 1245 } 1246 } 1247 1248 1249 /** 1250 * Disables or enables decorations for this dialog. 1251 * <p> 1252 * This method can only be called while the dialog is not displayable. To 1253 * make this dialog decorated, it must be opaque and have the default shape, 1254 * otherwise the {@code IllegalComponentStateException} will be thrown. 1255 * Refer to {@link Window#setShape}, {@link Window#setOpacity} and {@link 1256 * Window#setBackground} for details 1257 * 1258 * @param undecorated {@code true} if no dialog decorations are to be 1259 * enabled; {@code false} if dialog decorations are to be enabled 1260 * 1261 * @throws IllegalComponentStateException if the dialog is displayable 1262 * @throws IllegalComponentStateException if {@code undecorated} is 1263 * {@code false}, and this dialog does not have the default shape 1264 * @throws IllegalComponentStateException if {@code undecorated} is 1265 * {@code false}, and this dialog opacity is less than {@code 1.0f} 1266 * @throws IllegalComponentStateException if {@code undecorated} is 1267 * {@code false}, and the alpha value of this dialog background 1268 * color is less than {@code 1.0f} 1269 * 1270 * @see #isUndecorated 1271 * @see Component#isDisplayable 1272 * @see Window#getShape 1273 * @see Window#getOpacity 1274 * @see Window#getBackground 1275 * 1276 * @since 1.4 1277 */ 1278 public void setUndecorated(boolean undecorated) { 1279 /* Make sure we don't run in the middle of peer creation.*/ 1280 synchronized (getTreeLock()) { 1281 if (isDisplayable()) { 1282 throw new IllegalComponentStateException("The dialog is displayable."); 1283 } 1284 if (!undecorated) { 1285 if (getOpacity() < 1.0f) { 1286 throw new IllegalComponentStateException("The dialog is not opaque"); 1287 } 1288 if (getShape() != null) { 1289 throw new IllegalComponentStateException("The dialog does not have a default shape"); 1290 } 1291 Color bg = getBackground(); 1292 if ((bg != null) && (bg.getAlpha() < 255)) { 1293 throw new IllegalComponentStateException("The dialog background color is not opaque"); 1294 } 1295 } 1296 this.undecorated = undecorated; 1297 } 1298 } 1299 1300 /** 1301 * Indicates whether this dialog is undecorated. 1302 * By default, all dialogs are initially decorated. 1303 * @return <code>true</code> if dialog is undecorated; 1304 * <code>false</code> otherwise. 1305 * @see java.awt.Dialog#setUndecorated 1306 * @since 1.4 1307 */ 1308 public boolean isUndecorated() { 1309 return undecorated; 1310 } 1311 1312 /** 1313 * {@inheritDoc} 1314 */ 1315 @Override 1316 public void setOpacity(float opacity) { 1317 synchronized (getTreeLock()) { 1318 if ((opacity < 1.0f) && !isUndecorated()) { 1319 throw new IllegalComponentStateException("The dialog is decorated"); 1320 } 1321 super.setOpacity(opacity); 1322 } 1323 } 1324 1325 /** 1326 * {@inheritDoc} 1327 */ 1328 @Override 1329 public void setShape(Shape shape) { 1330 synchronized (getTreeLock()) { 1331 if ((shape != null) && !isUndecorated()) { 1332 throw new IllegalComponentStateException("The dialog is decorated"); 1333 } 1334 super.setShape(shape); 1335 } 1336 } 1337 1338 /** 1339 * {@inheritDoc} 1340 */ 1341 @Override 1342 public void setBackground(Color bgColor) { 1343 synchronized (getTreeLock()) { 1344 if ((bgColor != null) && (bgColor.getAlpha() < 255) && !isUndecorated()) { 1345 throw new IllegalComponentStateException("The dialog is decorated"); 1346 } 1347 super.setBackground(bgColor); 1348 } 1349 } 1350 1351 /** 1352 * Returns a string representing the state of this dialog. This 1353 * method is intended to be used only for debugging purposes, and the 1354 * content and format of the returned string may vary between 1355 * implementations. The returned string may be empty but may not be 1356 * <code>null</code>. 1357 * 1358 * @return the parameter string of this dialog window. 1359 */ 1360 protected String paramString() { 1361 String str = super.paramString() + "," + modalityType; 1362 if (title != null) { 1363 str += ",title=" + title; 1364 } 1365 return str; 1366 } 1367 1368 /** 1369 * Initialize JNI field and method IDs 1370 */ 1371 private static native void initIDs(); 1372 1373 /* 1374 * --- Modality support --- 1375 * 1376 */ 1377 1378 /* 1379 * This method is called only for modal dialogs. 1380 * 1381 * Goes through the list of all visible top-level windows and 1382 * divide them into three distinct groups: blockers of this dialog, 1383 * blocked by this dialog and all others. Then blocks this dialog 1384 * by first met dialog from the first group (if any) and blocks all 1385 * the windows from the second group. 1386 */ 1387 void modalShow() { 1388 // find all the dialogs that block this one 1389 IdentityArrayList<Dialog> blockers = new IdentityArrayList<Dialog>(); 1390 for (Dialog d : modalDialogs) { 1391 if (d.shouldBlock(this)) { 1392 Window w = d; 1393 while ((w != null) && (w != this)) { 1394 w = (Window)(w.getOwner_NoClientCode()); 1395 } 1396 if ((w == this) || !shouldBlock(d) || (modalityType.compareTo(d.getModalityType()) < 0)) { 1397 blockers.add(d); 1398 } 1399 } 1400 } 1401 1402 // add all blockers' blockers to blockers :) 1403 for (int i = 0; i < blockers.size(); i++) { 1404 Dialog blocker = blockers.get(i); 1405 if (blocker.isModalBlocked()) { 1406 Dialog blockerBlocker = blocker.getModalBlocker(); 1407 if (!blockers.contains(blockerBlocker)) { 1408 blockers.add(i + 1, blockerBlocker); 1409 } 1410 } 1411 } 1412 1413 if (blockers.size() > 0) { 1414 blockers.get(0).blockWindow(this); 1415 } 1416 1417 // find all windows from blockers' hierarchies 1418 IdentityArrayList<Window> blockersHierarchies = new IdentityArrayList<Window>(blockers); 1419 int k = 0; 1420 while (k < blockersHierarchies.size()) { 1421 Window w = blockersHierarchies.get(k); 1422 Window[] ownedWindows = w.getOwnedWindows_NoClientCode(); 1423 for (Window win : ownedWindows) { 1424 blockersHierarchies.add(win); 1425 } 1426 k++; 1427 } 1428 1429 java.util.List<Window> toBlock = new IdentityLinkedList<Window>(); 1430 // block all windows from scope of blocking except from blockers' hierarchies 1431 IdentityArrayList<Window> unblockedWindows = Window.getAllUnblockedWindows(); 1432 for (Window w : unblockedWindows) { 1433 if (shouldBlock(w) && !blockersHierarchies.contains(w)) { 1434 if ((w instanceof Dialog) && ((Dialog)w).isModal_NoClientCode()) { 1435 Dialog wd = (Dialog)w; 1436 if (wd.shouldBlock(this) && (modalDialogs.indexOf(wd) > modalDialogs.indexOf(this))) { 1437 continue; 1438 } 1439 } 1440 toBlock.add(w); 1441 } 1442 } 1443 blockWindows(toBlock); 1444 1445 if (!isModalBlocked()) { 1446 updateChildrenBlocking(); 1447 } 1448 } 1449 1450 /* 1451 * This method is called only for modal dialogs. 1452 * 1453 * Unblocks all the windows blocked by this modal dialog. After 1454 * each of them has been unblocked, it is checked to be blocked by 1455 * any other modal dialogs. 1456 */ 1457 void modalHide() { 1458 // we should unblock all the windows first... 1459 IdentityArrayList<Window> save = new IdentityArrayList<Window>(); 1460 int blockedWindowsCount = blockedWindows.size(); 1461 for (int i = 0; i < blockedWindowsCount; i++) { 1462 Window w = blockedWindows.get(0); 1463 save.add(w); 1464 unblockWindow(w); // also removes w from blockedWindows 1465 } 1466 // ... and only after that check if they should be blocked 1467 // by another dialogs 1468 for (int i = 0; i < blockedWindowsCount; i++) { 1469 Window w = save.get(i); 1470 if ((w instanceof Dialog) && ((Dialog)w).isModal_NoClientCode()) { 1471 Dialog d = (Dialog)w; 1472 d.modalShow(); 1473 } else { 1474 checkShouldBeBlocked(w); 1475 } 1476 } 1477 } 1478 1479 /* 1480 * Returns whether the given top-level window should be blocked by 1481 * this dialog. Note, that the given window can be also a modal dialog 1482 * and it should block this dialog, but this method do not take such 1483 * situations into consideration (such checks are performed in the 1484 * modalShow() and modalHide() methods). 1485 * 1486 * This method should be called on the getTreeLock() lock. 1487 */ 1488 boolean shouldBlock(Window w) { 1489 if (!isVisible_NoClientCode() || 1490 (!w.isVisible_NoClientCode() && !w.isInShow) || 1491 isInHide || 1492 (w == this) || 1493 !isModal_NoClientCode()) 1494 { 1495 return false; 1496 } 1497 if ((w instanceof Dialog) && ((Dialog)w).isInHide) { 1498 return false; 1499 } 1500 // check if w is from children hierarchy 1501 // fix for 6271546: we should also take into consideration child hierarchies 1502 // of this dialog's blockers 1503 Window blockerToCheck = this; 1504 while (blockerToCheck != null) { 1505 Component c = w; 1506 while ((c != null) && (c != blockerToCheck)) { 1507 c = c.getParent_NoClientCode(); 1508 } 1509 if (c == blockerToCheck) { 1510 return false; 1511 } 1512 blockerToCheck = blockerToCheck.getModalBlocker(); 1513 } 1514 switch (modalityType) { 1515 case MODELESS: 1516 return false; 1517 case DOCUMENT_MODAL: 1518 if (w.isModalExcluded(ModalExclusionType.APPLICATION_EXCLUDE)) { 1519 // application- and toolkit-excluded windows are not blocked by 1520 // document-modal dialogs from outside their children hierarchy 1521 Component c = this; 1522 while ((c != null) && (c != w)) { 1523 c = c.getParent_NoClientCode(); 1524 } 1525 return c == w; 1526 } else { 1527 return getDocumentRoot() == w.getDocumentRoot(); 1528 } 1529 case APPLICATION_MODAL: 1530 return !w.isModalExcluded(ModalExclusionType.APPLICATION_EXCLUDE) && 1531 (appContext == w.appContext); 1532 case TOOLKIT_MODAL: 1533 return !w.isModalExcluded(ModalExclusionType.TOOLKIT_EXCLUDE); 1534 } 1535 1536 return false; 1537 } 1538 1539 /* 1540 * Adds the given top-level window to the list of blocked 1541 * windows for this dialog and marks it as modal blocked. 1542 * If the window is already blocked by some modal dialog, 1543 * does nothing. 1544 */ 1545 void blockWindow(Window w) { 1546 if (!w.isModalBlocked()) { 1547 w.setModalBlocked(this, true, true); 1548 blockedWindows.add(w); 1549 } 1550 } 1551 1552 void blockWindows(java.util.List<Window> toBlock) { 1553 DialogPeer dpeer = (DialogPeer)peer; 1554 if (dpeer == null) { 1555 return; 1556 } 1557 Iterator<Window> it = toBlock.iterator(); 1558 while (it.hasNext()) { 1559 Window w = it.next(); 1560 if (!w.isModalBlocked()) { 1561 w.setModalBlocked(this, true, false); 1562 } else { 1563 it.remove(); 1564 } 1565 } 1566 dpeer.blockWindows(toBlock); 1567 blockedWindows.addAll(toBlock); 1568 } 1569 1570 /* 1571 * Removes the given top-level window from the list of blocked 1572 * windows for this dialog and marks it as unblocked. If the 1573 * window is not modal blocked, does nothing. 1574 */ 1575 void unblockWindow(Window w) { 1576 if (w.isModalBlocked() && blockedWindows.contains(w)) { 1577 blockedWindows.remove(w); 1578 w.setModalBlocked(this, false, true); 1579 } 1580 } 1581 1582 /* 1583 * Checks if any other modal dialog D blocks the given window. 1584 * If such D exists, mark the window as blocked by D. 1585 */ 1586 static void checkShouldBeBlocked(Window w) { 1587 synchronized (w.getTreeLock()) { 1588 for (int i = 0; i < modalDialogs.size(); i++) { 1589 Dialog modalDialog = modalDialogs.get(i); 1590 if (modalDialog.shouldBlock(w)) { 1591 modalDialog.blockWindow(w); 1592 break; 1593 } 1594 } 1595 } 1596 } 1597 1598 private void readObject(ObjectInputStream s) 1599 throws ClassNotFoundException, IOException, HeadlessException 1600 { 1601 GraphicsEnvironment.checkHeadless(); 1602 s.defaultReadObject(); 1603 1604 // in 1.5 or earlier modalityType was absent, so use "modal" instead 1605 if (modalityType == null) { 1606 setModal(modal); 1607 } 1608 1609 blockedWindows = new IdentityArrayList(); 1610 } 1611 1612 /* 1613 * --- Accessibility Support --- 1614 * 1615 */ 1616 1617 /** 1618 * Gets the AccessibleContext associated with this Dialog. 1619 * For dialogs, the AccessibleContext takes the form of an 1620 * AccessibleAWTDialog. 1621 * A new AccessibleAWTDialog instance is created if necessary. 1622 * 1623 * @return an AccessibleAWTDialog that serves as the 1624 * AccessibleContext of this Dialog 1625 * @since 1.3 1626 */ 1627 public AccessibleContext getAccessibleContext() { 1628 if (accessibleContext == null) { 1629 accessibleContext = new AccessibleAWTDialog(); 1630 } 1631 return accessibleContext; 1632 } 1633 1634 /** 1635 * This class implements accessibility support for the 1636 * <code>Dialog</code> class. It provides an implementation of the 1637 * Java Accessibility API appropriate to dialog user-interface elements. 1638 * @since 1.3 1639 */ 1640 protected class AccessibleAWTDialog extends AccessibleAWTWindow 1641 { 1642 /* 1643 * JDK 1.3 serialVersionUID 1644 */ 1645 private static final long serialVersionUID = 4837230331833941201L; 1646 1647 /** 1648 * Get the role of this object. 1649 * 1650 * @return an instance of AccessibleRole describing the role of the 1651 * object 1652 * @see AccessibleRole 1653 */ 1654 public AccessibleRole getAccessibleRole() { 1655 return AccessibleRole.DIALOG; 1656 } 1657 1658 /** 1659 * Get the state of this object. 1660 * 1661 * @return an instance of AccessibleStateSet containing the current 1662 * state set of the object 1663 * @see AccessibleState 1664 */ 1665 public AccessibleStateSet getAccessibleStateSet() { 1666 AccessibleStateSet states = super.getAccessibleStateSet(); 1667 if (getFocusOwner() != null) { 1668 states.add(AccessibleState.ACTIVE); 1669 } 1670 if (isModal()) { 1671 states.add(AccessibleState.MODAL); 1672 } 1673 if (isResizable()) { 1674 states.add(AccessibleState.RESIZABLE); 1675 } 1676 return states; 1677 } 1678 1679 } // inner class AccessibleAWTDialog 1680 }