001/* JDialog.java --
002   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package javax.swing;
040
041import java.awt.AWTEvent;
042import java.awt.Component;
043import java.awt.Container;
044import java.awt.Dialog;
045import java.awt.Dimension;
046import java.awt.Frame;
047import java.awt.Graphics;
048import java.awt.GraphicsConfiguration;
049import java.awt.IllegalComponentStateException;
050import java.awt.LayoutManager;
051import java.awt.event.WindowEvent;
052
053import javax.accessibility.Accessible;
054import javax.accessibility.AccessibleContext;
055
056/**
057 * A dialog window. This is an extension of {@link java.awt.Dialog} that
058 * provides support for the Swing architecture. Most importantly it contains a
059 * {@link JRootPane} as it's only top-level child, that manages the content
060 * pane, the menu and a glass pane.
061 *
062 * Also, unlike <code>java.awt.Dialog</code>s, JDialogs support the
063 * Swing Pluggable Look &amp; Feel architecture.
064 *
065 * @author Ronald Veldema (rveldema@cs.vu.nl)
066 */
067public class JDialog extends Dialog implements Accessible, WindowConstants,
068                                               RootPaneContainer
069{
070  /**
071   * Provides accessibility support for <code>JDialog</code>s.
072   */
073  protected class AccessibleJDialog extends Dialog.AccessibleAWTDialog
074  {
075    /**
076     * Creates a new instance of <code>AccessibleJDialog</code>.
077     */
078    protected AccessibleJDialog()
079    {
080      super();
081      // Nothing to do here.
082    }
083  }
084
085  private static final long serialVersionUID = -864070866424508218L;
086
087  /** DOCUMENT ME! */
088  protected AccessibleContext accessibleContext;
089
090  /** The single RootPane in the Dialog. */
091  protected JRootPane rootPane;
092
093  /**
094   * Whether checking is enabled on the RootPane.
095   *
096   * @specnote Should be false to comply with J2SE 5.0
097   */
098  protected boolean rootPaneCheckingEnabled = false;
099
100  /** The default action taken when closed. */
101  private int closeAction = HIDE_ON_CLOSE;
102
103  /** Whether JDialogs are decorated by the Look and Feel. */
104  private static boolean decorated;
105
106  /* Creates a new non-modal JDialog with no title
107   * using a shared Frame as the owner.
108   */
109  public JDialog()
110  {
111    this((Frame) SwingUtilities.getOwnerFrame(null), "", false, null);
112  }
113
114  /**
115   * Creates a new non-modal JDialog with no title
116   * using the given owner.
117   *
118   * @param owner The owner of the JDialog.
119   */
120  public JDialog(Dialog owner)
121  {
122    this(owner, "", false, null);
123  }
124
125  /**
126   * Creates a new JDialog with no title using the
127   * given modal setting and owner.
128   *
129   * @param owner The owner of the JDialog.
130   * @param modal Whether the JDialog is modal.
131   */
132  public JDialog(Dialog owner, boolean modal)
133  {
134    this(owner, "", modal, null);
135  }
136
137  /**
138   * Creates a new non-modal JDialog using the
139   * given title and owner.
140   *
141   * @param owner The owner of the JDialog.
142   * @param title The title of the JDialog.
143   */
144  public JDialog(Dialog owner, String title)
145  {
146    this(owner, title, false, null);
147  }
148
149  /**
150   * Creates a new JDialog using the given modal
151   * settings, title, and owner.
152   *
153   * @param owner The owner of the JDialog.
154   * @param title The title of the JDialog.
155   * @param modal Whether the JDialog is modal.
156   */
157  public JDialog(Dialog owner, String title, boolean modal)
158  {
159    this(owner, title, modal, null);
160  }
161
162  /**
163   * Creates a new JDialog using the given modal
164   * settings, title, owner and graphics configuration.
165   *
166   * @param owner The owner of the JDialog.
167   * @param title The title of the JDialog.
168   * @param modal Whether the JDialog is modal.
169   * @param gc The Graphics Configuration to use.
170   */
171  public JDialog(Dialog owner, String title, boolean modal,
172                 GraphicsConfiguration gc)
173  {
174    super(owner, title, modal, gc);
175    dialogInit();
176  }
177
178  /**
179   * Creates a new non-modal JDialog with no title
180   * using the given owner.
181   *
182   * @param owner The owner of the JDialog.
183   */
184  public JDialog(Frame owner)
185  {
186    this(owner, "", false, null);
187  }
188
189  /**
190   * Creates a new JDialog with no title using the
191   * given modal setting and owner.
192   *
193   * @param owner The owner of the JDialog.
194   * @param modal Whether the JDialog is modal.
195   */
196  public JDialog(Frame owner, boolean modal)
197  {
198    this(owner, "", modal, null);
199  }
200
201  /**
202   * Creates a new non-modal JDialog using the
203   * given title and owner.
204   *
205   * @param owner The owner of the JDialog.
206   * @param title The title of the JDialog.
207   */
208  public JDialog(Frame owner, String title)
209  {
210    this(owner, title, false, null);
211  }
212
213  /**
214   * Creates a new JDialog using the given modal
215   * settings, title, and owner.
216   *
217   * @param owner The owner of the JDialog.
218   * @param title The title of the JDialog.
219   * @param modal Whether the JDialog is modal.
220   */
221  public JDialog(Frame owner, String title, boolean modal)
222  {
223    this(owner, title, modal, null);
224  }
225
226  /**
227   * Creates a new JDialog using the given modal
228   * settings, title, owner and graphics configuration.
229   *
230   * @param owner The owner of the JDialog.
231   * @param title The title of the JDialog.
232   * @param modal Whether the JDialog is modal.
233   * @param gc The Graphics Configuration to use.
234   */
235  public JDialog(Frame owner, String title, boolean modal,
236                 GraphicsConfiguration gc)
237  {
238    super((Frame) SwingUtilities.getOwnerFrame(owner), title, modal, gc);
239    dialogInit();
240  }
241
242  /**
243   * This method is called to initialize the
244   * JDialog. It sets the layout used, the locale,
245   * and creates the RootPane.
246   */
247  protected void dialogInit()
248  {
249    // We need to explicitly enable events here so that our processKeyEvent()
250    // and processWindowEvent() gets called.
251    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
252
253    // FIXME: Do a check on GraphicsEnvironment.isHeadless()
254    setLocale(JComponent.getDefaultLocale());
255    getRootPane(); // Will do set/create.
256    invalidate();
257    // Now that initStageDone is true, adds and layouts apply to contentPane,
258    // not top-level.
259    setRootPaneCheckingEnabled(true);
260  }
261
262  /**
263   * This method returns whether JDialogs will have their
264   * window decorations provided by the Look and Feel.
265   *
266   * @return Whether the window decorations are Look and Feel provided.
267   */
268  public static boolean isDefaultLookAndFeelDecorated()
269  {
270    return decorated;
271  }
272
273  /**
274   * This method sets whether JDialogs will have their
275   * window decorations provided by the Look and Feel.
276   *
277   * @param defaultLookAndFeelDecorated Whether the window
278   * decorations are Look and Feel provided.
279   */
280  public static void setDefaultLookAndFeelDecorated(boolean defaultLookAndFeelDecorated)
281  {
282    decorated = defaultLookAndFeelDecorated;
283  }
284
285  /**
286   * This method returns the preferred size of
287   * the JDialog.
288   *
289   * @return The preferred size.
290   */
291  public Dimension getPreferredSize()
292  {
293    Dimension d = super.getPreferredSize();
294    return d;
295  }
296
297  /**
298   * This method returns the JMenuBar used
299   * in this JDialog.
300   *
301   * @return The JMenuBar in the JDialog.
302   */
303  public JMenuBar getJMenuBar()
304  {
305    return getRootPane().getJMenuBar();
306  }
307
308  /**
309   * This method sets the JMenuBar used
310   * in this JDialog.
311   *
312   * @param menubar The JMenuBar to use.
313   */
314  public void setJMenuBar(JMenuBar menubar)
315  {
316    getRootPane().setJMenuBar(menubar);
317  }
318
319  /**
320   * This method sets the LayoutManager used in the JDialog.
321   * This method will throw an Error if rootPaneChecking is
322   * enabled.
323   *
324   * @param manager The LayoutManager to use.
325   */
326  public void setLayout(LayoutManager manager)
327  {
328    // Check if we're in initialization stage. If so, call super.setLayout
329    // otherwise, valid calls go to the content pane.
330    if (isRootPaneCheckingEnabled())
331      getContentPane().setLayout(manager);
332    else
333      super.setLayout(manager);
334  }
335
336  /**
337   * This method sets the JLayeredPane used in the JDialog.
338   * If the given JLayeredPane is null, then this method
339   * will throw an Error.
340   *
341   * @param layeredPane The JLayeredPane to use.
342   */
343  public void setLayeredPane(JLayeredPane layeredPane)
344  {
345    if (layeredPane == null)
346      throw new IllegalComponentStateException("layeredPane cannot be null.");
347    getRootPane().setLayeredPane(layeredPane);
348  }
349
350  /**
351   * This method returns the JLayeredPane used with this JDialog.
352   *
353   * @return The JLayeredPane used with this JDialog.
354   */
355  public JLayeredPane getLayeredPane()
356  {
357    return getRootPane().getLayeredPane();
358  }
359
360  /**
361   * This method returns the JRootPane used with this JDialog.
362   *
363   * @return The JRootPane used with this JDialog.
364   */
365  public JRootPane getRootPane()
366  {
367    if (rootPane == null)
368      setRootPane(createRootPane());
369    return rootPane;
370  }
371
372  /**
373   * This method sets the JRootPane used with this JDialog.
374   *
375   * @param root The JRootPane to use.
376   */
377  protected void setRootPane(JRootPane root)
378  {
379    if (rootPane != null)
380      remove(rootPane);
381
382    rootPane = root;
383    rootPane.show();
384    add(rootPane);
385  }
386
387  /**
388   * This method creates a new JRootPane.
389   *
390   * @return A new JRootPane.
391   */
392  protected JRootPane createRootPane()
393  {
394    return new JRootPane();
395  }
396
397  /**
398   * This method returns the ContentPane
399   * in the JRootPane.
400   *
401   * @return The ContentPane in the JRootPane.
402   */
403  public Container getContentPane()
404  {
405    return getRootPane().getContentPane();
406  }
407
408  /**
409   * This method sets the ContentPane to use with this
410   * JDialog. If the ContentPane given is null, this method
411   * will throw an exception.
412   *
413   * @param contentPane The ContentPane to use with the JDialog.
414   */
415  public void setContentPane(Container contentPane)
416  {
417    if (contentPane == null)
418      throw new IllegalComponentStateException("contentPane cannot be null.");
419    getRootPane().setContentPane(contentPane);
420  }
421
422  /**
423   * This method returns the GlassPane for this JDialog.
424   *
425   * @return The GlassPane for this JDialog.
426   */
427  public Component getGlassPane()
428  {
429    return getRootPane().getGlassPane();
430  }
431
432  /**
433   * This method sets the GlassPane for this JDialog.
434   *
435   * @param glassPane The GlassPane for this JDialog.
436   */
437  public void setGlassPane(Component glassPane)
438  {
439    getRootPane().setGlassPane(glassPane);
440  }
441
442  /**
443   * This method is called when a component is added to the
444   * the JDialog. Calling this method with rootPaneCheckingEnabled
445   * will cause an Error to be thrown.
446   *
447   * @param comp The component to add.
448   * @param constraints The constraints.
449   * @param index The position of the component.
450   */
451  protected void addImpl(Component comp, Object constraints, int index)
452  {
453    // If we're adding in the initialization stage use super.add.
454    // Otherwise pass the add onto the content pane.
455    if (isRootPaneCheckingEnabled())
456      getContentPane().add(comp, constraints, index);
457    else
458      super.addImpl(comp, constraints, index);
459  }
460
461  /**
462   * This method removes a component from the JDialog.
463   *
464   * @param comp The component to remove.
465   */
466  public void remove(Component comp)
467  {
468    // If we're removing the root pane, use super.remove. Otherwise
469    // pass it on to the content pane instead.
470    if (comp == rootPane)
471      super.remove(rootPane);
472    else
473      getContentPane().remove(comp);
474  }
475
476  /**
477   * This method returns whether rootPane checking is enabled.
478   *
479   * @return Whether rootPane checking is enabled.
480   */
481  protected boolean isRootPaneCheckingEnabled()
482  {
483    return rootPaneCheckingEnabled;
484  }
485
486  /**
487   * This method sets whether rootPane checking is enabled.
488   *
489   * @param enabled Whether rootPane checking is enabled.
490   */
491  protected void setRootPaneCheckingEnabled(boolean enabled)
492  {
493    rootPaneCheckingEnabled = enabled;
494  }
495
496  /**
497   * This method simply calls paint and returns.
498   *
499   * @param g The Graphics object to paint with.
500   */
501  public void update(Graphics g)
502  {
503    paint(g);
504  }
505
506
507  /**
508   * This method handles window events. This allows the JDialog
509   * to honour its default close operation.
510   *
511   * @param e The WindowEvent.
512   */
513  protected void processWindowEvent(WindowEvent e)
514  {
515    super.processWindowEvent(e);
516    if (e.getID() == WindowEvent.WINDOW_CLOSING)
517      {
518        switch (closeAction)
519          {
520          case EXIT_ON_CLOSE:
521            System.exit(0);
522            break;
523          case DISPOSE_ON_CLOSE:
524            dispose();
525            break;
526          case HIDE_ON_CLOSE:
527            setVisible(false);
528            break;
529          case DO_NOTHING_ON_CLOSE:
530            break;
531          }
532      }
533  }
534
535  /**
536   * This method sets the action to take
537   * when the JDialog is closed.
538   *
539   * @param operation The action to take.
540   */
541  public void setDefaultCloseOperation(int operation)
542  {
543    /* Reference implementation allows invalid operations
544       to be specified.  If so, getDefaultCloseOperation
545       must return the invalid code, and the behaviour
546       defaults to DO_NOTHING_ON_CLOSE.  processWindowEvent
547       above handles this */
548    closeAction = operation;
549  }
550
551  /**
552   * This method returns the action taken when
553   * the JDialog is closed.
554   *
555   * @return The action to take.
556   */
557  public int getDefaultCloseOperation()
558  {
559    return closeAction;
560  }
561
562  /**
563   * This method returns a String describing the JDialog.
564   *
565   * @return A String describing the JDialog.
566   */
567  protected String paramString()
568  {
569    return "JDialog";
570  }
571
572  /**
573   * DOCUMENT ME!
574   *
575   * @return DOCUMENT ME!
576   */
577  public AccessibleContext getAccessibleContext()
578  {
579    if (accessibleContext == null)
580      accessibleContext = new AccessibleJDialog();
581    return accessibleContext;
582  }
583}