1 /* 2 * Copyright (c) 1997, 2014, 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 javax.swing; 26 27 import java.awt.*; 28 import java.awt.event.*; 29 import javax.accessibility.*; 30 31 /** 32 * The main class for creating a dialog window. You can use this class 33 * to create a custom dialog, or invoke the many class methods 34 * in {@link JOptionPane} to create a variety of standard dialogs. 35 * For information about creating dialogs, see 36 * <em>The Java Tutorial</em> section 37 * <a 38 href="http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html">How 39 * to Make Dialogs</a>. 40 * 41 * <p> 42 * 43 * The {@code JDialog} component contains a {@code JRootPane} 44 * as its only child. 45 * The {@code contentPane} should be the parent of any children of the 46 * {@code JDialog}. 47 * As a convenience, the {@code add}, {@code remove}, and {@code setLayout} 48 * methods of this class are overridden, so that they delegate calls 49 * to the corresponding methods of the {@code ContentPane}. 50 * For example, you can add a child component to a dialog as follows: 51 * <pre> 52 * dialog.add(child); 53 * </pre> 54 * And the child will be added to the contentPane. 55 * The {@code contentPane} is always non-{@code null}. 56 * Attempting to set it to {@code null} generates an exception. 57 * The default {@code contentPane} has a {@code BorderLayout} 58 * manager set on it. 59 * Refer to {@link javax.swing.RootPaneContainer} 60 * for details on adding, removing and setting the {@code LayoutManager} 61 * of a {@code JDialog}. 62 * <p> 63 * Please see the {@code JRootPane} documentation for a complete 64 * description of the {@code contentPane}, {@code glassPane}, 65 * and {@code layeredPane} components. 66 * <p> 67 * In a multi-screen environment, you can create a {@code JDialog} 68 * on a different screen device than its owner. See {@link java.awt.Frame} for 69 * more information. 70 * <p> 71 * <strong>Warning:</strong> Swing is not thread safe. For more 72 * information see <a 73 * href="package-summary.html#threading">Swing's Threading 74 * Policy</a>. 75 * <p> 76 * <strong>Warning:</strong> 77 * Serialized objects of this class will not be compatible with 78 * future Swing releases. The current serialization support is 79 * appropriate for short term storage or RMI between applications running 80 * the same version of Swing. As of 1.4, support for long term storage 81 * of all JavaBeans™ 82 * has been added to the {@code java.beans} package. 83 * Please see {@link java.beans.XMLEncoder}. 84 * 85 * @see JOptionPane 86 * @see JRootPane 87 * @see javax.swing.RootPaneContainer 88 * 89 * @beaninfo 90 * attribute: isContainer true 91 * attribute: containerDelegate getContentPane 92 * description: A toplevel window for creating dialog boxes. 93 * 94 * @author David Kloba 95 * @author James Gosling 96 * @author Scott Violet 97 * @since 1.2 98 */ 99 @SuppressWarnings("serial") // Same-version serialization only 100 public class JDialog extends Dialog implements WindowConstants, 101 Accessible, 102 RootPaneContainer, 103 TransferHandler.HasGetTransferHandler 104 { 105 /** 106 * Key into the AppContext, used to check if should provide decorations 107 * by default. 108 */ 109 private static final Object defaultLookAndFeelDecoratedKey = 110 new StringBuffer("JDialog.defaultLookAndFeelDecorated"); 111 112 private int defaultCloseOperation = HIDE_ON_CLOSE; 113 114 /** 115 * @see #getRootPane 116 * @see #setRootPane 117 */ 118 protected JRootPane rootPane; 119 120 /** 121 * If true then calls to {@code add} and {@code setLayout} 122 * will be forwarded to the {@code contentPane}. This is initially 123 * false, but is set to true when the {@code JDialog} is constructed. 124 * 125 * @see #isRootPaneCheckingEnabled 126 * @see #setRootPaneCheckingEnabled 127 * @see javax.swing.RootPaneContainer 128 */ 129 protected boolean rootPaneCheckingEnabled = false; 130 131 /** 132 * The {@code TransferHandler} for this dialog. 133 */ 134 private TransferHandler transferHandler; 135 136 /** 137 * Creates a modeless dialog without a title and without a specified 138 * {@code Frame} owner. A shared, hidden frame will be 139 * set as the owner of the dialog. 140 * <p> 141 * This constructor sets the component's locale property to the value 142 * returned by {@code JComponent.getDefaultLocale}. 143 * <p> 144 * NOTE: This constructor does not allow you to create an unowned 145 * {@code JDialog}. To create an unowned {@code JDialog} 146 * you must use either the {@code JDialog(Window)} or 147 * {@code JDialog(Dialog)} constructor with an argument of 148 * {@code null}. 149 * 150 * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} 151 * returns {@code true}. 152 * @see java.awt.GraphicsEnvironment#isHeadless 153 * @see JComponent#getDefaultLocale 154 */ 155 public JDialog() { 156 this((Frame)null, false); 157 } 158 159 /** 160 * Creates a modeless dialog with the specified {@code Frame} 161 * as its owner and an empty title. If {@code owner} 162 * is {@code null}, a shared, hidden frame will be set as the 163 * owner of the dialog. 164 * <p> 165 * This constructor sets the component's locale property to the value 166 * returned by {@code JComponent.getDefaultLocale}. 167 * <p> 168 * NOTE: This constructor does not allow you to create an unowned 169 * {@code JDialog}. To create an unowned {@code JDialog} 170 * you must use either the {@code JDialog(Window)} or 171 * {@code JDialog(Dialog)} constructor with an argument of 172 * {@code null}. 173 * 174 * @param owner the {@code Frame} from which the dialog is displayed 175 * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} 176 * returns {@code true}. 177 * @see java.awt.GraphicsEnvironment#isHeadless 178 * @see JComponent#getDefaultLocale 179 */ 180 public JDialog(Frame owner) { 181 this(owner, false); 182 } 183 184 /** 185 * Creates a dialog with an empty title and the specified modality and 186 * {@code Frame} as its owner. If {@code owner} is {@code null}, 187 * a shared, hidden frame will be set as the owner of the dialog. 188 * <p> 189 * This constructor sets the component's locale property to the value 190 * returned by {@code JComponent.getDefaultLocale}. 191 * <p> 192 * NOTE: This constructor does not allow you to create an unowned 193 * {@code JDialog}. To create an unowned {@code JDialog} 194 * you must use either the {@code JDialog(Window)} or 195 * {@code JDialog(Dialog)} constructor with an argument of 196 * {@code null}. 197 * 198 * @param owner the {@code Frame} from which the dialog is displayed 199 * @param modal specifies whether dialog blocks user input to other top-level 200 * windows when shown. If {@code true}, the modality type property is set to 201 * {@code DEFAULT_MODALITY_TYPE}, otherwise the dialog is modeless. 202 * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} 203 * returns {@code true}. 204 * @see java.awt.GraphicsEnvironment#isHeadless 205 * @see JComponent#getDefaultLocale 206 */ 207 public JDialog(Frame owner, boolean modal) { 208 this(owner, "", modal); 209 } 210 211 /** 212 * Creates a modeless dialog with the specified title and 213 * with the specified owner frame. If {@code owner} 214 * is {@code null}, a shared, hidden frame will be set as the 215 * owner of the dialog. 216 * <p> 217 * This constructor sets the component's locale property to the value 218 * returned by {@code JComponent.getDefaultLocale}. 219 * <p> 220 * NOTE: This constructor does not allow you to create an unowned 221 * {@code JDialog}. To create an unowned {@code JDialog} 222 * you must use either the {@code JDialog(Window)} or 223 * {@code JDialog(Dialog)} constructor with an argument of 224 * {@code null}. 225 * 226 * @param owner the {@code Frame} from which the dialog is displayed 227 * @param title the {@code String} to display in the dialog's 228 * title bar 229 * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} 230 * returns {@code true}. 231 * @see java.awt.GraphicsEnvironment#isHeadless 232 * @see JComponent#getDefaultLocale 233 */ 234 public JDialog(Frame owner, String title) { 235 this(owner, title, false); 236 } 237 238 /** 239 * Creates a dialog with the specified title, owner {@code Frame} 240 * and modality. If {@code owner} is {@code null}, 241 * a shared, hidden frame will be set as the owner of this dialog. 242 * <p> 243 * This constructor sets the component's locale property to the value 244 * returned by {@code JComponent.getDefaultLocale}. 245 * <p> 246 * NOTE: Any popup components ({@code JComboBox}, 247 * {@code JPopupMenu}, {@code JMenuBar}) 248 * created within a modal dialog will be forced to be lightweight. 249 * <p> 250 * NOTE: This constructor does not allow you to create an unowned 251 * {@code JDialog}. To create an unowned {@code JDialog} 252 * you must use either the {@code JDialog(Window)} or 253 * {@code JDialog(Dialog)} constructor with an argument of 254 * {@code null}. 255 * 256 * @param owner the {@code Frame} from which the dialog is displayed 257 * @param title the {@code String} to display in the dialog's 258 * title bar 259 * @param modal specifies whether dialog blocks user input to other top-level 260 * windows when shown. If {@code true}, the modality type property is set to 261 * {@code DEFAULT_MODALITY_TYPE} otherwise the dialog is modeless 262 * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} 263 * returns {@code true}. 264 * 265 * @see java.awt.Dialog.ModalityType 266 * @see java.awt.Dialog.ModalityType#MODELESS 267 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE 268 * @see java.awt.Dialog#setModal 269 * @see java.awt.Dialog#setModalityType 270 * @see java.awt.GraphicsEnvironment#isHeadless 271 * @see JComponent#getDefaultLocale 272 */ 273 public JDialog(Frame owner, String title, boolean modal) { 274 super(owner == null? SwingUtilities.getSharedOwnerFrame() : owner, 275 title, modal); 276 if (owner == null) { 277 WindowListener ownerShutdownListener = 278 SwingUtilities.getSharedOwnerFrameShutdownListener(); 279 addWindowListener(ownerShutdownListener); 280 } 281 dialogInit(); 282 } 283 284 /** 285 * Creates a dialog with the specified title, 286 * owner {@code Frame}, modality and {@code GraphicsConfiguration}. 287 * If {@code owner} is {@code null}, 288 * a shared, hidden frame will be set as the owner of this dialog. 289 * <p> 290 * This constructor sets the component's locale property to the value 291 * returned by {@code JComponent.getDefaultLocale}. 292 * <p> 293 * NOTE: Any popup components ({@code JComboBox}, 294 * {@code JPopupMenu}, {@code JMenuBar}) 295 * created within a modal dialog will be forced to be lightweight. 296 * <p> 297 * NOTE: This constructor does not allow you to create an unowned 298 * {@code JDialog}. To create an unowned {@code JDialog} 299 * you must use either the {@code JDialog(Window)} or 300 * {@code JDialog(Dialog)} constructor with an argument of 301 * {@code null}. 302 * 303 * @param owner the {@code Frame} from which the dialog is displayed 304 * @param title the {@code String} to display in the dialog's 305 * title bar 306 * @param modal specifies whether dialog blocks user input to other top-level 307 * windows when shown. If {@code true}, the modality type property is set to 308 * {@code DEFAULT_MODALITY_TYPE}, otherwise the dialog is modeless. 309 * @param gc the {@code GraphicsConfiguration} of the target screen device; 310 * if {@code null}, the default system {@code GraphicsConfiguration} 311 * is assumed 312 * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} 313 * returns {@code true}. 314 * @see java.awt.Dialog.ModalityType 315 * @see java.awt.Dialog.ModalityType#MODELESS 316 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE 317 * @see java.awt.Dialog#setModal 318 * @see java.awt.Dialog#setModalityType 319 * @see java.awt.GraphicsEnvironment#isHeadless 320 * @see JComponent#getDefaultLocale 321 * @since 1.4 322 */ 323 public JDialog(Frame owner, String title, boolean modal, 324 GraphicsConfiguration gc) { 325 super(owner == null? SwingUtilities.getSharedOwnerFrame() : owner, 326 title, modal, gc); 327 if (owner == null) { 328 WindowListener ownerShutdownListener = 329 SwingUtilities.getSharedOwnerFrameShutdownListener(); 330 addWindowListener(ownerShutdownListener); 331 } 332 dialogInit(); 333 } 334 335 /** 336 * Creates a modeless dialog with the specified {@code Dialog} 337 * as its owner and an empty title. 338 * <p> 339 * This constructor sets the component's locale property to the value 340 * returned by {@code JComponent.getDefaultLocale}. 341 * 342 * @param owner the owner {@code Dialog} from which the dialog is displayed 343 * or {@code null} if this dialog has no owner 344 * @throws HeadlessException {@code if GraphicsEnvironment.isHeadless()} 345 * returns {@code true}. 346 * @see java.awt.GraphicsEnvironment#isHeadless 347 * @see JComponent#getDefaultLocale 348 */ 349 public JDialog(Dialog owner) { 350 this(owner, false); 351 } 352 353 /** 354 * Creates a dialog with an empty title and the specified modality and 355 * {@code Dialog} as its owner. 356 * <p> 357 * This constructor sets the component's locale property to the value 358 * returned by {@code JComponent.getDefaultLocale}. 359 * 360 * @param owner the owner {@code Dialog} from which the dialog is displayed 361 * or {@code null} if this dialog has no owner 362 * @param modal specifies whether dialog blocks user input to other top-level 363 * windows when shown. If {@code true}, the modality type property is set to 364 * {@code DEFAULT_MODALITY_TYPE}, otherwise the dialog is modeless. 365 * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} 366 * returns {@code true}. 367 * @see java.awt.Dialog.ModalityType 368 * @see java.awt.Dialog.ModalityType#MODELESS 369 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE 370 * @see java.awt.Dialog#setModal 371 * @see java.awt.Dialog#setModalityType 372 * @see java.awt.GraphicsEnvironment#isHeadless 373 * @see JComponent#getDefaultLocale 374 */ 375 public JDialog(Dialog owner, boolean modal) { 376 this(owner, "", modal); 377 } 378 379 /** 380 * Creates a modeless dialog with the specified title and 381 * with the specified owner dialog. 382 * <p> 383 * This constructor sets the component's locale property to the value 384 * returned by {@code JComponent.getDefaultLocale}. 385 * 386 * @param owner the owner {@code Dialog} from which the dialog is displayed 387 * or {@code null} if this dialog has no owner 388 * @param title the {@code String} to display in the dialog's 389 * title bar 390 * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} 391 * returns {@code true}. 392 * @see java.awt.GraphicsEnvironment#isHeadless 393 * @see JComponent#getDefaultLocale 394 */ 395 public JDialog(Dialog owner, String title) { 396 this(owner, title, false); 397 } 398 399 /** 400 * Creates a dialog with the specified title, modality 401 * and the specified owner {@code Dialog}. 402 * <p> 403 * This constructor sets the component's locale property to the value 404 * returned by {@code JComponent.getDefaultLocale}. 405 * 406 * @param owner the owner {@code Dialog} from which the dialog is displayed 407 * or {@code null} if this dialog has no owner 408 * @param title the {@code String} to display in the dialog's 409 * title bar 410 * @param modal specifies whether dialog blocks user input to other top-level 411 * windows when shown. If {@code true}, the modality type property is set to 412 * {@code DEFAULT_MODALITY_TYPE}, otherwise the dialog is modeless 413 * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} 414 * returns {@code true}. 415 * @see java.awt.Dialog.ModalityType 416 * @see java.awt.Dialog.ModalityType#MODELESS 417 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE 418 * @see java.awt.Dialog#setModal 419 * @see java.awt.Dialog#setModalityType 420 * @see java.awt.GraphicsEnvironment#isHeadless 421 * @see JComponent#getDefaultLocale 422 */ 423 public JDialog(Dialog owner, String title, boolean modal) { 424 super(owner, title, modal); 425 dialogInit(); 426 } 427 428 /** 429 * Creates a dialog with the specified title, owner {@code Dialog}, 430 * modality and {@code GraphicsConfiguration}. 431 * 432 * <p> 433 * NOTE: Any popup components ({@code JComboBox}, 434 * {@code JPopupMenu}, {@code JMenuBar}) 435 * created within a modal dialog will be forced to be lightweight. 436 * <p> 437 * This constructor sets the component's locale property to the value 438 * returned by {@code JComponent.getDefaultLocale}. 439 * 440 * @param owner the owner {@code Dialog} from which the dialog is displayed 441 * or {@code null} if this dialog has no owner 442 * @param title the {@code String} to display in the dialog's 443 * title bar 444 * @param modal specifies whether dialog blocks user input to other top-level 445 * windows when shown. If {@code true}, the modality type property is set to 446 * {@code DEFAULT_MODALITY_TYPE}, otherwise the dialog is modeless 447 * @param gc the {@code GraphicsConfiguration} of the target screen device; 448 * if {@code null}, the default system {@code GraphicsConfiguration} 449 * is assumed 450 * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} 451 * returns {@code true}. 452 * @see java.awt.Dialog.ModalityType 453 * @see java.awt.Dialog.ModalityType#MODELESS 454 * @see java.awt.Dialog#DEFAULT_MODALITY_TYPE 455 * @see java.awt.Dialog#setModal 456 * @see java.awt.Dialog#setModalityType 457 * @see java.awt.GraphicsEnvironment#isHeadless 458 * @see JComponent#getDefaultLocale 459 * @since 1.4 460 */ 461 public JDialog(Dialog owner, String title, boolean modal, 462 GraphicsConfiguration gc) { 463 super(owner, title, modal, gc); 464 dialogInit(); 465 } 466 467 /** 468 * Creates a modeless dialog with the specified {@code Window} 469 * as its owner and an empty title. 470 * <p> 471 * This constructor sets the component's locale property to the value 472 * returned by {@code JComponent.getDefaultLocale}. 473 * 474 * @param owner the {@code Window} from which the dialog is displayed or 475 * {@code null} if this dialog has no owner 476 * 477 * @throws IllegalArgumentException 478 * if the {@code owner} is not an instance of {@link java.awt.Dialog Dialog} 479 * or {@link java.awt.Frame Frame} 480 * @throws IllegalArgumentException 481 * if the {@code owner}'s {@code GraphicsConfiguration} is not from a screen device 482 * @throws HeadlessException 483 * when {@code GraphicsEnvironment.isHeadless()} returns {@code true} 484 * 485 * @see java.awt.GraphicsEnvironment#isHeadless 486 * @see JComponent#getDefaultLocale 487 * 488 * @since 1.6 489 */ 490 public JDialog(Window owner) { 491 this(owner, Dialog.ModalityType.MODELESS); 492 } 493 494 /** 495 * Creates a dialog with an empty title and the specified modality and 496 * {@code Window} as its owner. 497 * <p> 498 * This constructor sets the component's locale property to the value 499 * returned by {@code JComponent.getDefaultLocale}. 500 * 501 * @param owner the {@code Window} from which the dialog is displayed or 502 * {@code null} if this dialog has no owner 503 * @param modalityType specifies whether dialog blocks input to other 504 * windows when shown. {@code null} value and unsupported modality 505 * types are equivalent to {@code MODELESS} 506 * 507 * @throws IllegalArgumentException 508 * if the {@code owner} is not an instance of {@link java.awt.Dialog Dialog} 509 * or {@link java.awt.Frame Frame} 510 * @throws IllegalArgumentException 511 * if the {@code owner}'s {@code GraphicsConfiguration} is not from a screen device 512 * @throws HeadlessException 513 * when {@code GraphicsEnvironment.isHeadless()} returns {@code true} 514 * @throws SecurityException 515 * if the calling thread does not have permission to create modal dialogs 516 * with the given {@code modalityType} 517 * 518 * @see java.awt.Dialog.ModalityType 519 * @see java.awt.Dialog#setModal 520 * @see java.awt.Dialog#setModalityType 521 * @see java.awt.GraphicsEnvironment#isHeadless 522 * @see JComponent#getDefaultLocale 523 * 524 * @since 1.6 525 */ 526 public JDialog(Window owner, ModalityType modalityType) { 527 this(owner, "", modalityType); 528 } 529 530 /** 531 * Creates a modeless dialog with the specified title and owner 532 * {@code Window}. 533 * <p> 534 * This constructor sets the component's locale property to the value 535 * returned by {@code JComponent.getDefaultLocale}. 536 * 537 * @param owner the {@code Window} from which the dialog is displayed or 538 * {@code null} if this dialog has no owner 539 * @param title the {@code String} to display in the dialog's 540 * title bar or {@code null} if the dialog has no title 541 * 542 * @throws IllegalArgumentException 543 * if the {@code owner} is not an instance of {@link java.awt.Dialog Dialog} 544 * or {@link java.awt.Frame Frame} 545 * @throws IllegalArgumentException 546 * if the {@code owner}'s {@code GraphicsConfiguration} is not from a screen device 547 * @throws HeadlessException 548 * when {@code GraphicsEnvironment.isHeadless()} returns {@code true} 549 * 550 * @see java.awt.GraphicsEnvironment#isHeadless 551 * @see JComponent#getDefaultLocale 552 * 553 * @since 1.6 554 */ 555 public JDialog(Window owner, String title) { 556 this(owner, title, Dialog.ModalityType.MODELESS); 557 } 558 559 /** 560 * Creates a dialog with the specified title, owner {@code Window} and 561 * modality. 562 * <p> 563 * This constructor sets the component's locale property to the value 564 * returned by {@code JComponent.getDefaultLocale}. 565 * 566 * @param owner the {@code Window} from which the dialog is displayed or 567 * {@code null} if this dialog has no owner 568 * @param title the {@code String} to display in the dialog's 569 * title bar or {@code null} if the dialog has no title 570 * @param modalityType specifies whether dialog blocks input to other 571 * windows when shown. {@code null} value and unsupported modality 572 * types are equivalent to {@code MODELESS} 573 * 574 * @throws IllegalArgumentException 575 * if the {@code owner} is not an instance of {@link java.awt.Dialog Dialog} 576 * or {@link java.awt.Frame Frame} 577 * @throws IllegalArgumentException 578 * if the {@code owner}'s {@code GraphicsConfiguration} is not from a screen device 579 * @throws HeadlessException 580 * when {@code GraphicsEnvironment.isHeadless()} returns {@code true} 581 * @throws SecurityException 582 * if the calling thread does not have permission to create modal dialogs 583 * with the given {@code modalityType} 584 * 585 * @see java.awt.Dialog.ModalityType 586 * @see java.awt.Dialog#setModal 587 * @see java.awt.Dialog#setModalityType 588 * @see java.awt.GraphicsEnvironment#isHeadless 589 * @see JComponent#getDefaultLocale 590 * 591 * @since 1.6 592 */ 593 public JDialog(Window owner, String title, Dialog.ModalityType modalityType) { 594 super(owner, title, modalityType); 595 dialogInit(); 596 } 597 598 /** 599 * Creates a dialog with the specified title, owner {@code Window}, 600 * modality and {@code GraphicsConfiguration}. 601 * <p> 602 * NOTE: Any popup components ({@code JComboBox}, 603 * {@code JPopupMenu}, {@code JMenuBar}) 604 * created within a modal dialog will be forced to be lightweight. 605 * <p> 606 * This constructor sets the component's locale property to the value 607 * returned by {@code JComponent.getDefaultLocale}. 608 * 609 * @param owner the {@code Window} from which the dialog is displayed or 610 * {@code null} if this dialog has no owner 611 * @param title the {@code String} to display in the dialog's 612 * title bar or {@code null} if the dialog has no title 613 * @param modalityType specifies whether dialog blocks input to other 614 * windows when shown. {@code null} value and unsupported modality 615 * types are equivalent to {@code MODELESS} 616 * @param gc the {@code GraphicsConfiguration} of the target screen device; 617 * if {@code null}, the default system {@code GraphicsConfiguration} 618 * is assumed 619 * @throws IllegalArgumentException 620 * if the {@code owner} is not an instance of {@link java.awt.Dialog Dialog} 621 * or {@link java.awt.Frame Frame} 622 * @throws IllegalArgumentException 623 * if the {@code owner}'s {@code GraphicsConfiguration} is not from a screen device 624 * @throws HeadlessException 625 * when {@code GraphicsEnvironment.isHeadless()} returns {@code true} 626 * @throws SecurityException 627 * if the calling thread does not have permission to create modal dialogs 628 * with the given {@code modalityType} 629 * 630 * @see java.awt.Dialog.ModalityType 631 * @see java.awt.Dialog#setModal 632 * @see java.awt.Dialog#setModalityType 633 * @see java.awt.GraphicsEnvironment#isHeadless 634 * @see JComponent#getDefaultLocale 635 * 636 * @since 1.6 637 */ 638 public JDialog(Window owner, String title, Dialog.ModalityType modalityType, 639 GraphicsConfiguration gc) { 640 super(owner, title, modalityType, gc); 641 dialogInit(); 642 } 643 644 /** 645 * Called by the constructors to init the {@code JDialog} properly. 646 */ 647 protected void dialogInit() { 648 enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK); 649 setLocale( JComponent.getDefaultLocale() ); 650 setRootPane(createRootPane()); 651 setBackground(UIManager.getColor("control")); 652 setRootPaneCheckingEnabled(true); 653 if (JDialog.isDefaultLookAndFeelDecorated()) { 654 boolean supportsWindowDecorations = 655 UIManager.getLookAndFeel().getSupportsWindowDecorations(); 656 if (supportsWindowDecorations) { 657 setUndecorated(true); 658 getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG); 659 } 660 } 661 sun.awt.SunToolkit.checkAndSetPolicy(this); 662 } 663 664 /** 665 * Called by the constructor methods to create the default 666 * {@code rootPane}. 667 * 668 * @return a new {@code JRootPane} 669 */ 670 protected JRootPane createRootPane() { 671 JRootPane rp = new JRootPane(); 672 // NOTE: this uses setOpaque vs LookAndFeel.installProperty as there 673 // is NO reason for the RootPane not to be opaque. For painting to 674 // work the contentPane must be opaque, therefor the RootPane can 675 // also be opaque. 676 rp.setOpaque(true); 677 return rp; 678 } 679 680 /** 681 * Handles window events depending on the state of the 682 * {@code defaultCloseOperation} property. 683 * 684 * @see #setDefaultCloseOperation 685 */ 686 protected void processWindowEvent(WindowEvent e) { 687 super.processWindowEvent(e); 688 689 if (e.getID() == WindowEvent.WINDOW_CLOSING) { 690 switch(defaultCloseOperation) { 691 case HIDE_ON_CLOSE: 692 setVisible(false); 693 break; 694 case DISPOSE_ON_CLOSE: 695 dispose(); 696 break; 697 case DO_NOTHING_ON_CLOSE: 698 default: 699 break; 700 } 701 } 702 } 703 704 705 /** 706 * Sets the operation that will happen by default when 707 * the user initiates a "close" on this dialog. 708 * You must specify one of the following choices: 709 * <br><br> 710 * <ul> 711 * <li>{@code DO_NOTHING_ON_CLOSE} 712 * (defined in {@code WindowConstants}): 713 * Don't do anything; require the 714 * program to handle the operation in the {@code windowClosing} 715 * method of a registered {@code WindowListener} object. 716 * 717 * <li>{@code HIDE_ON_CLOSE} 718 * (defined in {@code WindowConstants}): 719 * Automatically hide the dialog after 720 * invoking any registered {@code WindowListener} 721 * objects. 722 * 723 * <li>{@code DISPOSE_ON_CLOSE} 724 * (defined in {@code WindowConstants}): 725 * Automatically hide and dispose the 726 * dialog after invoking any registered {@code WindowListener} 727 * objects. 728 * </ul> 729 * <p> 730 * The value is set to {@code HIDE_ON_CLOSE} by default. Changes 731 * to the value of this property cause the firing of a property 732 * change event, with property name "defaultCloseOperation". 733 * <p> 734 * <b>Note</b>: When the last displayable window within the 735 * Java virtual machine (VM) is disposed of, the VM may 736 * terminate. See <a href="../../java/awt/doc-files/AWTThreadIssues.html"> 737 * AWT Threading Issues</a> for more information. 738 * 739 * @param operation the operation which should be performed when the 740 * user closes the dialog 741 * @throws IllegalArgumentException if defaultCloseOperation value 742 * isn't one of the above valid values 743 * @see #addWindowListener 744 * @see #getDefaultCloseOperation 745 * @see WindowConstants 746 * 747 * @beaninfo 748 * preferred: true 749 * bound: true 750 * enum: DO_NOTHING_ON_CLOSE WindowConstants.DO_NOTHING_ON_CLOSE 751 * HIDE_ON_CLOSE WindowConstants.HIDE_ON_CLOSE 752 * DISPOSE_ON_CLOSE WindowConstants.DISPOSE_ON_CLOSE 753 * description: The dialog's default close operation. 754 */ 755 public void setDefaultCloseOperation(int operation) { 756 if (operation != DO_NOTHING_ON_CLOSE && 757 operation != HIDE_ON_CLOSE && 758 operation != DISPOSE_ON_CLOSE) { 759 throw new IllegalArgumentException("defaultCloseOperation must be one of: DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE, or DISPOSE_ON_CLOSE"); 760 } 761 762 int oldValue = this.defaultCloseOperation; 763 this.defaultCloseOperation = operation; 764 firePropertyChange("defaultCloseOperation", oldValue, operation); 765 } 766 767 /** 768 * Returns the operation which occurs when the user 769 * initiates a "close" on this dialog. 770 * 771 * @return an integer indicating the window-close operation 772 * @see #setDefaultCloseOperation 773 */ 774 public int getDefaultCloseOperation() { 775 return defaultCloseOperation; 776 } 777 778 /** 779 * Sets the {@code transferHandler} property, which is a mechanism to 780 * support transfer of data into this component. Use {@code null} 781 * if the component does not support data transfer operations. 782 * <p> 783 * If the system property {@code suppressSwingDropSupport} is {@code false} 784 * (the default) and the current drop target on this component is either 785 * {@code null} or not a user-set drop target, this method will change the 786 * drop target as follows: If {@code newHandler} is {@code null} it will 787 * clear the drop target. If not {@code null} it will install a new 788 * {@code DropTarget}. 789 * <p> 790 * Note: When used with {@code JDialog}, {@code TransferHandler} only 791 * provides data import capability, as the data export related methods 792 * are currently typed to {@code JComponent}. 793 * <p> 794 * Please see 795 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html"> 796 * How to Use Drag and Drop and Data Transfer</a>, a section in 797 * <em>The Java Tutorial</em>, for more information. 798 * 799 * @param newHandler the new {@code TransferHandler} 800 * 801 * @see TransferHandler 802 * @see #getTransferHandler 803 * @see java.awt.Component#setDropTarget 804 * @since 1.6 805 * 806 * @beaninfo 807 * bound: true 808 * hidden: true 809 * description: Mechanism for transfer of data into the component 810 */ 811 public void setTransferHandler(TransferHandler newHandler) { 812 TransferHandler oldHandler = transferHandler; 813 transferHandler = newHandler; 814 SwingUtilities.installSwingDropTargetAsNecessary(this, transferHandler); 815 firePropertyChange("transferHandler", oldHandler, newHandler); 816 } 817 818 /** 819 * Gets the {@code transferHandler} property. 820 * 821 * @return the value of the {@code transferHandler} property 822 * 823 * @see TransferHandler 824 * @see #setTransferHandler 825 * @since 1.6 826 */ 827 public TransferHandler getTransferHandler() { 828 return transferHandler; 829 } 830 831 /** 832 * Calls {@code paint(g)}. This method was overridden to 833 * prevent an unnecessary call to clear the background. 834 * 835 * @param g the {@code Graphics} context in which to paint 836 */ 837 public void update(Graphics g) { 838 paint(g); 839 } 840 841 /** 842 * Sets the menubar for this dialog. 843 * 844 * @param menu the menubar being placed in the dialog 845 * 846 * @see #getJMenuBar 847 * 848 * @beaninfo 849 * hidden: true 850 * description: The menubar for accessing pulldown menus from this dialog. 851 */ 852 @SuppressWarnings("deprecation") 853 public void setJMenuBar(JMenuBar menu) { 854 getRootPane().setMenuBar(menu); 855 } 856 857 /** 858 * Returns the menubar set on this dialog. 859 * 860 * @return the menubar set on this dialog 861 * @see #setJMenuBar 862 */ 863 @SuppressWarnings("deprecation") 864 public JMenuBar getJMenuBar() { 865 return getRootPane().getMenuBar(); 866 } 867 868 869 /** 870 * Returns whether calls to {@code add} and 871 * {@code setLayout} are forwarded to the {@code contentPane}. 872 * 873 * @return true if {@code add} and {@code setLayout} 874 * are forwarded; false otherwise 875 * 876 * @see #addImpl 877 * @see #setLayout 878 * @see #setRootPaneCheckingEnabled 879 * @see javax.swing.RootPaneContainer 880 */ 881 protected boolean isRootPaneCheckingEnabled() { 882 return rootPaneCheckingEnabled; 883 } 884 885 886 /** 887 * Sets whether calls to {@code add} and 888 * {@code setLayout} are forwarded to the {@code contentPane}. 889 * 890 * @param enabled true if {@code add} and {@code setLayout} 891 * are forwarded, false if they should operate directly on the 892 * {@code JDialog}. 893 * 894 * @see #addImpl 895 * @see #setLayout 896 * @see #isRootPaneCheckingEnabled 897 * @see javax.swing.RootPaneContainer 898 * @beaninfo 899 * hidden: true 900 * description: Whether the add and setLayout methods are forwarded 901 */ 902 protected void setRootPaneCheckingEnabled(boolean enabled) { 903 rootPaneCheckingEnabled = enabled; 904 } 905 906 /** 907 * Adds the specified child {@code Component}. 908 * This method is overridden to conditionally forward calls to the 909 * {@code contentPane}. 910 * By default, children are added to the {@code contentPane} instead 911 * of the frame, refer to {@link javax.swing.RootPaneContainer} for 912 * details. 913 * 914 * @param comp the component to be enhanced 915 * @param constraints the constraints to be respected 916 * @param index the index 917 * @throws IllegalArgumentException if {@code index} is invalid 918 * @throws IllegalArgumentException if adding the container's parent 919 * to itself 920 * @throws IllegalArgumentException if adding a window to a container 921 * 922 * @see #setRootPaneCheckingEnabled 923 * @see javax.swing.RootPaneContainer 924 */ 925 protected void addImpl(Component comp, Object constraints, int index) 926 { 927 if(isRootPaneCheckingEnabled()) { 928 getContentPane().add(comp, constraints, index); 929 } 930 else { 931 super.addImpl(comp, constraints, index); 932 } 933 } 934 935 /** 936 * Removes the specified component from the container. If 937 * {@code comp} is not the {@code rootPane}, this will forward 938 * the call to the {@code contentPane}. This will do nothing if 939 * {@code comp} is not a child of the {@code JDialog} or 940 * {@code contentPane}. 941 * 942 * @param comp the component to be removed 943 * @throws NullPointerException if {@code comp} is null 944 * @see #add 945 * @see javax.swing.RootPaneContainer 946 */ 947 public void remove(Component comp) { 948 if (comp == rootPane) { 949 super.remove(comp); 950 } else { 951 getContentPane().remove(comp); 952 } 953 } 954 955 956 /** 957 * Sets the {@code LayoutManager}. 958 * Overridden to conditionally forward the call to the 959 * {@code contentPane}. 960 * Refer to {@link javax.swing.RootPaneContainer} for 961 * more information. 962 * 963 * @param manager the {@code LayoutManager} 964 * @see #setRootPaneCheckingEnabled 965 * @see javax.swing.RootPaneContainer 966 */ 967 public void setLayout(LayoutManager manager) { 968 if(isRootPaneCheckingEnabled()) { 969 getContentPane().setLayout(manager); 970 } 971 else { 972 super.setLayout(manager); 973 } 974 } 975 976 977 /** 978 * Returns the {@code rootPane} object for this dialog. 979 * 980 * @see #setRootPane 981 * @see RootPaneContainer#getRootPane 982 */ 983 public JRootPane getRootPane() { 984 return rootPane; 985 } 986 987 988 /** 989 * Sets the {@code rootPane} property. 990 * This method is called by the constructor. 991 * 992 * @param root the {@code rootPane} object for this dialog 993 * 994 * @see #getRootPane 995 * 996 * @beaninfo 997 * hidden: true 998 * description: the RootPane object for this dialog. 999 */ 1000 protected void setRootPane(JRootPane root) { 1001 if(rootPane != null) { 1002 remove(rootPane); 1003 } 1004 rootPane = root; 1005 if(rootPane != null) { 1006 boolean checkingEnabled = isRootPaneCheckingEnabled(); 1007 try { 1008 setRootPaneCheckingEnabled(false); 1009 add(rootPane, BorderLayout.CENTER); 1010 } 1011 finally { 1012 setRootPaneCheckingEnabled(checkingEnabled); 1013 } 1014 } 1015 } 1016 1017 1018 /** 1019 * Returns the {@code contentPane} object for this dialog. 1020 * 1021 * @return the {@code contentPane} property 1022 * 1023 * @see #setContentPane 1024 * @see RootPaneContainer#getContentPane 1025 */ 1026 public Container getContentPane() { 1027 return getRootPane().getContentPane(); 1028 } 1029 1030 1031 /** 1032 * Sets the {@code contentPane} property. 1033 * This method is called by the constructor. 1034 * <p> 1035 * Swing's painting architecture requires an opaque {@code JComponent} 1036 * in the containment hierarchy. This is typically provided by the 1037 * content pane. If you replace the content pane it is recommended you 1038 * replace it with an opaque {@code JComponent}. 1039 * @see JRootPane 1040 * 1041 * @param contentPane the {@code contentPane} object for this dialog 1042 * 1043 * @throws java.awt.IllegalComponentStateException (a runtime 1044 * exception) if the content pane parameter is {@code null} 1045 * @see #getContentPane 1046 * @see RootPaneContainer#setContentPane 1047 * 1048 * @beaninfo 1049 * hidden: true 1050 * description: The client area of the dialog where child 1051 * components are normally inserted. 1052 */ 1053 public void setContentPane(Container contentPane) { 1054 getRootPane().setContentPane(contentPane); 1055 } 1056 1057 /** 1058 * Returns the {@code layeredPane} object for this dialog. 1059 * 1060 * @return the {@code layeredPane} property 1061 * 1062 * @see #setLayeredPane 1063 * @see RootPaneContainer#getLayeredPane 1064 */ 1065 public JLayeredPane getLayeredPane() { 1066 return getRootPane().getLayeredPane(); 1067 } 1068 1069 /** 1070 * Sets the {@code layeredPane} property. 1071 * This method is called by the constructor. 1072 * 1073 * @param layeredPane the new {@code layeredPane} property 1074 * 1075 * @throws java.awt.IllegalComponentStateException (a runtime 1076 * exception) if the layered pane parameter is null 1077 * @see #getLayeredPane 1078 * @see RootPaneContainer#setLayeredPane 1079 * 1080 * @beaninfo 1081 * hidden: true 1082 * description: The pane which holds the various dialog layers. 1083 */ 1084 public void setLayeredPane(JLayeredPane layeredPane) { 1085 getRootPane().setLayeredPane(layeredPane); 1086 } 1087 1088 /** 1089 * Returns the {@code glassPane} object for this dialog. 1090 * 1091 * @return the {@code glassPane} property 1092 * 1093 * @see #setGlassPane 1094 * @see RootPaneContainer#getGlassPane 1095 */ 1096 public Component getGlassPane() { 1097 return getRootPane().getGlassPane(); 1098 } 1099 1100 /** 1101 * Sets the {@code glassPane} property. 1102 * This method is called by the constructor. 1103 * 1104 * @param glassPane the {@code glassPane} object for this dialog 1105 * @see #getGlassPane 1106 * @see RootPaneContainer#setGlassPane 1107 * 1108 * @beaninfo 1109 * hidden: true 1110 * description: A transparent pane used for menu rendering. 1111 */ 1112 public void setGlassPane(Component glassPane) { 1113 getRootPane().setGlassPane(glassPane); 1114 } 1115 1116 /** 1117 * {@inheritDoc} 1118 * 1119 * @since 1.6 1120 */ 1121 public Graphics getGraphics() { 1122 JComponent.getGraphicsInvoked(this); 1123 return super.getGraphics(); 1124 } 1125 1126 /** 1127 * Repaints the specified rectangle of this component within 1128 * {@code time} milliseconds. Refer to {@code RepaintManager} 1129 * for details on how the repaint is handled. 1130 * 1131 * @param time maximum time in milliseconds before update 1132 * @param x the <i>x</i> coordinate 1133 * @param y the <i>y</i> coordinate 1134 * @param width the width 1135 * @param height the height 1136 * @see RepaintManager 1137 * @since 1.6 1138 */ 1139 public void repaint(long time, int x, int y, int width, int height) { 1140 if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) { 1141 RepaintManager.currentManager(this).addDirtyRegion( 1142 this, x, y, width, height); 1143 } 1144 else { 1145 super.repaint(time, x, y, width, height); 1146 } 1147 } 1148 1149 /** 1150 * Provides a hint as to whether or not newly created {@code JDialog}s 1151 * should have their Window decorations (such as borders, widgets to 1152 * close the window, title...) provided by the current look 1153 * and feel. If {@code defaultLookAndFeelDecorated} is true, 1154 * the current {@code LookAndFeel} supports providing window 1155 * decorations, and the current window manager supports undecorated 1156 * windows, then newly created {@code JDialog}s will have their 1157 * Window decorations provided by the current {@code LookAndFeel}. 1158 * Otherwise, newly created {@code JDialog}s will have their 1159 * Window decorations provided by the current window manager. 1160 * <p> 1161 * You can get the same effect on a single JDialog by doing the following: 1162 * <pre> 1163 * JDialog dialog = new JDialog(); 1164 * dialog.setUndecorated(true); 1165 * dialog.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG); 1166 * </pre> 1167 * 1168 * @param defaultLookAndFeelDecorated A hint as to whether or not current 1169 * look and feel should provide window decorations 1170 * @see javax.swing.LookAndFeel#getSupportsWindowDecorations 1171 * @since 1.4 1172 */ 1173 public static void setDefaultLookAndFeelDecorated(boolean defaultLookAndFeelDecorated) { 1174 if (defaultLookAndFeelDecorated) { 1175 SwingUtilities.appContextPut(defaultLookAndFeelDecoratedKey, Boolean.TRUE); 1176 } else { 1177 SwingUtilities.appContextPut(defaultLookAndFeelDecoratedKey, Boolean.FALSE); 1178 } 1179 } 1180 1181 /** 1182 * Returns true if newly created {@code JDialog}s should have their 1183 * Window decorations provided by the current look and feel. This is only 1184 * a hint, as certain look and feels may not support this feature. 1185 * 1186 * @return true if look and feel should provide Window decorations. 1187 * @since 1.4 1188 */ 1189 public static boolean isDefaultLookAndFeelDecorated() { 1190 Boolean defaultLookAndFeelDecorated = 1191 (Boolean) SwingUtilities.appContextGet(defaultLookAndFeelDecoratedKey); 1192 if (defaultLookAndFeelDecorated == null) { 1193 defaultLookAndFeelDecorated = Boolean.FALSE; 1194 } 1195 return defaultLookAndFeelDecorated.booleanValue(); 1196 } 1197 1198 /** 1199 * Returns a string representation of this {@code JDialog}. 1200 * This method 1201 * is intended to be used only for debugging purposes, and the 1202 * content and format of the returned string may vary between 1203 * implementations. The returned string may be empty but may not 1204 * be {@code null}. 1205 * 1206 * @return a string representation of this {@code JDialog}. 1207 */ 1208 protected String paramString() { 1209 String defaultCloseOperationString; 1210 if (defaultCloseOperation == HIDE_ON_CLOSE) { 1211 defaultCloseOperationString = "HIDE_ON_CLOSE"; 1212 } else if (defaultCloseOperation == DISPOSE_ON_CLOSE) { 1213 defaultCloseOperationString = "DISPOSE_ON_CLOSE"; 1214 } else if (defaultCloseOperation == DO_NOTHING_ON_CLOSE) { 1215 defaultCloseOperationString = "DO_NOTHING_ON_CLOSE"; 1216 } else defaultCloseOperationString = ""; 1217 String rootPaneString = (rootPane != null ? 1218 rootPane.toString() : ""); 1219 String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ? 1220 "true" : "false"); 1221 1222 return super.paramString() + 1223 ",defaultCloseOperation=" + defaultCloseOperationString + 1224 ",rootPane=" + rootPaneString + 1225 ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString; 1226 } 1227 1228 1229 ///////////////// 1230 // Accessibility support 1231 //////////////// 1232 1233 /** 1234 * {@code AccessibleContext} associated with this {@code JDialog} 1235 */ 1236 protected AccessibleContext accessibleContext = null; 1237 1238 /** 1239 * Gets the AccessibleContext associated with this JDialog. 1240 * For JDialogs, the AccessibleContext takes the form of an 1241 * AccessibleJDialog. 1242 * A new AccessibleJDialog instance is created if necessary. 1243 * 1244 * @return an AccessibleJDialog that serves as the 1245 * AccessibleContext of this JDialog 1246 */ 1247 public AccessibleContext getAccessibleContext() { 1248 if (accessibleContext == null) { 1249 accessibleContext = new AccessibleJDialog(); 1250 } 1251 return accessibleContext; 1252 } 1253 1254 /** 1255 * This class implements accessibility support for the 1256 * {@code JDialog} class. It provides an implementation of the 1257 * Java Accessibility API appropriate to dialog user-interface 1258 * elements. 1259 */ 1260 protected class AccessibleJDialog extends AccessibleAWTDialog { 1261 1262 // AccessibleContext methods 1263 // 1264 /** 1265 * Get the accessible name of this object. 1266 * 1267 * @return the localized name of the object -- can be null if this 1268 * object does not have a name 1269 */ 1270 public String getAccessibleName() { 1271 if (accessibleName != null) { 1272 return accessibleName; 1273 } else { 1274 if (getTitle() == null) { 1275 return super.getAccessibleName(); 1276 } else { 1277 return getTitle(); 1278 } 1279 } 1280 } 1281 1282 /** 1283 * Get the state of this object. 1284 * 1285 * @return an instance of AccessibleStateSet containing the current 1286 * state set of the object 1287 * @see AccessibleState 1288 */ 1289 public AccessibleStateSet getAccessibleStateSet() { 1290 AccessibleStateSet states = super.getAccessibleStateSet(); 1291 1292 if (isResizable()) { 1293 states.add(AccessibleState.RESIZABLE); 1294 } 1295 if (getFocusOwner() != null) { 1296 states.add(AccessibleState.ACTIVE); 1297 } 1298 if (isModal()) { 1299 states.add(AccessibleState.MODAL); 1300 } 1301 return states; 1302 } 1303 1304 } // inner class AccessibleJDialog 1305 }