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