Save This Page
Home » openjdk-7 » javax » swing » [javadoc | source]
    1   /*
    2    * Copyright 1997-2006 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.swing;
   27   
   28   import java.awt.BorderLayout;
   29   import java.awt.Component;
   30   import java.awt.Container;
   31   import java.awt.Dialog;
   32   import java.awt.Dimension;
   33   import java.awt.KeyboardFocusManager;
   34   import java.awt.Frame;
   35   import java.awt.Point;
   36   import java.awt.HeadlessException;
   37   import java.awt.Toolkit;
   38   import java.awt.Window;
   39   import java.beans.PropertyChangeEvent;
   40   import java.beans.PropertyChangeListener;
   41   import java.awt.event.WindowListener;
   42   import java.awt.event.WindowAdapter;
   43   import java.awt.event.WindowEvent;
   44   import java.awt.event.ComponentAdapter;
   45   import java.awt.event.ComponentEvent;
   46   import java.io.IOException;
   47   import java.io.ObjectInputStream;
   48   import java.io.ObjectOutputStream;
   49   import java.io.Serializable;
   50   import java.lang.reflect.Method;
   51   import java.lang.reflect.InvocationTargetException;
   52   import java.security.AccessController;
   53   import java.security.PrivilegedAction;
   54   import java.util.Vector;
   55   import javax.swing.plaf.OptionPaneUI;
   56   import javax.swing.event.InternalFrameEvent;
   57   import javax.swing.event.InternalFrameAdapter;
   58   import javax.accessibility;
   59   import static javax.swing.ClientPropertyKey.PopupFactory_FORCE_HEAVYWEIGHT_POPUP;
   60   
   61   /**
   62    * <code>JOptionPane</code> makes it easy to pop up a standard dialog box that
   63    * prompts users for a value or informs them of something.
   64    * For information about using <code>JOptionPane</code>, see
   65    * <a
   66    href="http://java.sun.com/docs/books/tutorial/uiswing/components/dialog.html">How to Make Dialogs</a>,
   67    * a section in <em>The Java Tutorial</em>.
   68    *
   69    * <p>
   70    *
   71    * While the <code>JOptionPane</code>
   72    * class may appear complex because of the large number of methods, almost
   73    * all uses of this class are one-line calls to one of the static
   74    * <code>showXxxDialog</code> methods shown below:
   75    * <blockquote>
   76    *
   77    *
   78    * <table border=1 summary="Common JOptionPane method names and their descriptions">
   79    * <tr>
   80    *    <th>Method Name</th>
   81    *    <th>Description</th>
   82    * </tr>
   83    * <tr>
   84    *    <td>showConfirmDialog</td>
   85    *    <td>Asks a confirming question, like yes/no/cancel.</td>
   86    * </tr>
   87    * <tr>
   88    *    <td>showInputDialog</td>
   89    *    <td>Prompt for some input.</td>
   90    * </tr>
   91    * <tr>
   92    *   <td>showMessageDialog</td>
   93    *   <td>Tell the user about something that has happened.</td>
   94    * </tr>
   95    * <tr>
   96    *   <td>showOptionDialog</td>
   97    *   <td>The Grand Unification of the above three.</td>
   98    * </tr>
   99    * </table>
  100    *
  101    * </blockquote>
  102    * Each of these methods also comes in a <code>showInternalXXX</code>
  103    * flavor, which uses an internal frame to hold the dialog box (see
  104    * {@link JInternalFrame}).
  105    * Multiple convenience methods have also been defined -- overloaded
  106    * versions of the basic methods that use different parameter lists.
  107    * <p>
  108    * All dialogs are modal. Each <code>showXxxDialog</code> method blocks
  109    * the caller until the user's interaction is complete.
  110    * <p>
  111    *
  112    * <table cellspacing=6 cellpadding=4 border=0 align=right summary="layout">
  113    * <tr>
  114    *  <td bgcolor=#FFe0d0 rowspan=2>icon</td>
  115    *  <td bgcolor=#FFe0d0>message</td>
  116    * </tr>
  117    * <tr>
  118    *  <td bgcolor=#FFe0d0>input value</td>
  119    * </tr>
  120    * <tr>
  121    *   <td bgcolor=#FFe0d0 colspan=2>option buttons</td>
  122    * </tr>
  123    * </table>
  124    *
  125    * The basic appearance of one of these dialog boxes is generally
  126    * similar to the picture at the right, although the various
  127    * look-and-feels are
  128    * ultimately responsible for the final result.  In particular, the
  129    * look-and-feels will adjust the layout to accommodate the option pane's
  130    * <code>ComponentOrientation</code> property.
  131    * <br clear=all>
  132    * <p>
  133    * <b>Parameters:</b><br>
  134    * The parameters to these methods follow consistent patterns:
  135    * <blockquote>
  136    * <dl compact>
  137    * <dt>parentComponent<dd>
  138    * Defines the <code>Component</code> that is to be the parent of this
  139    * dialog box.
  140    * It is used in two ways: the <code>Frame</code> that contains
  141    * it is used as the <code>Frame</code>
  142    * parent for the dialog box, and its screen coordinates are used in
  143    * the placement of the dialog box. In general, the dialog box is placed
  144    * just below the component. This parameter may be <code>null</code>,
  145    * in which case a default <code>Frame</code> is used as the parent,
  146    * and the dialog will be
  147    * centered on the screen (depending on the L&F).
  148    * <dt><a name=message>message</a><dd>
  149    * A descriptive message to be placed in the dialog box.
  150    * In the most common usage, message is just a <code>String</code> or
  151    * <code>String</code> constant.
  152    * However, the type of this parameter is actually <code>Object</code>. Its
  153    * interpretation depends on its type:
  154    * <dl compact>
  155    * <dt>Object[]<dd>An array of objects is interpreted as a series of
  156    *                 messages (one per object) arranged in a vertical stack.
  157    *                 The interpretation is recursive -- each object in the
  158    *                 array is interpreted according to its type.
  159    * <dt>Component<dd>The <code>Component</code> is displayed in the dialog.
  160    * <dt>Icon<dd>The <code>Icon</code> is wrapped in a <code>JLabel</code>
  161    *               and displayed in the dialog.
  162    * <dt>others<dd>The object is converted to a <code>String</code> by calling
  163    *               its <code>toString</code> method. The result is wrapped in a
  164    *               <code>JLabel</code> and displayed.
  165    * </dl>
  166    * <dt>messageType<dd>Defines the style of the message. The Look and Feel
  167    * manager may lay out the dialog differently depending on this value, and
  168    * will often provide a default icon. The possible values are:
  169    * <ul>
  170    * <li><code>ERROR_MESSAGE</code>
  171    * <li><code>INFORMATION_MESSAGE</code>
  172    * <li><code>WARNING_MESSAGE</code>
  173    * <li><code>QUESTION_MESSAGE</code>
  174    * <li><code>PLAIN_MESSAGE</code>
  175    * </ul>
  176    * <dt>optionType<dd>Defines the set of option buttons that appear at
  177    * the bottom of the dialog box:
  178    * <ul>
  179    * <li><code>DEFAULT_OPTION</code>
  180    * <li><code>YES_NO_OPTION</code>
  181    * <li><code>YES_NO_CANCEL_OPTION</code>
  182    * <li><code>OK_CANCEL_OPTION</code>
  183    * </ul>
  184    * You aren't limited to this set of option buttons.  You can provide any
  185    * buttons you want using the options parameter.
  186    * <dt>options<dd>A more detailed description of the set of option buttons
  187    * that will appear at the bottom of the dialog box.
  188    * The usual value for the options parameter is an array of
  189    * <code>String</code>s. But
  190    * the parameter type is an array of <code>Objects</code>.
  191    * A button is created for each object depending on its type:
  192    * <dl compact>
  193    * <dt>Component<dd>The component is added to the button row directly.
  194    * <dt>Icon<dd>A <code>JButton</code> is created with this as its label.
  195    * <dt>other<dd>The <code>Object</code> is converted to a string using its
  196    *              <code>toString</code> method and the result is used to
  197    *              label a <code>JButton</code>.
  198    * </dl>
  199    * <dt>icon<dd>A decorative icon to be placed in the dialog box. A default
  200    * value for this is determined by the <code>messageType</code> parameter.
  201    * <dt>title<dd>The title for the dialog box.
  202    * <dt>initialValue<dd>The default selection (input value).
  203    * </dl>
  204    * </blockquote>
  205    * <p>
  206    * When the selection is changed, <code>setValue</code> is invoked,
  207    * which generates a <code>PropertyChangeEvent</code>.
  208    * <p>
  209    * If a <code>JOptionPane</code> has configured to all input
  210    * <code>setWantsInput</code>
  211    * the bound property <code>JOptionPane.INPUT_VALUE_PROPERTY</code>
  212    *  can also be listened
  213    * to, to determine when the user has input or selected a value.
  214    * <p>
  215    * When one of the <code>showXxxDialog</code> methods returns an integer,
  216    * the possible values are:
  217    * <ul>
  218    * <li><code>YES_OPTION</code>
  219    * <li><code>NO_OPTION</code>
  220    * <li><code>CANCEL_OPTION</code>
  221    * <li><code>OK_OPTION</code>
  222    * <li><code>CLOSED_OPTION</code>
  223    * </ul>
  224    * <b>Examples:</b>
  225    * <dl>
  226    * <dt>Show an error dialog that displays the message, 'alert':
  227    * <dd><code>
  228    * JOptionPane.showMessageDialog(null, "alert", "alert", JOptionPane.ERROR_MESSAGE);
  229    * </code><p>
  230    * <dt>Show an internal information dialog with the message, 'information':
  231    * <dd><code>
  232    * JOptionPane.showInternalMessageDialog(frame, "information",<br>
  233    *             <ul><ul>"information", JOptionPane.INFORMATION_MESSAGE);</ul></ul>
  234    * </code><p>
  235    * <dt>Show an information panel with the options yes/no and message 'choose one':
  236    * <dd><code>JOptionPane.showConfirmDialog(null,
  237    *             <ul><ul>"choose one", "choose one", JOptionPane.YES_NO_OPTION);</ul></ul>
  238    * </code><p>
  239    * <dt>Show an internal information dialog with the options yes/no/cancel and
  240    * message 'please choose one' and title information:
  241    * <dd><code>JOptionPane.showInternalConfirmDialog(frame,
  242    *             <ul><ul>"please choose one", "information",</ul></ul>
  243    *             <ul><ul>JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);</ul></ul>
  244    * </code><p>
  245    * <dt>Show a warning dialog with the options OK, CANCEL, title 'Warning', and
  246    * message 'Click OK to continue':
  247    * <dd><code>
  248    * Object[] options = { "OK", "CANCEL" };<br>
  249    * JOptionPane.showOptionDialog(null, "Click OK to continue", "Warning",
  250    *             <ul><ul>JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,</ul></ul>
  251    *             <ul><ul>null, options, options[0]);</ul></ul>
  252    * </code><p>
  253    * <dt>Show a dialog asking the user to type in a String:
  254    * <dd><code>
  255    * String inputValue = JOptionPane.showInputDialog("Please input a value");
  256    * </code><p>
  257    * <dt>Show a dialog asking the user to select a String:
  258    * <dd><code>
  259    * Object[] possibleValues = { "First", "Second", "Third" };<br>
  260    * Object selectedValue = JOptionPane.showInputDialog(null,
  261    *             <ul><ul>"Choose one", "Input",</ul></ul>
  262    *             <ul><ul>JOptionPane.INFORMATION_MESSAGE, null,</ul></ul>
  263    *             <ul><ul>possibleValues, possibleValues[0]);</ul></ul>
  264    * </code><p>
  265    * </dl>
  266    * <b>Direct Use:</b><br>
  267    * To create and use an <code>JOptionPane</code> directly, the
  268    * standard pattern is roughly as follows:
  269    * <pre>
  270    *     JOptionPane pane = new JOptionPane(<i>arguments</i>);
  271    *     pane.set<i>.Xxxx(...); // Configure</i>
  272    *     JDialog dialog = pane.createDialog(<i>parentComponent, title</i>);
  273    *     dialog.show();
  274    *     Object selectedValue = pane.getValue();
  275    *     if(selectedValue == null)
  276    *       return CLOSED_OPTION;
  277    *     <i>//If there is <b>not</b> an array of option buttons:</i>
  278    *     if(options == null) {
  279    *       if(selectedValue instanceof Integer)
  280    *          return ((Integer)selectedValue).intValue();
  281    *       return CLOSED_OPTION;
  282    *     }
  283    *     <i>//If there is an array of option buttons:</i>
  284    *     for(int counter = 0, maxCounter = options.length;
  285    *        counter < maxCounter; counter++) {
  286    *        if(options[counter].equals(selectedValue))
  287    *        return counter;
  288    *     }
  289    *     return CLOSED_OPTION;
  290    * </pre>
  291    * <p>
  292    * <strong>Warning:</strong> Swing is not thread safe. For more
  293    * information see <a
  294    * href="package-summary.html#threading">Swing's Threading
  295    * Policy</a>.
  296    * <p>
  297    * <strong>Warning:</strong>
  298    * Serialized objects of this class will not be compatible with
  299    * future Swing releases. The current serialization support is
  300    * appropriate for short term storage or RMI between applications running
  301    * the same version of Swing.  As of 1.4, support for long term storage
  302    * of all JavaBeans<sup><font size="-2">TM</font></sup>
  303    * has been added to the <code>java.beans</code> package.
  304    * Please see {@link java.beans.XMLEncoder}.
  305    *
  306    * @see JInternalFrame
  307    *
  308    * @beaninfo
  309    *      attribute: isContainer true
  310    *    description: A component which implements standard dialog box controls.
  311    *
  312    * @author James Gosling
  313    * @author Scott Violet
  314    */
  315   public class JOptionPane extends JComponent implements Accessible
  316   {
  317       /**
  318        * @see #getUIClassID
  319        * @see #readObject
  320        */
  321       private static final String uiClassID = "OptionPaneUI";
  322   
  323       /**
  324        * Indicates that the user has not yet selected a value.
  325        */
  326       public static final Object      UNINITIALIZED_VALUE = "uninitializedValue";
  327   
  328       //
  329       // Option types
  330       //
  331   
  332       /**
  333        * Type meaning Look and Feel should not supply any options -- only
  334        * use the options from the <code>JOptionPane</code>.
  335        */
  336       public static final int         DEFAULT_OPTION = -1;
  337       /** Type used for <code>showConfirmDialog</code>. */
  338       public static final int         YES_NO_OPTION = 0;
  339       /** Type used for <code>showConfirmDialog</code>. */
  340       public static final int         YES_NO_CANCEL_OPTION = 1;
  341       /** Type used for <code>showConfirmDialog</code>. */
  342       public static final int         OK_CANCEL_OPTION = 2;
  343   
  344       //
  345       // Return values.
  346       //
  347       /** Return value from class method if YES is chosen. */
  348       public static final int         YES_OPTION = 0;
  349       /** Return value from class method if NO is chosen. */
  350       public static final int         NO_OPTION = 1;
  351       /** Return value from class method if CANCEL is chosen. */
  352       public static final int         CANCEL_OPTION = 2;
  353       /** Return value form class method if OK is chosen. */
  354       public static final int         OK_OPTION = 0;
  355       /** Return value from class method if user closes window without selecting
  356        * anything, more than likely this should be treated as either a
  357        * <code>CANCEL_OPTION</code> or <code>NO_OPTION</code>. */
  358       public static final int         CLOSED_OPTION = -1;
  359   
  360       //
  361       // Message types. Used by the UI to determine what icon to display,
  362       // and possibly what behavior to give based on the type.
  363       //
  364       /** Used for error messages. */
  365       public static final int  ERROR_MESSAGE = 0;
  366       /** Used for information messages. */
  367       public static final int  INFORMATION_MESSAGE = 1;
  368       /** Used for warning messages. */
  369       public static final int  WARNING_MESSAGE = 2;
  370       /** Used for questions. */
  371       public static final int  QUESTION_MESSAGE = 3;
  372       /** No icon is used. */
  373       public static final int   PLAIN_MESSAGE = -1;
  374   
  375       /** Bound property name for <code>icon</code>. */
  376       public static final String      ICON_PROPERTY = "icon";
  377       /** Bound property name for <code>message</code>. */
  378       public static final String      MESSAGE_PROPERTY = "message";
  379       /** Bound property name for <code>value</code>. */
  380       public static final String      VALUE_PROPERTY = "value";
  381       /** Bound property name for <code>option</code>. */
  382       public static final String      OPTIONS_PROPERTY = "options";
  383       /** Bound property name for <code>initialValue</code>. */
  384       public static final String      INITIAL_VALUE_PROPERTY = "initialValue";
  385       /** Bound property name for <code>type</code>. */
  386       public static final String      MESSAGE_TYPE_PROPERTY = "messageType";
  387       /** Bound property name for <code>optionType</code>. */
  388       public static final String      OPTION_TYPE_PROPERTY = "optionType";
  389       /** Bound property name for <code>selectionValues</code>. */
  390       public static final String      SELECTION_VALUES_PROPERTY = "selectionValues";
  391       /** Bound property name for <code>initialSelectionValue</code>. */
  392       public static final String      INITIAL_SELECTION_VALUE_PROPERTY = "initialSelectionValue";
  393       /** Bound property name for <code>inputValue</code>. */
  394       public static final String      INPUT_VALUE_PROPERTY = "inputValue";
  395       /** Bound property name for <code>wantsInput</code>. */
  396       public static final String      WANTS_INPUT_PROPERTY = "wantsInput";
  397   
  398       /** Icon used in pane. */
  399       transient protected Icon                  icon;
  400       /** Message to display. */
  401       transient protected Object                message;
  402       /** Options to display to the user. */
  403       transient protected Object[]              options;
  404       /** Value that should be initially selected in <code>options</code>. */
  405       transient protected Object                initialValue;
  406       /** Message type. */
  407       protected int                   messageType;
  408       /**
  409        * Option type, one of <code>DEFAULT_OPTION</code>,
  410        * <code>YES_NO_OPTION</code>,
  411        * <code>YES_NO_CANCEL_OPTION</code> or
  412        * <code>OK_CANCEL_OPTION</code>.
  413        */
  414       protected int                   optionType;
  415       /** Currently selected value, will be a valid option, or
  416        * <code>UNINITIALIZED_VALUE</code> or <code>null</code>. */
  417       transient protected Object                value;
  418       /** Array of values the user can choose from. Look and feel will
  419        * provide the UI component to choose this from. */
  420       protected transient Object[]              selectionValues;
  421       /** Value the user has input. */
  422       protected transient Object                inputValue;
  423       /** Initial value to select in <code>selectionValues</code>. */
  424       protected transient Object                initialSelectionValue;
  425       /** If true, a UI widget will be provided to the user to get input. */
  426       protected boolean                         wantsInput;
  427   
  428   
  429       /**
  430        * Shows a question-message dialog requesting input from the user. The
  431        * dialog uses the default frame, which usually means it is centered on
  432        * the screen.
  433        *
  434        * @param message the <code>Object</code> to display
  435        * @exception HeadlessException if
  436        *   <code>GraphicsEnvironment.isHeadless</code> returns
  437        *   <code>true</code>
  438        * @see java.awt.GraphicsEnvironment#isHeadless
  439        */
  440       public static String showInputDialog(Object message)
  441           throws HeadlessException {
  442           return showInputDialog(null, message);
  443       }
  444   
  445       /**
  446        * Shows a question-message dialog requesting input from the user, with
  447        * the input value initialized to <code>initialSelectionValue</code>. The
  448        * dialog uses the default frame, which usually means it is centered on
  449        * the screen.
  450        *
  451        * @param message the <code>Object</code> to display
  452        * @param initialSelectionValue the value used to initialize the input
  453        *                 field
  454        * @since 1.4
  455        */
  456       public static String showInputDialog(Object message, Object initialSelectionValue) {
  457           return showInputDialog(null, message, initialSelectionValue);
  458       }
  459   
  460       /**
  461        * Shows a question-message dialog requesting input from the user
  462        * parented to <code>parentComponent</code>.
  463        * The dialog is displayed on top of the <code>Component</code>'s
  464        * frame, and is usually positioned below the <code>Component</code>.
  465        *
  466        * @param parentComponent  the parent <code>Component</code> for the
  467        *          dialog
  468        * @param message  the <code>Object</code> to display
  469        * @exception HeadlessException if
  470        *    <code>GraphicsEnvironment.isHeadless</code> returns
  471        *    <code>true</code>
  472        * @see java.awt.GraphicsEnvironment#isHeadless
  473        */
  474       public static String showInputDialog(Component parentComponent,
  475           Object message) throws HeadlessException {
  476           return showInputDialog(parentComponent, message, UIManager.getString(
  477               "OptionPane.inputDialogTitle", parentComponent), QUESTION_MESSAGE);
  478       }
  479   
  480       /**
  481        * Shows a question-message dialog requesting input from the user and
  482        * parented to <code>parentComponent</code>. The input value will be
  483        * initialized to <code>initialSelectionValue</code>.
  484        * The dialog is displayed on top of the <code>Component</code>'s
  485        * frame, and is usually positioned below the <code>Component</code>.
  486        *
  487        * @param parentComponent  the parent <code>Component</code> for the
  488        *          dialog
  489        * @param message the <code>Object</code> to display
  490        * @param initialSelectionValue the value used to initialize the input
  491        *                 field
  492        * @since 1.4
  493        */
  494       public static String showInputDialog(Component parentComponent, Object message,
  495                                            Object initialSelectionValue) {
  496           return (String)showInputDialog(parentComponent, message,
  497                         UIManager.getString("OptionPane.inputDialogTitle",
  498                         parentComponent), QUESTION_MESSAGE, null, null,
  499                         initialSelectionValue);
  500       }
  501   
  502       /**
  503        * Shows a dialog requesting input from the user parented to
  504        * <code>parentComponent</code> with the dialog having the title
  505        * <code>title</code> and message type <code>messageType</code>.
  506        *
  507        * @param parentComponent  the parent <code>Component</code> for the
  508        *                  dialog
  509        * @param message  the <code>Object</code> to display
  510        * @param title    the <code>String</code> to display in the dialog
  511        *                  title bar
  512        * @param messageType the type of message that is to be displayed:
  513        *                  <code>ERROR_MESSAGE</code>,
  514        *                  <code>INFORMATION_MESSAGE</code>,
  515        *                  <code>WARNING_MESSAGE</code>,
  516        *                  <code>QUESTION_MESSAGE</code>,
  517        *                  or <code>PLAIN_MESSAGE</code>
  518        * @exception HeadlessException if
  519        *   <code>GraphicsEnvironment.isHeadless</code> returns
  520        *   <code>true</code>
  521        * @see java.awt.GraphicsEnvironment#isHeadless
  522        */
  523       public static String showInputDialog(Component parentComponent,
  524           Object message, String title, int messageType)
  525           throws HeadlessException {
  526           return (String)showInputDialog(parentComponent, message, title,
  527                                          messageType, null, null, null);
  528       }
  529   
  530       /**
  531        * Prompts the user for input in a blocking dialog where the
  532        * initial selection, possible selections, and all other options can
  533        * be specified. The user will able to choose from
  534        * <code>selectionValues</code>, where <code>null</code> implies the
  535        * user can input
  536        * whatever they wish, usually by means of a <code>JTextField</code>.
  537        * <code>initialSelectionValue</code> is the initial value to prompt
  538        * the user with. It is up to the UI to decide how best to represent
  539        * the <code>selectionValues</code>, but usually a
  540        * <code>JComboBox</code>, <code>JList</code>, or
  541        * <code>JTextField</code> will be used.
  542        *
  543        * @param parentComponent  the parent <code>Component</code> for the
  544        *                  dialog
  545        * @param message  the <code>Object</code> to display
  546        * @param title    the <code>String</code> to display in the
  547        *                  dialog title bar
  548        * @param messageType the type of message to be displayed:
  549        *                  <code>ERROR_MESSAGE</code>,
  550        *                  <code>INFORMATION_MESSAGE</code>,
  551        *                  <code>WARNING_MESSAGE</code>,
  552        *                  <code>QUESTION_MESSAGE</code>,
  553        *                  or <code>PLAIN_MESSAGE</code>
  554        * @param icon     the <code>Icon</code> image to display
  555        * @param selectionValues an array of <code>Object</code>s that
  556        *                  gives the possible selections
  557        * @param initialSelectionValue the value used to initialize the input
  558        *                 field
  559        * @return user's input, or <code>null</code> meaning the user
  560        *                  canceled the input
  561        * @exception HeadlessException if
  562        *   <code>GraphicsEnvironment.isHeadless</code> returns
  563        *   <code>true</code>
  564        * @see java.awt.GraphicsEnvironment#isHeadless
  565        */
  566       public static Object showInputDialog(Component parentComponent,
  567           Object message, String title, int messageType, Icon icon,
  568           Object[] selectionValues, Object initialSelectionValue)
  569           throws HeadlessException {
  570           JOptionPane    pane = new JOptionPane(message, messageType,
  571                                                 OK_CANCEL_OPTION, icon,
  572                                                 null, null);
  573   
  574           pane.setWantsInput(true);
  575           pane.setSelectionValues(selectionValues);
  576           pane.setInitialSelectionValue(initialSelectionValue);
  577           pane.setComponentOrientation(((parentComponent == null) ?
  578               getRootFrame() : parentComponent).getComponentOrientation());
  579   
  580           int style = styleFromMessageType(messageType);
  581           JDialog dialog = pane.createDialog(parentComponent, title, style);
  582   
  583           pane.selectInitialValue();
  584           dialog.show();
  585           dialog.dispose();
  586   
  587           Object value = pane.getInputValue();
  588   
  589           if (value == UNINITIALIZED_VALUE) {
  590               return null;
  591           }
  592           return value;
  593       }
  594   
  595       /**
  596        * Brings up an information-message dialog titled "Message".
  597        *
  598        * @param parentComponent determines the <code>Frame</code> in
  599        *          which the dialog is displayed; if <code>null</code>,
  600        *          or if the <code>parentComponent</code> has no
  601        *          <code>Frame</code>, a default <code>Frame</code> is used
  602        * @param message   the <code>Object</code> to display
  603        * @exception HeadlessException if
  604        *   <code>GraphicsEnvironment.isHeadless</code> returns
  605        *   <code>true</code>
  606        * @see java.awt.GraphicsEnvironment#isHeadless
  607        */
  608       public static void showMessageDialog(Component parentComponent,
  609           Object message) throws HeadlessException {
  610           showMessageDialog(parentComponent, message, UIManager.getString(
  611                       "OptionPane.messageDialogTitle", parentComponent),
  612                       INFORMATION_MESSAGE);
  613       }
  614   
  615       /**
  616        * Brings up a dialog that displays a message using a default
  617        * icon determined by the <code>messageType</code> parameter.
  618        *
  619        * @param parentComponent determines the <code>Frame</code>
  620        *          in which the dialog is displayed; if <code>null</code>,
  621        *          or if the <code>parentComponent</code> has no
  622        *          <code>Frame</code>, a default <code>Frame</code> is used
  623        * @param message   the <code>Object</code> to display
  624        * @param title     the title string for the dialog
  625        * @param messageType the type of message to be displayed:
  626        *                  <code>ERROR_MESSAGE</code>,
  627        *                  <code>INFORMATION_MESSAGE</code>,
  628        *                  <code>WARNING_MESSAGE</code>,
  629        *                  <code>QUESTION_MESSAGE</code>,
  630        *                  or <code>PLAIN_MESSAGE</code>
  631        * @exception HeadlessException if
  632        *   <code>GraphicsEnvironment.isHeadless</code> returns
  633        *   <code>true</code>
  634        * @see java.awt.GraphicsEnvironment#isHeadless
  635        */
  636       public static void showMessageDialog(Component parentComponent,
  637           Object message, String title, int messageType)
  638           throws HeadlessException {
  639           showMessageDialog(parentComponent, message, title, messageType, null);
  640       }
  641   
  642       /**
  643        * Brings up a dialog displaying a message, specifying all parameters.
  644        *
  645        * @param parentComponent determines the <code>Frame</code> in which the
  646        *                  dialog is displayed; if <code>null</code>,
  647        *                  or if the <code>parentComponent</code> has no
  648        *                  <code>Frame</code>, a
  649        *                  default <code>Frame</code> is used
  650        * @param message   the <code>Object</code> to display
  651        * @param title     the title string for the dialog
  652        * @param messageType the type of message to be displayed:
  653        *                  <code>ERROR_MESSAGE</code>,
  654        *                  <code>INFORMATION_MESSAGE</code>,
  655        *                  <code>WARNING_MESSAGE</code>,
  656        *                  <code>QUESTION_MESSAGE</code>,
  657        *                  or <code>PLAIN_MESSAGE</code>
  658        * @param icon      an icon to display in the dialog that helps the user
  659        *                  identify the kind of message that is being displayed
  660        * @exception HeadlessException if
  661        *   <code>GraphicsEnvironment.isHeadless</code> returns
  662        *   <code>true</code>
  663        * @see java.awt.GraphicsEnvironment#isHeadless
  664        */
  665       public static void showMessageDialog(Component parentComponent,
  666           Object message, String title, int messageType, Icon icon)
  667           throws HeadlessException {
  668           showOptionDialog(parentComponent, message, title, DEFAULT_OPTION,
  669                            messageType, icon, null, null);
  670       }
  671   
  672       /**
  673        * Brings up a dialog with the options <i>Yes</i>,
  674        * <i>No</i> and <i>Cancel</i>; with the
  675        * title, <b>Select an Option</b>.
  676        *
  677        * @param parentComponent determines the <code>Frame</code> in which the
  678        *                  dialog is displayed; if <code>null</code>,
  679        *                  or if the <code>parentComponent</code> has no
  680        *                  <code>Frame</code>, a
  681        *                  default <code>Frame</code> is used
  682        * @param message   the <code>Object</code> to display
  683        * @return an integer indicating the option selected by the user
  684        * @exception HeadlessException if
  685        *   <code>GraphicsEnvironment.isHeadless</code> returns
  686        *   <code>true</code>
  687        * @see java.awt.GraphicsEnvironment#isHeadless
  688        */
  689       public static int showConfirmDialog(Component parentComponent,
  690           Object message) throws HeadlessException {
  691           return showConfirmDialog(parentComponent, message,
  692                                    UIManager.getString("OptionPane.titleText"),
  693                                    YES_NO_CANCEL_OPTION);
  694       }
  695   
  696       /**
  697        * Brings up a dialog where the number of choices is determined
  698        * by the <code>optionType</code> parameter.
  699        *
  700        * @param parentComponent determines the <code>Frame</code> in which the
  701        *                  dialog is displayed; if <code>null</code>,
  702        *                  or if the <code>parentComponent</code> has no
  703        *                  <code>Frame</code>, a
  704        *                  default <code>Frame</code> is used
  705        * @param message   the <code>Object</code> to display
  706        * @param title     the title string for the dialog
  707        * @param optionType an int designating the options available on the dialog:
  708        *                  <code>YES_NO_OPTION</code>,
  709        *                  <code>YES_NO_CANCEL_OPTION</code>,
  710        *                  or <code>OK_CANCEL_OPTION</code>
  711        * @return an int indicating the option selected by the user
  712        * @exception HeadlessException if
  713        *   <code>GraphicsEnvironment.isHeadless</code> returns
  714        *   <code>true</code>
  715        * @see java.awt.GraphicsEnvironment#isHeadless
  716        */
  717       public static int showConfirmDialog(Component parentComponent,
  718           Object message, String title, int optionType)
  719           throws HeadlessException {
  720           return showConfirmDialog(parentComponent, message, title, optionType,
  721                                    QUESTION_MESSAGE);
  722       }
  723   
  724       /**
  725        * Brings up a dialog where the number of choices is determined
  726        * by the <code>optionType</code> parameter, where the
  727        * <code>messageType</code>
  728        * parameter determines the icon to display.
  729        * The <code>messageType</code> parameter is primarily used to supply
  730        * a default icon from the Look and Feel.
  731        *
  732        * @param parentComponent determines the <code>Frame</code> in
  733        *                  which the dialog is displayed; if <code>null</code>,
  734        *                  or if the <code>parentComponent</code> has no
  735        *                  <code>Frame</code>, a
  736        *                  default <code>Frame</code> is used.
  737        * @param message   the <code>Object</code> to display
  738        * @param title     the title string for the dialog
  739        * @param optionType an integer designating the options available
  740        *                   on the dialog: <code>YES_NO_OPTION</code>,
  741        *                  <code>YES_NO_CANCEL_OPTION</code>,
  742        *                  or <code>OK_CANCEL_OPTION</code>
  743        * @param messageType an integer designating the kind of message this is;
  744        *                  primarily used to determine the icon from the pluggable
  745        *                  Look and Feel: <code>ERROR_MESSAGE</code>,
  746        *                  <code>INFORMATION_MESSAGE</code>,
  747        *                  <code>WARNING_MESSAGE</code>,
  748        *                  <code>QUESTION_MESSAGE</code>,
  749        *                  or <code>PLAIN_MESSAGE</code>
  750        * @return an integer indicating the option selected by the user
  751        * @exception HeadlessException if
  752        *   <code>GraphicsEnvironment.isHeadless</code> returns
  753        *   <code>true</code>
  754        * @see java.awt.GraphicsEnvironment#isHeadless
  755        */
  756       public static int showConfirmDialog(Component parentComponent,
  757           Object message, String title, int optionType, int messageType)
  758           throws HeadlessException {
  759           return showConfirmDialog(parentComponent, message, title, optionType,
  760                                   messageType, null);
  761       }
  762   
  763       /**
  764        * Brings up a dialog with a specified icon, where the number of
  765        * choices is determined by the <code>optionType</code> parameter.
  766        * The <code>messageType</code> parameter is primarily used to supply
  767        * a default icon from the look and feel.
  768        *
  769        * @param parentComponent determines the <code>Frame</code> in which the
  770        *                  dialog is displayed; if <code>null</code>,
  771        *                  or if the <code>parentComponent</code> has no
  772        *                  <code>Frame</code>, a
  773        *                  default <code>Frame</code> is used
  774        * @param message   the Object to display
  775        * @param title     the title string for the dialog
  776        * @param optionType an int designating the options available on the dialog:
  777        *                  <code>YES_NO_OPTION</code>,
  778        *                  <code>YES_NO_CANCEL_OPTION</code>,
  779        *                  or <code>OK_CANCEL_OPTION</code>
  780        * @param messageType an int designating the kind of message this is,
  781        *                  primarily used to determine the icon from the pluggable
  782        *                  Look and Feel: <code>ERROR_MESSAGE</code>,
  783        *                  <code>INFORMATION_MESSAGE</code>,
  784        *                  <code>WARNING_MESSAGE</code>,
  785        *                  <code>QUESTION_MESSAGE</code>,
  786        *                  or <code>PLAIN_MESSAGE</code>
  787        * @param icon      the icon to display in the dialog
  788        * @return an int indicating the option selected by the user
  789        * @exception HeadlessException if
  790        *   <code>GraphicsEnvironment.isHeadless</code> returns
  791        *   <code>true</code>
  792        * @see java.awt.GraphicsEnvironment#isHeadless
  793        */
  794       public static int showConfirmDialog(Component parentComponent,
  795           Object message, String title, int optionType,
  796           int messageType, Icon icon) throws HeadlessException {
  797           return showOptionDialog(parentComponent, message, title, optionType,
  798                                   messageType, icon, null, null);
  799       }
  800   
  801       /**
  802        * Brings up a dialog with a specified icon, where the initial
  803        * choice is determined by the <code>initialValue</code> parameter and
  804        * the number of choices is determined by the <code>optionType</code>
  805        * parameter.
  806        * <p>
  807        * If <code>optionType</code> is <code>YES_NO_OPTION</code>,
  808        * or <code>YES_NO_CANCEL_OPTION</code>
  809        * and the <code>options</code> parameter is <code>null</code>,
  810        * then the options are
  811        * supplied by the look and feel.
  812        * <p>
  813        * The <code>messageType</code> parameter is primarily used to supply
  814        * a default icon from the look and feel.
  815        *
  816        * @param parentComponent determines the <code>Frame</code>
  817        *                  in which the dialog is displayed;  if
  818        *                  <code>null</code>, or if the
  819        *                  <code>parentComponent</code> has no
  820        *                  <code>Frame</code>, a
  821        *                  default <code>Frame</code> is used
  822        * @param message   the <code>Object</code> to display
  823        * @param title     the title string for the dialog
  824        * @param optionType an integer designating the options available on the
  825        *                  dialog: <code>DEFAULT_OPTION</code>,
  826        *                  <code>YES_NO_OPTION</code>,
  827        *                  <code>YES_NO_CANCEL_OPTION</code>,
  828        *                  or <code>OK_CANCEL_OPTION</code>
  829        * @param messageType an integer designating the kind of message this is,
  830        *                  primarily used to determine the icon from the
  831        *                  pluggable Look and Feel: <code>ERROR_MESSAGE</code>,
  832        *                  <code>INFORMATION_MESSAGE</code>,
  833        *                  <code>WARNING_MESSAGE</code>,
  834        *                  <code>QUESTION_MESSAGE</code>,
  835        *                  or <code>PLAIN_MESSAGE</code>
  836        * @param icon      the icon to display in the dialog
  837        * @param options   an array of objects indicating the possible choices
  838        *                  the user can make; if the objects are components, they
  839        *                  are rendered properly; non-<code>String</code>
  840        *                  objects are
  841        *                  rendered using their <code>toString</code> methods;
  842        *                  if this parameter is <code>null</code>,
  843        *                  the options are determined by the Look and Feel
  844        * @param initialValue the object that represents the default selection
  845        *                  for the dialog; only meaningful if <code>options</code>
  846        *                  is used; can be <code>null</code>
  847        * @return an integer indicating the option chosen by the user,
  848        *                  or <code>CLOSED_OPTION</code> if the user closed
  849        *                  the dialog
  850        * @exception HeadlessException if
  851        *   <code>GraphicsEnvironment.isHeadless</code> returns
  852        *   <code>true</code>
  853        * @see java.awt.GraphicsEnvironment#isHeadless
  854        */
  855       public static int showOptionDialog(Component parentComponent,
  856           Object message, String title, int optionType, int messageType,
  857           Icon icon, Object[] options, Object initialValue)
  858           throws HeadlessException {
  859           JOptionPane             pane = new JOptionPane(message, messageType,
  860                                                          optionType, icon,
  861                                                          options, initialValue);
  862   
  863           pane.setInitialValue(initialValue);
  864           pane.setComponentOrientation(((parentComponent == null) ?
  865               getRootFrame() : parentComponent).getComponentOrientation());
  866   
  867           int style = styleFromMessageType(messageType);
  868           JDialog dialog = pane.createDialog(parentComponent, title, style);
  869   
  870           pane.selectInitialValue();
  871           dialog.show();
  872           dialog.dispose();
  873   
  874           Object        selectedValue = pane.getValue();
  875   
  876           if(selectedValue == null)
  877               return CLOSED_OPTION;
  878           if(options == null) {
  879               if(selectedValue instanceof Integer)
  880                   return ((Integer)selectedValue).intValue();
  881               return CLOSED_OPTION;
  882           }
  883           for(int counter = 0, maxCounter = options.length;
  884               counter < maxCounter; counter++) {
  885               if(options[counter].equals(selectedValue))
  886                   return counter;
  887           }
  888           return CLOSED_OPTION;
  889       }
  890   
  891       /**
  892        * Creates and returns a new <code>JDialog</code> wrapping
  893        * <code>this</code> centered on the <code>parentComponent</code>
  894        * in the <code>parentComponent</code>'s frame.
  895        * <code>title</code> is the title of the returned dialog.
  896        * The returned <code>JDialog</code> will not be resizable by the
  897        * user, however programs can invoke <code>setResizable</code> on
  898        * the <code>JDialog</code> instance to change this property.
  899        * The returned <code>JDialog</code> will be set up such that
  900        * once it is closed, or the user clicks on one of the buttons,
  901        * the optionpane's value property will be set accordingly and
  902        * the dialog will be closed.  Each time the dialog is made visible,
  903        * it will reset the option pane's value property to
  904        * <code>JOptionPane.UNINITIALIZED_VALUE</code> to ensure the
  905        * user's subsequent action closes the dialog properly.
  906        *
  907        * @param parentComponent determines the frame in which the dialog
  908        *          is displayed; if the <code>parentComponent</code> has
  909        *          no <code>Frame</code>, a default <code>Frame</code> is used
  910        * @param title     the title string for the dialog
  911        * @return a new <code>JDialog</code> containing this instance
  912        * @exception HeadlessException if
  913        *   <code>GraphicsEnvironment.isHeadless</code> returns
  914        *   <code>true</code>
  915        * @see java.awt.GraphicsEnvironment#isHeadless
  916        */
  917       public JDialog createDialog(Component parentComponent, String title)
  918           throws HeadlessException {
  919           int style = styleFromMessageType(getMessageType());
  920           return createDialog(parentComponent, title, style);
  921       }
  922   
  923       /**
  924        * Creates and returns a new parentless <code>JDialog</code>
  925        * with the specified title.
  926        * The returned <code>JDialog</code> will not be resizable by the
  927        * user, however programs can invoke <code>setResizable</code> on
  928        * the <code>JDialog</code> instance to change this property.
  929        * The returned <code>JDialog</code> will be set up such that
  930        * once it is closed, or the user clicks on one of the buttons,
  931        * the optionpane's value property will be set accordingly and
  932        * the dialog will be closed.  Each time the dialog is made visible,
  933        * it will reset the option pane's value property to
  934        * <code>JOptionPane.UNINITIALIZED_VALUE</code> to ensure the
  935        * user's subsequent action closes the dialog properly.
  936        *
  937        * @param title     the title string for the dialog
  938        * @return a new <code>JDialog</code> containing this instance
  939        * @exception HeadlessException if
  940        *   <code>GraphicsEnvironment.isHeadless</code> returns
  941        *   <code>true</code>
  942        * @see java.awt.GraphicsEnvironment#isHeadless
  943        * @since 1.6
  944        */
  945       public JDialog createDialog(String title) throws HeadlessException {
  946           int style = styleFromMessageType(getMessageType());
  947           JDialog dialog = new JDialog((Dialog) null, title, true);
  948           initDialog(dialog, style, null);
  949           return dialog;
  950       }
  951   
  952       private JDialog createDialog(Component parentComponent, String title,
  953               int style)
  954               throws HeadlessException {
  955   
  956           final JDialog dialog;
  957   
  958           Window window = JOptionPane.getWindowForComponent(parentComponent);
  959           if (window instanceof Frame) {
  960               dialog = new JDialog((Frame)window, title, true);
  961           } else {
  962               dialog = new JDialog((Dialog)window, title, true);
  963           }
  964           if (window instanceof SwingUtilities.SharedOwnerFrame) {
  965               WindowListener ownerShutdownListener =
  966                   (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener();
  967               dialog.addWindowListener(ownerShutdownListener);
  968           }
  969           initDialog(dialog, style, parentComponent);
  970           return dialog;
  971       }
  972   
  973       private void initDialog(final JDialog dialog, int style, Component parentComponent) {
  974           dialog.setComponentOrientation(this.getComponentOrientation());
  975           Container contentPane = dialog.getContentPane();
  976   
  977           contentPane.setLayout(new BorderLayout());
  978           contentPane.add(this, BorderLayout.CENTER);
  979           dialog.setResizable(false);
  980           if (JDialog.isDefaultLookAndFeelDecorated()) {
  981               boolean supportsWindowDecorations =
  982                 UIManager.getLookAndFeel().getSupportsWindowDecorations();
  983               if (supportsWindowDecorations) {
  984                   dialog.setUndecorated(true);
  985                   getRootPane().setWindowDecorationStyle(style);
  986               }
  987           }
  988           dialog.pack();
  989           dialog.setLocationRelativeTo(parentComponent);
  990           WindowAdapter adapter = new WindowAdapter() {
  991               private boolean gotFocus = false;
  992               public void windowClosing(WindowEvent we) {
  993                   setValue(null);
  994               }
  995               public void windowGainedFocus(WindowEvent we) {
  996                   // Once window gets focus, set initial focus
  997                   if (!gotFocus) {
  998                       selectInitialValue();
  999                       gotFocus = true;
 1000                   }
 1001               }
 1002           };
 1003           dialog.addWindowListener(adapter);
 1004           dialog.addWindowFocusListener(adapter);
 1005           dialog.addComponentListener(new ComponentAdapter() {
 1006               public void componentShown(ComponentEvent ce) {
 1007                   // reset value to ensure closing works properly
 1008                   setValue(JOptionPane.UNINITIALIZED_VALUE);
 1009               }
 1010           });
 1011           addPropertyChangeListener(new PropertyChangeListener() {
 1012               public void propertyChange(PropertyChangeEvent event) {
 1013                   // Let the defaultCloseOperation handle the closing
 1014                   // if the user closed the window without selecting a button
 1015                   // (newValue = null in that case).  Otherwise, close the dialog.
 1016                   if (dialog.isVisible() && event.getSource() == JOptionPane.this &&
 1017                     (event.getPropertyName().equals(VALUE_PROPERTY) ||
 1018                      event.getPropertyName().equals(INPUT_VALUE_PROPERTY)) &&
 1019                     event.getNewValue() != null &&
 1020                     event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) {
 1021                       dialog.setVisible(false);
 1022                   }
 1023               }
 1024           });
 1025       }
 1026   
 1027   
 1028       /**
 1029        * Brings up an internal confirmation dialog panel. The dialog
 1030        * is a information-message dialog titled "Message".
 1031        *
 1032        * @param parentComponent determines the <code>Frame</code>
 1033        *          in which the dialog is displayed; if <code>null</code>,
 1034        *          or if the <code>parentComponent</code> has no
 1035        *          <code>Frame</code>, a default <code>Frame</code> is used
 1036        * @param message   the object to display
 1037        */
 1038       public static void showInternalMessageDialog(Component parentComponent,
 1039                                                    Object message) {
 1040           showInternalMessageDialog(parentComponent, message, UIManager.
 1041                                    getString("OptionPane.messageDialogTitle",
 1042                                    parentComponent), INFORMATION_MESSAGE);
 1043       }
 1044   
 1045       /**
 1046        * Brings up an internal dialog panel that displays a message
 1047        * using a default icon determined by the <code>messageType</code>
 1048        * parameter.
 1049        *
 1050        * @param parentComponent determines the <code>Frame</code>
 1051        *          in which the dialog is displayed; if <code>null</code>,
 1052        *          or if the <code>parentComponent</code> has no
 1053        *          <code>Frame</code>, a default <code>Frame</code> is used
 1054        * @param message   the <code>Object</code> to display
 1055        * @param title     the title string for the dialog
 1056        * @param messageType the type of message to be displayed:
 1057        *                  <code>ERROR_MESSAGE</code>,
 1058        *                  <code>INFORMATION_MESSAGE</code>,
 1059        *                  <code>WARNING_MESSAGE</code>,
 1060        *                  <code>QUESTION_MESSAGE</code>,
 1061        *                  or <code>PLAIN_MESSAGE</code>
 1062        */
 1063       public static void showInternalMessageDialog(Component parentComponent,
 1064                                                    Object message, String title,
 1065                                                    int messageType) {
 1066           showInternalMessageDialog(parentComponent, message, title, messageType,null);
 1067       }
 1068   
 1069       /**
 1070        * Brings up an internal dialog panel displaying a message,
 1071        * specifying all parameters.
 1072        *
 1073        * @param parentComponent determines the <code>Frame</code>
 1074        *          in which the dialog is displayed; if <code>null</code>,
 1075        *          or if the <code>parentComponent</code> has no
 1076        *          <code>Frame</code>, a default <code>Frame</code> is used
 1077        * @param message   the <code>Object</code> to display
 1078        * @param title     the title string for the dialog
 1079        * @param messageType the type of message to be displayed:
 1080        *                  <code>ERROR_MESSAGE</code>,
 1081        *                  <code>INFORMATION_MESSAGE</code>,
 1082        *                  <code>WARNING_MESSAGE</code>,
 1083        *                  <code>QUESTION_MESSAGE</code>,
 1084        *                  or <code>PLAIN_MESSAGE</code>
 1085        * @param icon      an icon to display in the dialog that helps the user
 1086        *                  identify the kind of message that is being displayed
 1087        */
 1088       public static void showInternalMessageDialog(Component parentComponent,
 1089                                            Object message,
 1090                                            String title, int messageType,
 1091                                            Icon icon){
 1092           showInternalOptionDialog(parentComponent, message, title, DEFAULT_OPTION,
 1093                                    messageType, icon, null, null);
 1094       }
 1095   
 1096       /**
 1097        * Brings up an internal dialog panel with the options <i>Yes</i>, <i>No</i>
 1098        * and <i>Cancel</i>; with the title, <b>Select an Option</b>.
 1099        *
 1100        * @param parentComponent determines the <code>Frame</code> in
 1101        *          which the dialog is displayed; if <code>null</code>,
 1102        *          or if the <code>parentComponent</code> has no
 1103        *          <code>Frame</code>, a default <code>Frame</code> is used
 1104        * @param message   the <code>Object</code> to display
 1105        * @return an integer indicating the option selected by the user
 1106        */
 1107       public static int showInternalConfirmDialog(Component parentComponent,
 1108                                                   Object message) {
 1109           return showInternalConfirmDialog(parentComponent, message,
 1110                                    UIManager.getString("OptionPane.titleText"),
 1111                                    YES_NO_CANCEL_OPTION);
 1112       }
 1113   
 1114       /**
 1115        * Brings up a internal dialog panel where the number of choices
 1116        * is determined by the <code>optionType</code> parameter.
 1117        *
 1118        * @param parentComponent determines the <code>Frame</code>
 1119        *          in which the dialog is displayed; if <code>null</code>,
 1120        *          or if the <code>parentComponent</code> has no
 1121        *          <code>Frame</code>, a default <code>Frame</code> is used
 1122        * @param message   the object to display in the dialog; a
 1123        *          <code>Component</code> object is rendered as a
 1124        *          <code>Component</code>; a <code>String</code>
 1125        *          object is rendered as a string; other objects
 1126        *          are converted to a <code>String</code> using the
 1127        *          <code>toString</code> method
 1128        * @param title     the title string for the dialog
 1129        * @param optionType an integer designating the options
 1130        *          available on the dialog: <code>YES_NO_OPTION</code>,
 1131        *          or <code>YES_NO_CANCEL_OPTION</code>
 1132        * @return an integer indicating the option selected by the user
 1133        */
 1134       public static int showInternalConfirmDialog(Component parentComponent,
 1135                                                   Object message, String title,
 1136                                                   int optionType) {
 1137           return showInternalConfirmDialog(parentComponent, message, title, optionType,
 1138                                            QUESTION_MESSAGE);
 1139       }
 1140   
 1141       /**
 1142        * Brings up an internal dialog panel where the number of choices
 1143        * is determined by the <code>optionType</code> parameter, where
 1144        * the <code>messageType</code> parameter determines the icon to display.
 1145        * The <code>messageType</code> parameter is primarily used to supply
 1146        * a default icon from the Look and Feel.
 1147        *
 1148        * @param parentComponent determines the <code>Frame</code> in
 1149        *          which the dialog is displayed; if <code>null</code>,
 1150        *          or if the <code>parentComponent</code> has no
 1151        *          <code>Frame</code>, a default <code>Frame</code> is used
 1152        * @param message   the object to display in the dialog; a
 1153        *          <code>Component</code> object is rendered as a
 1154        *          <code>Component</code>; a <code>String</code>
 1155        *          object is rendered as a string; other objects are
 1156        *          converted to a <code>String</code> using the
 1157        *          <code>toString</code> method
 1158        * @param title     the title string for the dialog
 1159        * @param optionType an integer designating the options
 1160        *          available on the dialog:
 1161        *          <code>YES_NO_OPTION</code>, or <code>YES_NO_CANCEL_OPTION</code>
 1162        * @param messageType an integer designating the kind of message this is,
 1163        *          primarily used to determine the icon from the
 1164        *          pluggable Look and Feel: <code>ERROR_MESSAGE</code>,
 1165        *          <code>INFORMATION_MESSAGE</code>,
 1166        *          <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
 1167        *          or <code>PLAIN_MESSAGE</code>
 1168        * @return an integer indicating the option selected by the user
 1169        */
 1170       public static int showInternalConfirmDialog(Component parentComponent,
 1171                                           Object message,
 1172                                           String title, int optionType,
 1173                                           int messageType) {
 1174           return showInternalConfirmDialog(parentComponent, message, title, optionType,
 1175                                            messageType, null);
 1176       }
 1177   
 1178       /**
 1179        * Brings up an internal dialog panel with a specified icon, where
 1180        * the number of choices is determined by the <code>optionType</code>
 1181        * parameter.
 1182        * The <code>messageType</code> parameter is primarily used to supply
 1183        * a default icon from the look and feel.
 1184        *
 1185        * @param parentComponent determines the <code>Frame</code>
 1186        *          in which the dialog is displayed; if <code>null</code>,
 1187        *          or if the parentComponent has no Frame, a
 1188        *          default <code>Frame</code> is used
 1189        * @param message   the object to display in the dialog; a
 1190        *          <code>Component</code> object is rendered as a
 1191        *          <code>Component</code>; a <code>String</code>
 1192        *          object is rendered as a string; other objects are
 1193        *          converted to a <code>String</code> using the
 1194        *          <code>toString</code> method
 1195        * @param title     the title string for the dialog
 1196        * @param optionType an integer designating the options available
 1197        *          on the dialog:
 1198        *          <code>YES_NO_OPTION</code>, or
 1199        *          <code>YES_NO_CANCEL_OPTION</code>.
 1200        * @param messageType an integer designating the kind of message this is,
 1201        *          primarily used to determine the icon from the pluggable
 1202        *          Look and Feel: <code>ERROR_MESSAGE</code>,
 1203        *          <code>INFORMATION_MESSAGE</code>,
 1204        *          <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
 1205        *          or <code>PLAIN_MESSAGE</code>
 1206        * @param icon      the icon to display in the dialog
 1207        * @return an integer indicating the option selected by the user
 1208        */
 1209       public static int showInternalConfirmDialog(Component parentComponent,
 1210                                           Object message,
 1211                                           String title, int optionType,
 1212                                           int messageType, Icon icon) {
 1213           return showInternalOptionDialog(parentComponent, message, title, optionType,
 1214                                           messageType, icon, null, null);
 1215       }
 1216   
 1217       /**
 1218        * Brings up an internal dialog panel with a specified icon, where
 1219        * the initial choice is determined by the <code>initialValue</code>
 1220        * parameter and the number of choices is determined by the
 1221        * <code>optionType</code> parameter.
 1222        * <p>
 1223        * If <code>optionType</code> is <code>YES_NO_OPTION</code>, or
 1224        * <code>YES_NO_CANCEL_OPTION</code>
 1225        * and the <code>options</code> parameter is <code>null</code>,
 1226        * then the options are supplied by the Look and Feel.
 1227        * <p>
 1228        * The <code>messageType</code> parameter is primarily used to supply
 1229        * a default icon from the look and feel.
 1230        *
 1231        * @param parentComponent determines the <code>Frame</code>
 1232        *          in which the dialog is displayed; if <code>null</code>,
 1233        *          or if the <code>parentComponent</code> has no
 1234        *          <code>Frame</code>, a default <code>Frame</code> is used
 1235        * @param message   the object to display in the dialog; a
 1236        *          <code>Component</code> object is rendered as a
 1237        *          <code>Component</code>; a <code>String</code>
 1238        *          object is rendered as a string. Other objects are
 1239        *          converted to a <code>String</code> using the
 1240        *          <code>toString</code> method
 1241        * @param title     the title string for the dialog
 1242        * @param optionType an integer designating the options available
 1243        *          on the dialog: <code>YES_NO_OPTION</code>,
 1244        *          or <code>YES_NO_CANCEL_OPTION</code>
 1245        * @param messageType an integer designating the kind of message this is;
 1246        *          primarily used to determine the icon from the
 1247        *          pluggable Look and Feel: <code>ERROR_MESSAGE</code>,
 1248        *          <code>INFORMATION_MESSAGE</code>,
 1249        *          <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
 1250        *          or <code>PLAIN_MESSAGE</code>
 1251        * @param icon      the icon to display in the dialog
 1252        * @param options   an array of objects indicating the possible choices
 1253        *          the user can make; if the objects are components, they
 1254        *          are rendered properly; non-<code>String</code>
 1255        *          objects are rendered using their <code>toString</code>
 1256        *          methods; if this parameter is <code>null</code>,
 1257        *          the options are determined by the Look and Feel
 1258        * @param initialValue the object that represents the default selection
 1259        *          for the dialog; only meaningful if <code>options</code>
 1260        *          is used; can be <code>null</code>
 1261        * @return an integer indicating the option chosen by the user,
 1262        *          or <code>CLOSED_OPTION</code> if the user closed the Dialog
 1263        */
 1264       public static int showInternalOptionDialog(Component parentComponent,
 1265                                          Object message,
 1266                                          String title, int optionType,
 1267                                          int messageType, Icon icon,
 1268                                          Object[] options, Object initialValue) {
 1269           JOptionPane pane = new JOptionPane(message, messageType,
 1270                   optionType, icon, options, initialValue);
 1271           pane.putClientProperty(PopupFactory_FORCE_HEAVYWEIGHT_POPUP,
 1272                   Boolean.TRUE);
 1273           Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager().
 1274                   getFocusOwner();
 1275   
 1276           pane.setInitialValue(initialValue);
 1277   
 1278           JInternalFrame dialog =
 1279               pane.createInternalFrame(parentComponent, title);
 1280           pane.selectInitialValue();
 1281           dialog.setVisible(true);
 1282   
 1283           /* Since all input will be blocked until this dialog is dismissed,
 1284            * make sure its parent containers are visible first (this component
 1285            * is tested below).  This is necessary for JApplets, because
 1286            * because an applet normally isn't made visible until after its
 1287            * start() method returns -- if this method is called from start(),
 1288            * the applet will appear to hang while an invisible modal frame
 1289            * waits for input.
 1290            */
 1291           if (dialog.isVisible() && !dialog.isShowing()) {
 1292               Container parent = dialog.getParent();
 1293               while (parent != null) {
 1294                   if (parent.isVisible() == false) {
 1295                       parent.setVisible(true);
 1296                   }
 1297                   parent = parent.getParent();
 1298               }
 1299           }
 1300   
 1301           // Use reflection to get Container.startLWModal.
 1302           try {
 1303               Object obj;
 1304               obj = AccessController.doPrivileged(new ModalPrivilegedAction(
 1305                       Container.class, "startLWModal"));
 1306               if (obj != null) {
 1307                   ((Method)obj).invoke(dialog, (Object[])null);
 1308               }
 1309           } catch (IllegalAccessException ex) {
 1310           } catch (IllegalArgumentException ex) {
 1311           } catch (InvocationTargetException ex) {
 1312           }
 1313   
 1314           if (parentComponent instanceof JInternalFrame) {
 1315               try {
 1316                   ((JInternalFrame)parentComponent).setSelected(true);
 1317               } catch (java.beans.PropertyVetoException e) {
 1318               }
 1319           }
 1320   
 1321           Object selectedValue = pane.getValue();
 1322   
 1323           if (fo != null && fo.isShowing()) {
 1324               fo.requestFocus();
 1325           }
 1326           if (selectedValue == null) {
 1327               return CLOSED_OPTION;
 1328           }
 1329           if (options == null) {
 1330               if (selectedValue instanceof Integer) {
 1331                   return ((Integer)selectedValue).intValue();
 1332               }
 1333               return CLOSED_OPTION;
 1334           }
 1335           for(int counter = 0, maxCounter = options.length;
 1336               counter < maxCounter; counter++) {
 1337               if (options[counter].equals(selectedValue)) {
 1338                   return counter;
 1339               }
 1340           }
 1341           return CLOSED_OPTION;
 1342       }
 1343   
 1344       /**
 1345        * Shows an internal question-message dialog requesting input from
 1346        * the user parented to <code>parentComponent</code>. The dialog
 1347        * is displayed in the <code>Component</code>'s frame,
 1348        * and is usually positioned below the <code>Component</code>.
 1349        *
 1350        * @param parentComponent  the parent <code>Component</code>
 1351        *          for the dialog
 1352        * @param message  the <code>Object</code> to display
 1353        */
 1354       public static String showInternalInputDialog(Component parentComponent,
 1355                                                    Object message) {
 1356           return showInternalInputDialog(parentComponent, message, UIManager.
 1357                  getString("OptionPane.inputDialogTitle", parentComponent),
 1358                  QUESTION_MESSAGE);
 1359       }
 1360   
 1361       /**
 1362        * Shows an internal dialog requesting input from the user parented
 1363        * to <code>parentComponent</code> with the dialog having the title
 1364        * <code>title</code> and message type <code>messageType</code>.
 1365        *
 1366        * @param parentComponent the parent <code>Component</code> for the dialog
 1367        * @param message  the <code>Object</code> to display
 1368        * @param title    the <code>String</code> to display in the
 1369        *          dialog title bar
 1370        * @param messageType the type of message that is to be displayed:
 1371        *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
 1372        *                    QUESTION_MESSAGE, or PLAIN_MESSAGE
 1373        */
 1374       public static String showInternalInputDialog(Component parentComponent,
 1375                                Object message, String title, int messageType) {
 1376           return (String)showInternalInputDialog(parentComponent, message, title,
 1377                                          messageType, null, null, null);
 1378       }
 1379   
 1380       /**
 1381        * Prompts the user for input in a blocking internal dialog where
 1382        * the initial selection, possible selections, and all other
 1383        * options can be specified. The user will able to choose from
 1384        * <code>selectionValues</code>, where <code>null</code>
 1385        * implies the user can input
 1386        * whatever they wish, usually by means of a <code>JTextField</code>.
 1387        * <code>initialSelectionValue</code> is the initial value to prompt
 1388        * the user with. It is up to the UI to decide how best to represent
 1389        * the <code>selectionValues</code>, but usually a
 1390        * <code>JComboBox</code>, <code>JList</code>, or
 1391        * <code>JTextField</code> will be used.
 1392        *
 1393        * @param parentComponent the parent <code>Component</code> for the dialog
 1394        * @param message  the <code>Object</code> to display
 1395        * @param title    the <code>String</code> to display in the dialog
 1396        *          title bar
 1397        * @param messageType the type of message to be displayed:
 1398        *                  <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
 1399        *                  <code>WARNING_MESSAGE</code>,
 1400        *                  <code>QUESTION_MESSAGE</code>, or <code>PLAIN_MESSAGE</code>
 1401        * @param icon     the <code>Icon</code> image to display
 1402        * @param selectionValues an array of <code>Objects</code> that
 1403        *                  gives the possible selections
 1404        * @param initialSelectionValue the value used to initialize the input
 1405        *                  field
 1406        * @return user's input, or <code>null</code> meaning the user
 1407        *          canceled the input
 1408        */
 1409       public static Object showInternalInputDialog(Component parentComponent,
 1410               Object message, String title, int messageType, Icon icon,
 1411               Object[] selectionValues, Object initialSelectionValue) {
 1412           JOptionPane pane = new JOptionPane(message, messageType,
 1413                   OK_CANCEL_OPTION, icon, null, null);
 1414           pane.putClientProperty(PopupFactory_FORCE_HEAVYWEIGHT_POPUP,
 1415                   Boolean.TRUE);
 1416           Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager().
 1417                   getFocusOwner();
 1418   
 1419           pane.setWantsInput(true);
 1420           pane.setSelectionValues(selectionValues);
 1421           pane.setInitialSelectionValue(initialSelectionValue);
 1422   
 1423           JInternalFrame dialog =
 1424               pane.createInternalFrame(parentComponent, title);
 1425   
 1426           pane.selectInitialValue();
 1427           dialog.setVisible(true);
 1428   
 1429           /* Since all input will be blocked until this dialog is dismissed,
 1430            * make sure its parent containers are visible first (this component
 1431            * is tested below).  This is necessary for JApplets, because
 1432            * because an applet normally isn't made visible until after its
 1433            * start() method returns -- if this method is called from start(),
 1434            * the applet will appear to hang while an invisible modal frame
 1435            * waits for input.
 1436            */
 1437           if (dialog.isVisible() && !dialog.isShowing()) {
 1438               Container parent = dialog.getParent();
 1439               while (parent != null) {
 1440                   if (parent.isVisible() == false) {
 1441                       parent.setVisible(true);
 1442                   }
 1443                   parent = parent.getParent();
 1444               }
 1445           }
 1446   
 1447           // Use reflection to get Container.startLWModal.
 1448           try {
 1449               Object obj;
 1450               obj = AccessController.doPrivileged(new ModalPrivilegedAction(
 1451                       Container.class, "startLWModal"));
 1452               if (obj != null) {
 1453                   ((Method)obj).invoke(dialog, (Object[])null);
 1454               }
 1455           } catch (IllegalAccessException ex) {
 1456           } catch (IllegalArgumentException ex) {
 1457           } catch (InvocationTargetException ex) {
 1458           }
 1459   
 1460           if (parentComponent instanceof JInternalFrame) {
 1461               try {
 1462                   ((JInternalFrame)parentComponent).setSelected(true);
 1463               } catch (java.beans.PropertyVetoException e) {
 1464               }
 1465           }
 1466   
 1467           if (fo != null && fo.isShowing()) {
 1468               fo.requestFocus();
 1469           }
 1470           Object value = pane.getInputValue();
 1471   
 1472           if (value == UNINITIALIZED_VALUE) {
 1473               return null;
 1474           }
 1475           return value;
 1476       }
 1477   
 1478       /**
 1479        * Creates and returns an instance of <code>JInternalFrame</code>.
 1480        * The internal frame is created with the specified title,
 1481        * and wrapping the <code>JOptionPane</code>.
 1482        * The returned <code>JInternalFrame</code> is
 1483        * added to the <code>JDesktopPane</code> ancestor of
 1484        * <code>parentComponent</code>, or components
 1485        * parent if one its ancestors isn't a <code>JDesktopPane</code>,
 1486        * or if <code>parentComponent</code>
 1487        * doesn't have a parent then a <code>RuntimeException</code> is thrown.
 1488        *
 1489        * @param parentComponent  the parent <code>Component</code> for
 1490        *          the internal frame
 1491        * @param title    the <code>String</code> to display in the
 1492        *          frame's title bar
 1493        * @return a <code>JInternalFrame</code> containing a
 1494        *          <code>JOptionPane</code>
 1495        * @exception RuntimeException if <code>parentComponent</code> does
 1496        *          not have a valid parent
 1497        */
 1498       public JInternalFrame createInternalFrame(Component parentComponent,
 1499                                    String title) {
 1500           Container parent =
 1501                   JOptionPane.getDesktopPaneForComponent(parentComponent);
 1502   
 1503           if (parent == null && (parentComponent == null ||
 1504                   (parent = parentComponent.getParent()) == null)) {
 1505               throw new RuntimeException("JOptionPane: parentComponent does " +
 1506                       "not have a valid parent");
 1507           }
 1508   
 1509           // Option dialogs should be closable only
 1510           final JInternalFrame  iFrame = new JInternalFrame(title, false, true,
 1511                                                              false, false);
 1512   
 1513           iFrame.putClientProperty("JInternalFrame.frameType", "optionDialog");
 1514           iFrame.putClientProperty("JInternalFrame.messageType",
 1515                                    Integer.valueOf(getMessageType()));
 1516   
 1517           iFrame.addInternalFrameListener(new InternalFrameAdapter() {
 1518               public void internalFrameClosing(InternalFrameEvent e) {
 1519                   if (getValue() == UNINITIALIZED_VALUE) {
 1520                       setValue(null);
 1521                   }
 1522               }
 1523           });
 1524           addPropertyChangeListener(new PropertyChangeListener() {
 1525               public void propertyChange(PropertyChangeEvent event) {
 1526                   // Let the defaultCloseOperation handle the closing
 1527                   // if the user closed the iframe without selecting a button
 1528                   // (newValue = null in that case).  Otherwise, close the dialog.
 1529                   if (iFrame.isVisible() &&
 1530                           event.getSource() == JOptionPane.this &&
 1531                           event.getPropertyName().equals(VALUE_PROPERTY)) {
 1532                   // Use reflection to get Container.stopLWModal().
 1533                   try {
 1534                       Object obj;
 1535                       obj = AccessController.doPrivileged(
 1536                           new ModalPrivilegedAction(
 1537                               Container.class, "stopLWModal"));
 1538                       if (obj != null) {
 1539                           ((Method)obj).invoke(iFrame, (Object[])null);
 1540                       }
 1541                   } catch (IllegalAccessException ex) {
 1542                   } catch (IllegalArgumentException ex) {
 1543                   } catch (InvocationTargetException ex) {
 1544                   }
 1545   
 1546                   try {
 1547                       iFrame.setClosed(true);
 1548                   }
 1549                   catch (java.beans.PropertyVetoException e) {
 1550                   }
 1551   
 1552                   iFrame.setVisible(false);
 1553                   }
 1554               }
 1555           });
 1556           iFrame.getContentPane().add(this, BorderLayout.CENTER);
 1557           if (parent instanceof JDesktopPane) {
 1558               parent.add(iFrame, JLayeredPane.MODAL_LAYER);
 1559           } else {
 1560               parent.add(iFrame, BorderLayout.CENTER);
 1561           }
 1562           Dimension iFrameSize = iFrame.getPreferredSize();
 1563           Dimension rootSize = parent.getSize();
 1564           Dimension parentSize = parentComponent.getSize();
 1565   
 1566           iFrame.setBounds((rootSize.width - iFrameSize.width) / 2,
 1567                            (rootSize.height - iFrameSize.height) / 2,
 1568                            iFrameSize.width, iFrameSize.height);
 1569           // We want dialog centered relative to its parent component
 1570           Point iFrameCoord =
 1571             SwingUtilities.convertPoint(parentComponent, 0, 0, parent);
 1572           int x = (parentSize.width - iFrameSize.width) / 2 + iFrameCoord.x;
 1573           int y = (parentSize.height - iFrameSize.height) / 2 + iFrameCoord.y;
 1574   
 1575           // If possible, dialog should be fully visible
 1576           int ovrx = x + iFrameSize.width - rootSize.width;
 1577           int ovry = y + iFrameSize.height - rootSize.height;
 1578           x = Math.max((ovrx > 0? x - ovrx: x), 0);
 1579           y = Math.max((ovry > 0? y - ovry: y), 0);
 1580           iFrame.setBounds(x, y, iFrameSize.width, iFrameSize.height);
 1581   
 1582           parent.validate();
 1583           try {
 1584               iFrame.setSelected(true);
 1585           } catch (java.beans.PropertyVetoException e) {}
 1586   
 1587           return iFrame;
 1588       }
 1589   
 1590       /**
 1591        * Returns the specified component's <code>Frame</code>.
 1592        *
 1593        * @param parentComponent the <code>Component</code> to check for a
 1594        *          <code>Frame</code>
 1595        * @return the <code>Frame</code> that contains the component,
 1596        *          or <code>getRootFrame</code>
 1597        *          if the component is <code>null</code>,
 1598        *          or does not have a valid <code>Frame</code> parent
 1599        * @exception HeadlessException if
 1600        *   <code>GraphicsEnvironment.isHeadless</code> returns
 1601        *   <code>true</code>
 1602        * @see #getRootFrame
 1603        * @see java.awt.GraphicsEnvironment#isHeadless
 1604        */
 1605       public static Frame getFrameForComponent(Component parentComponent)
 1606           throws HeadlessException {
 1607           if (parentComponent == null)
 1608               return getRootFrame();
 1609           if (parentComponent instanceof Frame)
 1610               return (Frame)parentComponent;
 1611           return JOptionPane.getFrameForComponent(parentComponent.getParent());
 1612       }
 1613   
 1614       /**
 1615        * Returns the specified component's toplevel <code>Frame</code> or
 1616        * <code>Dialog</code>.
 1617        *
 1618        * @param parentComponent the <code>Component</code> to check for a
 1619        *          <code>Frame</code> or <code>Dialog</code>
 1620        * @return the <code>Frame</code> or <code>Dialog</code> that
 1621        *          contains the component, or the default
 1622        *          frame if the component is <code>null</code>,
 1623        *          or does not have a valid
 1624        *          <code>Frame</code> or <code>Dialog</code> parent
 1625        * @exception HeadlessException if
 1626        *   <code>GraphicsEnvironment.isHeadless</code> returns
 1627        *   <code>true</code>
 1628        * @see java.awt.GraphicsEnvironment#isHeadless
 1629        */
 1630       static Window getWindowForComponent(Component parentComponent)
 1631           throws HeadlessException {
 1632           if (parentComponent == null)
 1633               return getRootFrame();
 1634           if (parentComponent instanceof Frame || parentComponent instanceof Dialog)
 1635               return (Window)parentComponent;
 1636           return JOptionPane.getWindowForComponent(parentComponent.getParent());
 1637       }
 1638   
 1639   
 1640       /**
 1641        * Returns the specified component's desktop pane.
 1642        *
 1643        * @param parentComponent the <code>Component</code> to check for a
 1644        *          desktop
 1645        * @return the <code>JDesktopPane</code> that contains the component,
 1646        *          or <code>null</code> if the component is <code>null</code>
 1647        *          or does not have an ancestor that is a
 1648        *          <code>JInternalFrame</code>
 1649        */
 1650       public static JDesktopPane getDesktopPaneForComponent(Component parentComponent) {
 1651           if(parentComponent == null)
 1652               return null;
 1653           if(parentComponent instanceof JDesktopPane)
 1654               return (JDesktopPane)parentComponent;
 1655           return getDesktopPaneForComponent(parentComponent.getParent());
 1656       }
 1657   
 1658       private static final Object sharedFrameKey = JOptionPane.class;
 1659   
 1660       /**
 1661        * Sets the frame to use for class methods in which a frame is
 1662        * not provided.
 1663        * <p>
 1664        * <strong>Note:</strong>
 1665        * It is recommended that rather than using this method you supply a valid parent.
 1666        *
 1667        * @param newRootFrame the default <code>Frame</code> to use
 1668        */
 1669       public static void setRootFrame(Frame newRootFrame) {
 1670           if (newRootFrame != null) {
 1671               SwingUtilities.appContextPut(sharedFrameKey, newRootFrame);
 1672           } else {
 1673               SwingUtilities.appContextRemove(sharedFrameKey);
 1674           }
 1675       }
 1676   
 1677       /**
 1678        * Returns the <code>Frame</code> to use for the class methods in
 1679        * which a frame is not provided.
 1680        *
 1681        * @return the default <code>Frame</code> to use
 1682        * @exception HeadlessException if
 1683        *   <code>GraphicsEnvironment.isHeadless</code> returns
 1684        *   <code>true</code>
 1685        * @see #setRootFrame
 1686        * @see java.awt.GraphicsEnvironment#isHeadless
 1687        */
 1688       public static Frame getRootFrame() throws HeadlessException {
 1689           Frame sharedFrame =
 1690               (Frame)SwingUtilities.appContextGet(sharedFrameKey);
 1691           if (sharedFrame == null) {
 1692               sharedFrame = SwingUtilities.getSharedOwnerFrame();
 1693               SwingUtilities.appContextPut(sharedFrameKey, sharedFrame);
 1694           }
 1695           return sharedFrame;
 1696       }
 1697   
 1698       /**
 1699        * Creates a <code>JOptionPane</code> with a test message.
 1700        */
 1701       public JOptionPane() {
 1702           this("JOptionPane message");
 1703       }
 1704   
 1705       /**
 1706        * Creates a instance of <code>JOptionPane</code> to display a
 1707        * message using the
 1708        * plain-message message type and the default options delivered by
 1709        * the UI.
 1710        *
 1711        * @param message the <code>Object</code> to display
 1712        */
 1713       public JOptionPane(Object message) {
 1714           this(message, PLAIN_MESSAGE);
 1715       }
 1716   
 1717       /**
 1718        * Creates an instance of <code>JOptionPane</code> to display a message
 1719        * with the specified message type and the default options,
 1720        *
 1721        * @param message the <code>Object</code> to display
 1722        * @param messageType the type of message to be displayed:
 1723        *                  <code>ERROR_MESSAGE</code>,
 1724        *                  <code>INFORMATION_MESSAGE</code>,
 1725        *                  <code>WARNING_MESSAGE</code>,
 1726        *                  <code>QUESTION_MESSAGE</code>,
 1727        *                  or <code>PLAIN_MESSAGE</code>
 1728        */
 1729       public JOptionPane(Object message, int messageType) {
 1730           this(message, messageType, DEFAULT_OPTION);
 1731       }
 1732   
 1733       /**
 1734        * Creates an instance of <code>JOptionPane</code> to display a message
 1735        * with the specified message type and options.
 1736        *
 1737        * @param message the <code>Object</code> to display
 1738        * @param messageType the type of message to be displayed:
 1739        *                  <code>ERROR_MESSAGE</code>,
 1740        *                  <code>INFORMATION_MESSAGE</code>,
 1741        *                  <code>WARNING_MESSAGE</code>,
 1742        *                  <code>QUESTION_MESSAGE</code>,
 1743        *                  or <code>PLAIN_MESSAGE</code>
 1744        * @param optionType the options to display in the pane:
 1745        *                  <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>,
 1746        *                  <code>YES_NO_CANCEL_OPTION</code>,
 1747        *                  <code>OK_CANCEL_OPTION</code>
 1748        */
 1749       public JOptionPane(Object message, int messageType, int optionType) {
 1750           this(message, messageType, optionType, null);
 1751       }
 1752   
 1753       /**
 1754        * Creates an instance of <code>JOptionPane</code> to display a message
 1755        * with the specified message type, options, and icon.
 1756        *
 1757        * @param message the <code>Object</code> to display
 1758        * @param messageType the type of message to be displayed:
 1759        *                  <code>ERROR_MESSAGE</code>,
 1760        *                  <code>INFORMATION_MESSAGE</code>,
 1761        *                  <code>WARNING_MESSAGE</code>,
 1762        *                  <code>QUESTION_MESSAGE</code>,
 1763        *                  or <code>PLAIN_MESSAGE</code>
 1764        * @param optionType the options to display in the pane:
 1765        *                  <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>,
 1766        *                  <code>YES_NO_CANCEL_OPTION</code>,
 1767        *                  <code>OK_CANCEL_OPTION</code>
 1768        * @param icon the <code>Icon</code> image to display
 1769        */
 1770       public JOptionPane(Object message, int messageType, int optionType,
 1771                          Icon icon) {
 1772           this(message, messageType, optionType, icon, null);
 1773       }
 1774   
 1775       /**
 1776        * Creates an instance of <code>JOptionPane</code> to display a message
 1777        * with the specified message type, icon, and options.
 1778        * None of the options is initially selected.
 1779        * <p>
 1780        * The options objects should contain either instances of
 1781        * <code>Component</code>s, (which are added directly) or
 1782        * <code>Strings</code> (which are wrapped in a <code>JButton</code>).
 1783        * If you provide <code>Component</code>s, you must ensure that when the
 1784        * <code>Component</code> is clicked it messages <code>setValue</code>
 1785        * in the created <code>JOptionPane</code>.
 1786        *
 1787        * @param message the <code>Object</code> to display
 1788        * @param messageType the type of message to be displayed:
 1789        *                  <code>ERROR_MESSAGE</code>,
 1790        *                  <code>INFORMATION_MESSAGE</code>,
 1791        *                  <code>WARNING_MESSAGE</code>,
 1792        *                  <code>QUESTION_MESSAGE</code>,
 1793        *                  or <code>PLAIN_MESSAGE</code>
 1794        * @param optionType the options to display in the pane:
 1795        *                  <code>DEFAULT_OPTION</code>,
 1796        *                  <code>YES_NO_OPTION</code>,
 1797        *                  <code>YES_NO_CANCEL_OPTION</code>,
 1798        *                  <code>OK_CANCEL_OPTION</code>
 1799        * @param icon the <code>Icon</code> image to display
 1800        * @param options  the choices the user can select
 1801        */
 1802       public JOptionPane(Object message, int messageType, int optionType,
 1803                          Icon icon, Object[] options) {
 1804           this(message, messageType, optionType, icon, options, null);
 1805       }
 1806   
 1807       /**
 1808        * Creates an instance of <code>JOptionPane</code> to display a message
 1809        * with the specified message type, icon, and options, with the
 1810        * initially-selected option specified.
 1811        *
 1812        * @param message the <code>Object</code> to display
 1813        * @param messageType the type of message to be displayed:
 1814        *                  <code>ERROR_MESSAGE</code>,
 1815        *                  <code>INFORMATION_MESSAGE</code>,
 1816        *                  <code>WARNING_MESSAGE</code>,
 1817        *                  <code>QUESTION_MESSAGE</code>,
 1818        *                  or <code>PLAIN_MESSAGE</code>
 1819        * @param optionType the options to display in the pane:
 1820        *                  <code>DEFAULT_OPTION</code>,
 1821        *                  <code>YES_NO_OPTION</code>,
 1822        *                  <code>YES_NO_CANCEL_OPTION</code>,
 1823        *                  <code>OK_CANCEL_OPTION</code>
 1824        * @param icon the Icon image to display
 1825        * @param options  the choices the user can select
 1826        * @param initialValue the choice that is initially selected; if
 1827        *                  <code>null</code>, then nothing will be initially selected;
 1828        *                  only meaningful if <code>options</code> is used
 1829        */
 1830       public JOptionPane(Object message, int messageType, int optionType,
 1831                          Icon icon, Object[] options, Object initialValue) {
 1832   
 1833           this.message = message;
 1834           this.options = options;
 1835           this.initialValue = initialValue;
 1836           this.icon = icon;
 1837           setMessageType(messageType);
 1838           setOptionType(optionType);
 1839           value = UNINITIALIZED_VALUE;
 1840           inputValue = UNINITIALIZED_VALUE;
 1841           updateUI();
 1842       }
 1843   
 1844       /**
 1845        * Sets the UI object which implements the L&F for this component.
 1846        *
 1847        * @param ui  the <code>OptionPaneUI</code> L&F object
 1848        * @see UIDefaults#getUI
 1849        * @beaninfo
 1850        *       bound: true
 1851        *      hidden: true
 1852        * description: The UI object that implements the optionpane's LookAndFeel
 1853        */
 1854       public void setUI(OptionPaneUI ui) {
 1855           if ((OptionPaneUI)this.ui != ui) {
 1856               super.setUI(ui);
 1857               invalidate();
 1858           }
 1859       }
 1860   
 1861       /**
 1862        * Returns the UI object which implements the L&F for this component.
 1863        *
 1864        * @return the <code>OptionPaneUI</code> object
 1865        */
 1866       public OptionPaneUI getUI() {
 1867           return (OptionPaneUI)ui;
 1868       }
 1869   
 1870       /**
 1871        * Notification from the <code>UIManager</code> that the L&F has changed.
 1872        * Replaces the current UI object with the latest version from the
 1873        * <code>UIManager</code>.
 1874        *
 1875        * @see JComponent#updateUI
 1876        */
 1877       public void updateUI() {
 1878           setUI((OptionPaneUI)UIManager.getUI(this));
 1879       }
 1880   
 1881   
 1882       /**
 1883        * Returns the name of the UI class that implements the
 1884        * L&F for this component.
 1885        *
 1886        * @return the string "OptionPaneUI"
 1887        * @see JComponent#getUIClassID
 1888        * @see UIDefaults#getUI
 1889        */
 1890       public String getUIClassID() {
 1891           return uiClassID;
 1892       }
 1893   
 1894   
 1895       /**
 1896        * Sets the option pane's message-object.
 1897        * @param newMessage the <code>Object</code> to display
 1898        * @see #getMessage
 1899        *
 1900        * @beaninfo
 1901        *   preferred: true
 1902        *   bound: true
 1903        * description: The optionpane's message object.
 1904        */
 1905       public void setMessage(Object newMessage) {
 1906           Object           oldMessage = message;
 1907   
 1908           message = newMessage;
 1909           firePropertyChange(MESSAGE_PROPERTY, oldMessage, message);
 1910       }
 1911   
 1912       /**
 1913        * Returns the message-object this pane displays.
 1914        * @see #setMessage
 1915        *
 1916        * @return the <code>Object</code> that is displayed
 1917        */
 1918       public Object getMessage() {
 1919           return message;
 1920       }
 1921   
 1922       /**
 1923        * Sets the icon to display. If non-<code>null</code>, the look and feel
 1924        * does not provide an icon.
 1925        * @param newIcon the <code>Icon</code> to display
 1926        *
 1927        * @see #getIcon
 1928        * @beaninfo
 1929        *   preferred: true
 1930        *       bound: true
 1931        * description: The option pane's type icon.
 1932        */
 1933       public void setIcon(Icon newIcon) {
 1934           Object              oldIcon = icon;
 1935   
 1936           icon = newIcon;
 1937           firePropertyChange(ICON_PROPERTY, oldIcon, icon);
 1938       }
 1939   
 1940       /**
 1941        * Returns the icon this pane displays.
 1942        * @return the <code>Icon</code> that is displayed
 1943        *
 1944        * @see #setIcon
 1945        */
 1946       public Icon getIcon() {
 1947           return icon;
 1948       }
 1949   
 1950       /**
 1951        * Sets the value the user has chosen.
 1952        * @param newValue  the chosen value
 1953        *
 1954        * @see #getValue
 1955        * @beaninfo
 1956        *   preferred: true
 1957        *       bound: true
 1958        * description: The option pane's value object.
 1959        */
 1960       public void setValue(Object newValue) {
 1961           Object               oldValue = value;
 1962   
 1963           value = newValue;
 1964           firePropertyChange(VALUE_PROPERTY, oldValue, value);
 1965       }
 1966   
 1967       /**
 1968        * Returns the value the user has selected. <code>UNINITIALIZED_VALUE</code>
 1969        * implies the user has not yet made a choice, <code>null</code> means the
 1970        * user closed the window with out choosing anything. Otherwise
 1971        * the returned value will be one of the options defined in this
 1972        * object.
 1973        *
 1974        * @return the <code>Object</code> chosen by the user,
 1975        *         <code>UNINITIALIZED_VALUE</code>
 1976        *         if the user has not yet made a choice, or <code>null</code> if
 1977        *         the user closed the window without making a choice
 1978        *
 1979        * @see #setValue
 1980        */
 1981       public Object getValue() {
 1982           return value;
 1983       }
 1984   
 1985       /**
 1986        * Sets the options this pane displays. If an element in
 1987        * <code>newOptions</code> is a <code>Component</code>
 1988        * it is added directly to the pane,
 1989        * otherwise a button is created for the element.
 1990        *
 1991        * @param newOptions an array of <code>Objects</code> that create the
 1992        *          buttons the user can click on, or arbitrary
 1993        *          <code>Components</code> to add to the pane
 1994        *
 1995        * @see #getOptions
 1996        * @beaninfo
 1997        *       bound: true
 1998        * description: The option pane's options objects.
 1999