1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  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.Window;
  38 import java.beans.PropertyChangeEvent;
  39 import java.beans.PropertyChangeListener;
  40 import java.awt.event.WindowListener;
  41 import java.awt.event.WindowAdapter;
  42 import java.awt.event.WindowEvent;
  43 import java.awt.event.ComponentAdapter;
  44 import java.awt.event.ComponentEvent;
  45 import java.io.IOException;
  46 import java.io.ObjectInputStream;
  47 import java.io.ObjectOutputStream;
  48 import java.io.Serializable;
  49 import java.lang.reflect.Method;
  50 import java.lang.reflect.InvocationTargetException;
  51 import java.security.AccessController;
  52 import java.security.PrivilegedAction;
  53 import java.util.Vector;
  54 import javax.swing.plaf.OptionPaneUI;
  55 import javax.swing.event.InternalFrameEvent;
  56 import javax.swing.event.InternalFrameAdapter;
  57 import javax.accessibility.*;
  58 import static javax.swing.ClientPropertyKey.PopupFactory_FORCE_HEAVYWEIGHT_POPUP;
  59 import sun.awt.AWTAccessor;
  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://docs.oracle.com/javase/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  *
 111  * <table cellspacing=6 cellpadding=4 border=0 style="float:right" summary="layout">
 112  * <tr>
 113  *  <td style="background-color:#FFe0d0" rowspan=2>icon</td>
 114  *  <td style="background-color:#FFe0d0">message</td>
 115  * </tr>
 116  * <tr>
 117  *  <td style="background-color:#FFe0d0">input value</td>
 118  * </tr>
 119  * <tr>
 120  *   <td style="background-color:#FFe0d0" colspan=2>option buttons</td>
 121  * </tr>
 122  * </table>
 123  *
 124  * The basic appearance of one of these dialog boxes is generally
 125  * similar to the picture at the right, although the various
 126  * look-and-feels are
 127  * ultimately responsible for the final result.  In particular, the
 128  * look-and-feels will adjust the layout to accommodate the option pane's
 129  * <code>ComponentOrientation</code> property.
 130  * <br style="clear:all">
 131  * <p>
 132  * <b>Parameters:</b><br>
 133  * The parameters to these methods follow consistent patterns:
 134  * <blockquote>
 135  * <dl>
 136  * <dt>parentComponent<dd>
 137  * Defines the <code>Component</code> that is to be the parent of this
 138  * dialog box.
 139  * It is used in two ways: the <code>Frame</code> that contains
 140  * it is used as the <code>Frame</code>
 141  * parent for the dialog box, and its screen coordinates are used in
 142  * the placement of the dialog box. In general, the dialog box is placed
 143  * just below the component. This parameter may be <code>null</code>,
 144  * in which case a default <code>Frame</code> is used as the parent,
 145  * and the dialog will be
 146  * centered on the screen (depending on the {@literal L&F}).
 147  * <dt><a name=message>message</a><dd>
 148  * A descriptive message to be placed in the dialog box.
 149  * In the most common usage, message is just a <code>String</code> or
 150  * <code>String</code> constant.
 151  * However, the type of this parameter is actually <code>Object</code>. Its
 152  * interpretation depends on its type:
 153  * <dl>
 154  * <dt>Object[]<dd>An array of objects is interpreted as a series of
 155  *                 messages (one per object) arranged in a vertical stack.
 156  *                 The interpretation is recursive -- each object in the
 157  *                 array is interpreted according to its type.
 158  * <dt>Component<dd>The <code>Component</code> is displayed in the dialog.
 159  * <dt>Icon<dd>The <code>Icon</code> is wrapped in a <code>JLabel</code>
 160  *               and displayed in the dialog.
 161  * <dt>others<dd>The object is converted to a <code>String</code> by calling
 162  *               its <code>toString</code> method. The result is wrapped in a
 163  *               <code>JLabel</code> and displayed.
 164  * </dl>
 165  * <dt>messageType<dd>Defines the style of the message. The Look and Feel
 166  * manager may lay out the dialog differently depending on this value, and
 167  * will often provide a default icon. The possible values are:
 168  * <ul>
 169  * <li><code>ERROR_MESSAGE</code>
 170  * <li><code>INFORMATION_MESSAGE</code>
 171  * <li><code>WARNING_MESSAGE</code>
 172  * <li><code>QUESTION_MESSAGE</code>
 173  * <li><code>PLAIN_MESSAGE</code>
 174  * </ul>
 175  * <dt>optionType<dd>Defines the set of option buttons that appear at
 176  * the bottom of the dialog box:
 177  * <ul>
 178  * <li><code>DEFAULT_OPTION</code>
 179  * <li><code>YES_NO_OPTION</code>
 180  * <li><code>YES_NO_CANCEL_OPTION</code>
 181  * <li><code>OK_CANCEL_OPTION</code>
 182  * </ul>
 183  * You aren't limited to this set of option buttons.  You can provide any
 184  * buttons you want using the options parameter.
 185  * <dt>options<dd>A more detailed description of the set of option buttons
 186  * that will appear at the bottom of the dialog box.
 187  * The usual value for the options parameter is an array of
 188  * <code>String</code>s. But
 189  * the parameter type is an array of <code>Objects</code>.
 190  * A button is created for each object depending on its type:
 191  * <dl>
 192  * <dt>Component<dd>The component is added to the button row directly.
 193  * <dt>Icon<dd>A <code>JButton</code> is created with this as its label.
 194  * <dt>other<dd>The <code>Object</code> is converted to a string using its
 195  *              <code>toString</code> method and the result is used to
 196  *              label a <code>JButton</code>.
 197  * </dl>
 198  * <dt>icon<dd>A decorative icon to be placed in the dialog box. A default
 199  * value for this is determined by the <code>messageType</code> parameter.
 200  * <dt>title<dd>The title for the dialog box.
 201  * <dt>initialValue<dd>The default selection (input value).
 202  * </dl>
 203  * </blockquote>
 204  * <p>
 205  * When the selection is changed, <code>setValue</code> is invoked,
 206  * which generates a <code>PropertyChangeEvent</code>.
 207  * <p>
 208  * If a <code>JOptionPane</code> has configured to all input
 209  * <code>setWantsInput</code>
 210  * the bound property <code>JOptionPane.INPUT_VALUE_PROPERTY</code>
 211  *  can also be listened
 212  * to, to determine when the user has input or selected a value.
 213  * <p>
 214  * When one of the <code>showXxxDialog</code> methods returns an integer,
 215  * the possible values are:
 216  * <ul>
 217  * <li><code>YES_OPTION</code>
 218  * <li><code>NO_OPTION</code>
 219  * <li><code>CANCEL_OPTION</code>
 220  * <li><code>OK_OPTION</code>
 221  * <li><code>CLOSED_OPTION</code>
 222  * </ul>
 223  * <b>Examples:</b>
 224  * <dl>
 225  * <dt>Show an error dialog that displays the message, 'alert':
 226  * <dd><code>
 227  * JOptionPane.showMessageDialog(null, "alert", "alert", JOptionPane.ERROR_MESSAGE);
 228  * </code>
 229  * <dt>Show an internal information dialog with the message, 'information':
 230  * <dd><pre>
 231  * JOptionPane.showInternalMessageDialog(frame, "information",
 232  *             "information", JOptionPane.INFORMATION_MESSAGE);
 233  * </pre>
 234  * <dt>Show an information panel with the options yes/no and message 'choose one':
 235  * <dd><pre>JOptionPane.showConfirmDialog(null,
 236  *             "choose one", "choose one", JOptionPane.YES_NO_OPTION);
 237  * </pre>
 238  * <dt>Show an internal information dialog with the options yes/no/cancel and
 239  * message 'please choose one' and title information:
 240  * <dd><pre>JOptionPane.showInternalConfirmDialog(frame,
 241  *             "please choose one", "information",
 242  *             JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
 243  * </pre>
 244  * <dt>Show a warning dialog with the options OK, CANCEL, title 'Warning', and
 245  * message 'Click OK to continue':
 246  * <dd><pre>
 247  * Object[] options = { "OK", "CANCEL" };
 248  * JOptionPane.showOptionDialog(null, "Click OK to continue", "Warning",
 249  *             JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
 250  *             null, options, options[0]);
 251  * </pre>
 252  * <dt>Show a dialog asking the user to type in a String:
 253  * <dd><code>
 254  * String inputValue = JOptionPane.showInputDialog("Please input a value");
 255  * </code>
 256  * <dt>Show a dialog asking the user to select a String:
 257  * <dd><pre>
 258  * Object[] possibleValues = { "First", "Second", "Third" };<br>
 259  * Object selectedValue = JOptionPane.showInputDialog(null,
 260  *             "Choose one", "Input",
 261  *             JOptionPane.INFORMATION_MESSAGE, null,
 262  *             possibleValues, possibleValues[0]);
 263  * </pre>
 264  * </dl>
 265  * <b>Direct Use:</b><br>
 266  * To create and use an <code>JOptionPane</code> directly, the
 267  * standard pattern is roughly as follows:
 268  * <pre>
 269  *     JOptionPane pane = new JOptionPane(<i>arguments</i>);
 270  *     pane.set<i>.Xxxx(...); // Configure</i>
 271  *     JDialog dialog = pane.createDialog(<i>parentComponent, title</i>);
 272  *     dialog.show();
 273  *     Object selectedValue = pane.getValue();
 274  *     if(selectedValue == null)
 275  *       return CLOSED_OPTION;
 276  *     <i>//If there is <b>not</b> an array of option buttons:</i>
 277  *     if(options == null) {
 278  *       if(selectedValue instanceof Integer)
 279  *          return ((Integer)selectedValue).intValue();
 280  *       return CLOSED_OPTION;
 281  *     }
 282  *     <i>//If there is an array of option buttons:</i>
 283  *     for(int counter = 0, maxCounter = options.length;
 284  *        counter &lt; maxCounter; counter++) {
 285  *        if(options[counter].equals(selectedValue))
 286  *        return counter;
 287  *     }
 288  *     return CLOSED_OPTION;
 289  * </pre>
 290  * <p>
 291  * <strong>Warning:</strong> Swing is not thread safe. For more
 292  * information see <a
 293  * href="package-summary.html#threading">Swing's Threading
 294  * Policy</a>.
 295  * <p>
 296  * <strong>Warning:</strong>
 297  * Serialized objects of this class will not be compatible with
 298  * future Swing releases. The current serialization support is
 299  * appropriate for short term storage or RMI between applications running
 300  * the same version of Swing.  As of 1.4, support for long term storage
 301  * of all JavaBeans&trade;
 302  * has been added to the <code>java.beans</code> package.
 303  * Please see {@link java.beans.XMLEncoder}.
 304  *
 305  * @see JInternalFrame
 306  *
 307  * @beaninfo
 308  *      attribute: isContainer true
 309  *    description: A component which implements standard dialog box controls.
 310  *
 311  * @author James Gosling
 312  * @author Scott Violet
 313  * @since 1.2
 314  */
 315 @SuppressWarnings("serial") // Same-version serialization only
 316 public class JOptionPane extends JComponent implements Accessible
 317 {
 318     /**
 319      * @see #getUIClassID
 320      * @see #readObject
 321      */
 322     private static final String uiClassID = "OptionPaneUI";
 323 
 324     /**
 325      * Indicates that the user has not yet selected a value.
 326      */
 327     public static final Object      UNINITIALIZED_VALUE = "uninitializedValue";
 328 
 329     //
 330     // Option types
 331     //
 332 
 333     /**
 334      * Type meaning Look and Feel should not supply any options -- only
 335      * use the options from the <code>JOptionPane</code>.
 336      */
 337     public static final int         DEFAULT_OPTION = -1;
 338     /** Type used for <code>showConfirmDialog</code>. */
 339     public static final int         YES_NO_OPTION = 0;
 340     /** Type used for <code>showConfirmDialog</code>. */
 341     public static final int         YES_NO_CANCEL_OPTION = 1;
 342     /** Type used for <code>showConfirmDialog</code>. */
 343     public static final int         OK_CANCEL_OPTION = 2;
 344 
 345     //
 346     // Return values.
 347     //
 348     /** Return value from class method if YES is chosen. */
 349     public static final int         YES_OPTION = 0;
 350     /** Return value from class method if NO is chosen. */
 351     public static final int         NO_OPTION = 1;
 352     /** Return value from class method if CANCEL is chosen. */
 353     public static final int         CANCEL_OPTION = 2;
 354     /** Return value form class method if OK is chosen. */
 355     public static final int         OK_OPTION = 0;
 356     /** Return value from class method if user closes window without selecting
 357      * anything, more than likely this should be treated as either a
 358      * <code>CANCEL_OPTION</code> or <code>NO_OPTION</code>. */
 359     public static final int         CLOSED_OPTION = -1;
 360 
 361     //
 362     // Message types. Used by the UI to determine what icon to display,
 363     // and possibly what behavior to give based on the type.
 364     //
 365     /** Used for error messages. */
 366     public static final int  ERROR_MESSAGE = 0;
 367     /** Used for information messages. */
 368     public static final int  INFORMATION_MESSAGE = 1;
 369     /** Used for warning messages. */
 370     public static final int  WARNING_MESSAGE = 2;
 371     /** Used for questions. */
 372     public static final int  QUESTION_MESSAGE = 3;
 373     /** No icon is used. */
 374     public static final int   PLAIN_MESSAGE = -1;
 375 
 376     /** Bound property name for <code>icon</code>. */
 377     public static final String      ICON_PROPERTY = "icon";
 378     /** Bound property name for <code>message</code>. */
 379     public static final String      MESSAGE_PROPERTY = "message";
 380     /** Bound property name for <code>value</code>. */
 381     public static final String      VALUE_PROPERTY = "value";
 382     /** Bound property name for <code>option</code>. */
 383     public static final String      OPTIONS_PROPERTY = "options";
 384     /** Bound property name for <code>initialValue</code>. */
 385     public static final String      INITIAL_VALUE_PROPERTY = "initialValue";
 386     /** Bound property name for <code>type</code>. */
 387     public static final String      MESSAGE_TYPE_PROPERTY = "messageType";
 388     /** Bound property name for <code>optionType</code>. */
 389     public static final String      OPTION_TYPE_PROPERTY = "optionType";
 390     /** Bound property name for <code>selectionValues</code>. */
 391     public static final String      SELECTION_VALUES_PROPERTY = "selectionValues";
 392     /** Bound property name for <code>initialSelectionValue</code>. */
 393     public static final String      INITIAL_SELECTION_VALUE_PROPERTY = "initialSelectionValue";
 394     /** Bound property name for <code>inputValue</code>. */
 395     public static final String      INPUT_VALUE_PROPERTY = "inputValue";
 396     /** Bound property name for <code>wantsInput</code>. */
 397     public static final String      WANTS_INPUT_PROPERTY = "wantsInput";
 398 
 399     /** Icon used in pane. */
 400     transient protected Icon                  icon;
 401     /** Message to display. */
 402     transient protected Object                message;
 403     /** Options to display to the user. */
 404     transient protected Object[]              options;
 405     /** Value that should be initially selected in <code>options</code>. */
 406     transient protected Object                initialValue;
 407     /** Message type. */
 408     protected int                   messageType;
 409     /**
 410      * Option type, one of <code>DEFAULT_OPTION</code>,
 411      * <code>YES_NO_OPTION</code>,
 412      * <code>YES_NO_CANCEL_OPTION</code> or
 413      * <code>OK_CANCEL_OPTION</code>.
 414      */
 415     protected int                   optionType;
 416     /** Currently selected value, will be a valid option, or
 417      * <code>UNINITIALIZED_VALUE</code> or <code>null</code>. */
 418     transient protected Object                value;
 419     /** Array of values the user can choose from. Look and feel will
 420      * provide the UI component to choose this from. */
 421     protected transient Object[]              selectionValues;
 422     /** Value the user has input. */
 423     protected transient Object                inputValue;
 424     /** Initial value to select in <code>selectionValues</code>. */
 425     protected transient Object                initialSelectionValue;
 426     /** If true, a UI widget will be provided to the user to get input. */
 427     protected boolean                         wantsInput;
 428 
 429 
 430     /**
 431      * Shows a question-message dialog requesting input from the user. The
 432      * dialog uses the default frame, which usually means it is centered on
 433      * the screen.
 434      *
 435      * @param message the <code>Object</code> to display
 436      * @exception HeadlessException if
 437      *   <code>GraphicsEnvironment.isHeadless</code> returns
 438      *   <code>true</code>
 439      * @return user's input
 440      * @see java.awt.GraphicsEnvironment#isHeadless
 441      */
 442     public static String showInputDialog(Object message)
 443         throws HeadlessException {
 444         return showInputDialog(null, message);
 445     }
 446 
 447     /**
 448      * Shows a question-message dialog requesting input from the user, with
 449      * the input value initialized to <code>initialSelectionValue</code>. The
 450      * dialog uses the default frame, which usually means it is centered on
 451      * the screen.
 452      *
 453      * @param message the <code>Object</code> to display
 454      * @param initialSelectionValue the value used to initialize the input
 455      *                 field
 456      * @return user's input
 457      * @since 1.4
 458      */
 459     public static String showInputDialog(Object message, Object initialSelectionValue) {
 460         return showInputDialog(null, message, initialSelectionValue);
 461     }
 462 
 463     /**
 464      * Shows a question-message dialog requesting input from the user
 465      * parented to <code>parentComponent</code>.
 466      * The dialog is displayed on top of the <code>Component</code>'s
 467      * frame, and is usually positioned below the <code>Component</code>.
 468      *
 469      * @param parentComponent  the parent <code>Component</code> for the
 470      *          dialog
 471      * @param message  the <code>Object</code> to display
 472      * @exception HeadlessException if
 473      *    <code>GraphicsEnvironment.isHeadless</code> returns
 474      *    <code>true</code>
 475      * @return user's input
 476      * @see java.awt.GraphicsEnvironment#isHeadless
 477      */
 478     public static String showInputDialog(Component parentComponent,
 479         Object message) throws HeadlessException {
 480         return showInputDialog(parentComponent, message, UIManager.getString(
 481             "OptionPane.inputDialogTitle", parentComponent), QUESTION_MESSAGE);
 482     }
 483 
 484     /**
 485      * Shows a question-message dialog requesting input from the user and
 486      * parented to <code>parentComponent</code>. The input value will be
 487      * initialized to <code>initialSelectionValue</code>.
 488      * The dialog is displayed on top of the <code>Component</code>'s
 489      * frame, and is usually positioned below the <code>Component</code>.
 490      *
 491      * @param parentComponent  the parent <code>Component</code> for the
 492      *          dialog
 493      * @param message the <code>Object</code> to display
 494      * @param initialSelectionValue the value used to initialize the input
 495      *                 field
 496      * @return user's input
 497      * @since 1.4
 498      */
 499     public static String showInputDialog(Component parentComponent, Object message,
 500                                          Object initialSelectionValue) {
 501         return (String)showInputDialog(parentComponent, message,
 502                       UIManager.getString("OptionPane.inputDialogTitle",
 503                       parentComponent), QUESTION_MESSAGE, null, null,
 504                       initialSelectionValue);
 505     }
 506 
 507     /**
 508      * Shows a dialog requesting input from the user parented to
 509      * <code>parentComponent</code> with the dialog having the title
 510      * <code>title</code> and message type <code>messageType</code>.
 511      *
 512      * @param parentComponent  the parent <code>Component</code> for the
 513      *                  dialog
 514      * @param message  the <code>Object</code> to display
 515      * @param title    the <code>String</code> to display in the dialog
 516      *                  title bar
 517      * @param messageType the type of message that is to be displayed:
 518      *                  <code>ERROR_MESSAGE</code>,
 519      *                  <code>INFORMATION_MESSAGE</code>,
 520      *                  <code>WARNING_MESSAGE</code>,
 521      *                  <code>QUESTION_MESSAGE</code>,
 522      *                  or <code>PLAIN_MESSAGE</code>
 523      * @return user's input
 524      * @exception HeadlessException if
 525      *   <code>GraphicsEnvironment.isHeadless</code> returns
 526      *   <code>true</code>
 527      * @see java.awt.GraphicsEnvironment#isHeadless
 528      */
 529     public static String showInputDialog(Component parentComponent,
 530         Object message, String title, int messageType)
 531         throws HeadlessException {
 532         return (String)showInputDialog(parentComponent, message, title,
 533                                        messageType, null, null, null);
 534     }
 535 
 536     /**
 537      * Prompts the user for input in a blocking dialog where the
 538      * initial selection, possible selections, and all other options can
 539      * be specified. The user will able to choose from
 540      * <code>selectionValues</code>, where <code>null</code> implies the
 541      * user can input
 542      * whatever they wish, usually by means of a <code>JTextField</code>.
 543      * <code>initialSelectionValue</code> is the initial value to prompt
 544      * the user with. It is up to the UI to decide how best to represent
 545      * the <code>selectionValues</code>, but usually a
 546      * <code>JComboBox</code>, <code>JList</code>, or
 547      * <code>JTextField</code> will be used.
 548      *
 549      * @param parentComponent  the parent <code>Component</code> for the
 550      *                  dialog
 551      * @param message  the <code>Object</code> to display
 552      * @param title    the <code>String</code> to display in the
 553      *                  dialog title bar
 554      * @param messageType the type of message to be displayed:
 555      *                  <code>ERROR_MESSAGE</code>,
 556      *                  <code>INFORMATION_MESSAGE</code>,
 557      *                  <code>WARNING_MESSAGE</code>,
 558      *                  <code>QUESTION_MESSAGE</code>,
 559      *                  or <code>PLAIN_MESSAGE</code>
 560      * @param icon     the <code>Icon</code> image to display
 561      * @param selectionValues an array of <code>Object</code>s that
 562      *                  gives the possible selections
 563      * @param initialSelectionValue the value used to initialize the input
 564      *                 field
 565      * @return user's input, or <code>null</code> meaning the user
 566      *                  canceled the input
 567      * @exception HeadlessException if
 568      *   <code>GraphicsEnvironment.isHeadless</code> returns
 569      *   <code>true</code>
 570      * @see java.awt.GraphicsEnvironment#isHeadless
 571      */
 572     public static Object showInputDialog(Component parentComponent,
 573         Object message, String title, int messageType, Icon icon,
 574         Object[] selectionValues, Object initialSelectionValue)
 575         throws HeadlessException {
 576         JOptionPane    pane = new JOptionPane(message, messageType,
 577                                               OK_CANCEL_OPTION, icon,
 578                                               null, null);
 579 
 580         pane.setWantsInput(true);
 581         pane.setSelectionValues(selectionValues);
 582         pane.setInitialSelectionValue(initialSelectionValue);
 583         pane.setComponentOrientation(((parentComponent == null) ?
 584             getRootFrame() : parentComponent).getComponentOrientation());
 585 
 586         int style = styleFromMessageType(messageType);
 587         JDialog dialog = pane.createDialog(parentComponent, title, style);
 588 
 589         pane.selectInitialValue();
 590         dialog.show();
 591         dialog.dispose();
 592 
 593         Object value = pane.getInputValue();
 594 
 595         if (value == UNINITIALIZED_VALUE) {
 596             return null;
 597         }
 598         return value;
 599     }
 600 
 601     /**
 602      * Brings up an information-message dialog titled "Message".
 603      *
 604      * @param parentComponent determines the <code>Frame</code> in
 605      *          which the dialog is displayed; if <code>null</code>,
 606      *          or if the <code>parentComponent</code> has no
 607      *          <code>Frame</code>, a default <code>Frame</code> is used
 608      * @param message   the <code>Object</code> to display
 609      * @exception HeadlessException if
 610      *   <code>GraphicsEnvironment.isHeadless</code> returns
 611      *   <code>true</code>
 612      * @see java.awt.GraphicsEnvironment#isHeadless
 613      */
 614     public static void showMessageDialog(Component parentComponent,
 615         Object message) throws HeadlessException {
 616         showMessageDialog(parentComponent, message, UIManager.getString(
 617                     "OptionPane.messageDialogTitle", parentComponent),
 618                     INFORMATION_MESSAGE);
 619     }
 620 
 621     /**
 622      * Brings up a dialog that displays a message using a default
 623      * icon determined by the <code>messageType</code> parameter.
 624      *
 625      * @param parentComponent determines the <code>Frame</code>
 626      *          in which the dialog is displayed; if <code>null</code>,
 627      *          or if the <code>parentComponent</code> has no
 628      *          <code>Frame</code>, a default <code>Frame</code> is used
 629      * @param message   the <code>Object</code> to display
 630      * @param title     the title string for the dialog
 631      * @param messageType the type of message to be displayed:
 632      *                  <code>ERROR_MESSAGE</code>,
 633      *                  <code>INFORMATION_MESSAGE</code>,
 634      *                  <code>WARNING_MESSAGE</code>,
 635      *                  <code>QUESTION_MESSAGE</code>,
 636      *                  or <code>PLAIN_MESSAGE</code>
 637      * @exception HeadlessException if
 638      *   <code>GraphicsEnvironment.isHeadless</code> returns
 639      *   <code>true</code>
 640      * @see java.awt.GraphicsEnvironment#isHeadless
 641      */
 642     public static void showMessageDialog(Component parentComponent,
 643         Object message, String title, int messageType)
 644         throws HeadlessException {
 645         showMessageDialog(parentComponent, message, title, messageType, null);
 646     }
 647 
 648     /**
 649      * Brings up a dialog displaying a message, specifying all parameters.
 650      *
 651      * @param parentComponent determines the <code>Frame</code> in which the
 652      *                  dialog is displayed; if <code>null</code>,
 653      *                  or if the <code>parentComponent</code> has no
 654      *                  <code>Frame</code>, a
 655      *                  default <code>Frame</code> is used
 656      * @param message   the <code>Object</code> to display
 657      * @param title     the title string for the dialog
 658      * @param messageType the type of message to be displayed:
 659      *                  <code>ERROR_MESSAGE</code>,
 660      *                  <code>INFORMATION_MESSAGE</code>,
 661      *                  <code>WARNING_MESSAGE</code>,
 662      *                  <code>QUESTION_MESSAGE</code>,
 663      *                  or <code>PLAIN_MESSAGE</code>
 664      * @param icon      an icon to display in the dialog that helps the user
 665      *                  identify the kind of message that is being displayed
 666      * @exception HeadlessException if
 667      *   <code>GraphicsEnvironment.isHeadless</code> returns
 668      *   <code>true</code>
 669      * @see java.awt.GraphicsEnvironment#isHeadless
 670      */
 671     public static void showMessageDialog(Component parentComponent,
 672         Object message, String title, int messageType, Icon icon)
 673         throws HeadlessException {
 674         showOptionDialog(parentComponent, message, title, DEFAULT_OPTION,
 675                          messageType, icon, null, null);
 676     }
 677 
 678     /**
 679      * Brings up a dialog with the options <i>Yes</i>,
 680      * <i>No</i> and <i>Cancel</i>; with the
 681      * title, <b>Select an Option</b>.
 682      *
 683      * @param parentComponent determines the <code>Frame</code> in which the
 684      *                  dialog is displayed; if <code>null</code>,
 685      *                  or if the <code>parentComponent</code> has no
 686      *                  <code>Frame</code>, a
 687      *                  default <code>Frame</code> is used
 688      * @param message   the <code>Object</code> to display
 689      * @return an integer indicating the option selected by the user
 690      * @exception HeadlessException if
 691      *   <code>GraphicsEnvironment.isHeadless</code> returns
 692      *   <code>true</code>
 693      * @see java.awt.GraphicsEnvironment#isHeadless
 694      */
 695     public static int showConfirmDialog(Component parentComponent,
 696         Object message) throws HeadlessException {
 697         return showConfirmDialog(parentComponent, message,
 698                                  UIManager.getString("OptionPane.titleText"),
 699                                  YES_NO_CANCEL_OPTION);
 700     }
 701 
 702     /**
 703      * Brings up a dialog where the number of choices is determined
 704      * by the <code>optionType</code> parameter.
 705      *
 706      * @param parentComponent determines the <code>Frame</code> in which the
 707      *                  dialog is displayed; if <code>null</code>,
 708      *                  or if the <code>parentComponent</code> has no
 709      *                  <code>Frame</code>, a
 710      *                  default <code>Frame</code> is used
 711      * @param message   the <code>Object</code> to display
 712      * @param title     the title string for the dialog
 713      * @param optionType an int designating the options available on the dialog:
 714      *                  <code>YES_NO_OPTION</code>,
 715      *                  <code>YES_NO_CANCEL_OPTION</code>,
 716      *                  or <code>OK_CANCEL_OPTION</code>
 717      * @return an int indicating the option selected by the user
 718      * @exception HeadlessException if
 719      *   <code>GraphicsEnvironment.isHeadless</code> returns
 720      *   <code>true</code>
 721      * @see java.awt.GraphicsEnvironment#isHeadless
 722      */
 723     public static int showConfirmDialog(Component parentComponent,
 724         Object message, String title, int optionType)
 725         throws HeadlessException {
 726         return showConfirmDialog(parentComponent, message, title, optionType,
 727                                  QUESTION_MESSAGE);
 728     }
 729 
 730     /**
 731      * Brings up a dialog where the number of choices is determined
 732      * by the <code>optionType</code> parameter, where the
 733      * <code>messageType</code>
 734      * parameter determines the icon to display.
 735      * The <code>messageType</code> parameter is primarily used to supply
 736      * a default icon from the Look and Feel.
 737      *
 738      * @param parentComponent determines the <code>Frame</code> in
 739      *                  which the dialog is displayed; if <code>null</code>,
 740      *                  or if the <code>parentComponent</code> has no
 741      *                  <code>Frame</code>, a
 742      *                  default <code>Frame</code> is used.
 743      * @param message   the <code>Object</code> to display
 744      * @param title     the title string for the dialog
 745      * @param optionType an integer designating the options available
 746      *                   on the dialog: <code>YES_NO_OPTION</code>,
 747      *                  <code>YES_NO_CANCEL_OPTION</code>,
 748      *                  or <code>OK_CANCEL_OPTION</code>
 749      * @param messageType an integer designating the kind of message this is;
 750      *                  primarily used to determine the icon from the pluggable
 751      *                  Look and Feel: <code>ERROR_MESSAGE</code>,
 752      *                  <code>INFORMATION_MESSAGE</code>,
 753      *                  <code>WARNING_MESSAGE</code>,
 754      *                  <code>QUESTION_MESSAGE</code>,
 755      *                  or <code>PLAIN_MESSAGE</code>
 756      * @return an integer indicating the option selected by the user
 757      * @exception HeadlessException if
 758      *   <code>GraphicsEnvironment.isHeadless</code> returns
 759      *   <code>true</code>
 760      * @see java.awt.GraphicsEnvironment#isHeadless
 761      */
 762     public static int showConfirmDialog(Component parentComponent,
 763         Object message, String title, int optionType, int messageType)
 764         throws HeadlessException {
 765         return showConfirmDialog(parentComponent, message, title, optionType,
 766                                 messageType, null);
 767     }
 768 
 769     /**
 770      * Brings up a dialog with a specified icon, where the number of
 771      * choices is determined by the <code>optionType</code> parameter.
 772      * The <code>messageType</code> parameter is primarily used to supply
 773      * a default icon from the look and feel.
 774      *
 775      * @param parentComponent determines the <code>Frame</code> in which the
 776      *                  dialog is displayed; if <code>null</code>,
 777      *                  or if the <code>parentComponent</code> has no
 778      *                  <code>Frame</code>, a
 779      *                  default <code>Frame</code> is used
 780      * @param message   the Object to display
 781      * @param title     the title string for the dialog
 782      * @param optionType an int designating the options available on the dialog:
 783      *                  <code>YES_NO_OPTION</code>,
 784      *                  <code>YES_NO_CANCEL_OPTION</code>,
 785      *                  or <code>OK_CANCEL_OPTION</code>
 786      * @param messageType an int designating the kind of message this is,
 787      *                  primarily used to determine the icon from the pluggable
 788      *                  Look and Feel: <code>ERROR_MESSAGE</code>,
 789      *                  <code>INFORMATION_MESSAGE</code>,
 790      *                  <code>WARNING_MESSAGE</code>,
 791      *                  <code>QUESTION_MESSAGE</code>,
 792      *                  or <code>PLAIN_MESSAGE</code>
 793      * @param icon      the icon to display in the dialog
 794      * @return an int indicating the option selected by the user
 795      * @exception HeadlessException if
 796      *   <code>GraphicsEnvironment.isHeadless</code> returns
 797      *   <code>true</code>
 798      * @see java.awt.GraphicsEnvironment#isHeadless
 799      */
 800     public static int showConfirmDialog(Component parentComponent,
 801         Object message, String title, int optionType,
 802         int messageType, Icon icon) throws HeadlessException {
 803         return showOptionDialog(parentComponent, message, title, optionType,
 804                                 messageType, icon, null, null);
 805     }
 806 
 807     /**
 808      * Brings up a dialog with a specified icon, where the initial
 809      * choice is determined by the <code>initialValue</code> parameter and
 810      * the number of choices is determined by the <code>optionType</code>
 811      * parameter.
 812      * <p>
 813      * If <code>optionType</code> is <code>YES_NO_OPTION</code>,
 814      * or <code>YES_NO_CANCEL_OPTION</code>
 815      * and the <code>options</code> parameter is <code>null</code>,
 816      * then the options are
 817      * supplied by the look and feel.
 818      * <p>
 819      * The <code>messageType</code> parameter is primarily used to supply
 820      * a default icon from the look and feel.
 821      *
 822      * @param parentComponent determines the <code>Frame</code>
 823      *                  in which the dialog is displayed;  if
 824      *                  <code>null</code>, or if the
 825      *                  <code>parentComponent</code> has no
 826      *                  <code>Frame</code>, a
 827      *                  default <code>Frame</code> is used
 828      * @param message   the <code>Object</code> to display
 829      * @param title     the title string for the dialog
 830      * @param optionType an integer designating the options available on the
 831      *                  dialog: <code>DEFAULT_OPTION</code>,
 832      *                  <code>YES_NO_OPTION</code>,
 833      *                  <code>YES_NO_CANCEL_OPTION</code>,
 834      *                  or <code>OK_CANCEL_OPTION</code>
 835      * @param messageType an integer designating the kind of message this is,
 836      *                  primarily used to determine the icon from the
 837      *                  pluggable Look and Feel: <code>ERROR_MESSAGE</code>,
 838      *                  <code>INFORMATION_MESSAGE</code>,
 839      *                  <code>WARNING_MESSAGE</code>,
 840      *                  <code>QUESTION_MESSAGE</code>,
 841      *                  or <code>PLAIN_MESSAGE</code>
 842      * @param icon      the icon to display in the dialog
 843      * @param options   an array of objects indicating the possible choices
 844      *                  the user can make; if the objects are components, they
 845      *                  are rendered properly; non-<code>String</code>
 846      *                  objects are
 847      *                  rendered using their <code>toString</code> methods;
 848      *                  if this parameter is <code>null</code>,
 849      *                  the options are determined by the Look and Feel
 850      * @param initialValue the object that represents the default selection
 851      *                  for the dialog; only meaningful if <code>options</code>
 852      *                  is used; can be <code>null</code>
 853      * @return an integer indicating the option chosen by the user,
 854      *                  or <code>CLOSED_OPTION</code> if the user closed
 855      *                  the dialog
 856      * @exception HeadlessException if
 857      *   <code>GraphicsEnvironment.isHeadless</code> returns
 858      *   <code>true</code>
 859      * @see java.awt.GraphicsEnvironment#isHeadless
 860      */
 861     public static int showOptionDialog(Component parentComponent,
 862         Object message, String title, int optionType, int messageType,
 863         Icon icon, Object[] options, Object initialValue)
 864         throws HeadlessException {
 865         JOptionPane             pane = new JOptionPane(message, messageType,
 866                                                        optionType, icon,
 867                                                        options, initialValue);
 868 
 869         pane.setInitialValue(initialValue);
 870         pane.setComponentOrientation(((parentComponent == null) ?
 871             getRootFrame() : parentComponent).getComponentOrientation());
 872 
 873         int style = styleFromMessageType(messageType);
 874         JDialog dialog = pane.createDialog(parentComponent, title, style);
 875 
 876         pane.selectInitialValue();
 877         dialog.show();
 878         dialog.dispose();
 879 
 880         Object        selectedValue = pane.getValue();
 881 
 882         if(selectedValue == null)
 883             return CLOSED_OPTION;
 884         if(options == null) {
 885             if(selectedValue instanceof Integer)
 886                 return ((Integer)selectedValue).intValue();
 887             return CLOSED_OPTION;
 888         }
 889         for(int counter = 0, maxCounter = options.length;
 890             counter < maxCounter; counter++) {
 891             if(options[counter].equals(selectedValue))
 892                 return counter;
 893         }
 894         return CLOSED_OPTION;
 895     }
 896 
 897     /**
 898      * Creates and returns a new <code>JDialog</code> wrapping
 899      * <code>this</code> centered on the <code>parentComponent</code>
 900      * in the <code>parentComponent</code>'s frame.
 901      * <code>title</code> is the title of the returned dialog.
 902      * The returned <code>JDialog</code> will not be resizable by the
 903      * user, however programs can invoke <code>setResizable</code> on
 904      * the <code>JDialog</code> instance to change this property.
 905      * The returned <code>JDialog</code> will be set up such that
 906      * once it is closed, or the user clicks on one of the buttons,
 907      * the optionpane's value property will be set accordingly and
 908      * the dialog will be closed.  Each time the dialog is made visible,
 909      * it will reset the option pane's value property to
 910      * <code>JOptionPane.UNINITIALIZED_VALUE</code> to ensure the
 911      * user's subsequent action closes the dialog properly.
 912      *
 913      * @param parentComponent determines the frame in which the dialog
 914      *          is displayed; if the <code>parentComponent</code> has
 915      *          no <code>Frame</code>, a default <code>Frame</code> is used
 916      * @param title     the title string for the dialog
 917      * @return a new <code>JDialog</code> containing this instance
 918      * @exception HeadlessException if
 919      *   <code>GraphicsEnvironment.isHeadless</code> returns
 920      *   <code>true</code>
 921      * @see java.awt.GraphicsEnvironment#isHeadless
 922      */
 923     public JDialog createDialog(Component parentComponent, String title)
 924         throws HeadlessException {
 925         int style = styleFromMessageType(getMessageType());
 926         return createDialog(parentComponent, title, style);
 927     }
 928 
 929     /**
 930      * Creates and returns a new parentless <code>JDialog</code>
 931      * with the specified title.
 932      * The returned <code>JDialog</code> will not be resizable by the
 933      * user, however programs can invoke <code>setResizable</code> on
 934      * the <code>JDialog</code> instance to change this property.
 935      * The returned <code>JDialog</code> will be set up such that
 936      * once it is closed, or the user clicks on one of the buttons,
 937      * the optionpane's value property will be set accordingly and
 938      * the dialog will be closed.  Each time the dialog is made visible,
 939      * it will reset the option pane's value property to
 940      * <code>JOptionPane.UNINITIALIZED_VALUE</code> to ensure the
 941      * user's subsequent action closes the dialog properly.
 942      *
 943      * @param title     the title string for the dialog
 944      * @return a new <code>JDialog</code> containing this instance
 945      * @exception HeadlessException if
 946      *   <code>GraphicsEnvironment.isHeadless</code> returns
 947      *   <code>true</code>
 948      * @see java.awt.GraphicsEnvironment#isHeadless
 949      * @since 1.6
 950      */
 951     public JDialog createDialog(String title) throws HeadlessException {
 952         int style = styleFromMessageType(getMessageType());
 953         JDialog dialog = new JDialog((Dialog) null, title, true);
 954         initDialog(dialog, style, null);
 955         return dialog;
 956     }
 957 
 958     private JDialog createDialog(Component parentComponent, String title,
 959             int style)
 960             throws HeadlessException {
 961 
 962         final JDialog dialog;
 963 
 964         Window window = JOptionPane.getWindowForComponent(parentComponent);
 965         if (window instanceof Frame) {
 966             dialog = new JDialog((Frame)window, title, true);
 967         } else {
 968             dialog = new JDialog((Dialog)window, title, true);
 969         }
 970         if (window instanceof SwingUtilities.SharedOwnerFrame) {
 971             WindowListener ownerShutdownListener =
 972                     SwingUtilities.getSharedOwnerFrameShutdownListener();
 973             dialog.addWindowListener(ownerShutdownListener);
 974         }
 975         initDialog(dialog, style, parentComponent);
 976         return dialog;
 977     }
 978 
 979     private void initDialog(final JDialog dialog, int style, Component parentComponent) {
 980         dialog.setComponentOrientation(this.getComponentOrientation());
 981         Container contentPane = dialog.getContentPane();
 982 
 983         contentPane.setLayout(new BorderLayout());
 984         contentPane.add(this, BorderLayout.CENTER);
 985         dialog.setResizable(false);
 986         if (JDialog.isDefaultLookAndFeelDecorated()) {
 987             boolean supportsWindowDecorations =
 988               UIManager.getLookAndFeel().getSupportsWindowDecorations();
 989             if (supportsWindowDecorations) {
 990                 dialog.setUndecorated(true);
 991                 getRootPane().setWindowDecorationStyle(style);
 992             }
 993         }
 994         dialog.pack();
 995         dialog.setLocationRelativeTo(parentComponent);
 996 
 997         final PropertyChangeListener listener = new PropertyChangeListener() {
 998             public void propertyChange(PropertyChangeEvent event) {
 999                 // Let the defaultCloseOperation handle the closing
1000                 // if the user closed the window without selecting a button
1001                 // (newValue = null in that case).  Otherwise, close the dialog.
1002                 if (dialog.isVisible() && event.getSource() == JOptionPane.this &&
1003                         (event.getPropertyName().equals(VALUE_PROPERTY)) &&
1004                         event.getNewValue() != null &&
1005                         event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) {
1006                     dialog.setVisible(false);
1007                 }
1008             }
1009         };
1010 
1011         WindowAdapter adapter = new WindowAdapter() {
1012             private boolean gotFocus = false;
1013             public void windowClosing(WindowEvent we) {
1014                 setValue(null);
1015             }
1016 
1017             public void windowClosed(WindowEvent e) {
1018                 removePropertyChangeListener(listener);
1019                 dialog.getContentPane().removeAll();
1020             }
1021 
1022             public void windowGainedFocus(WindowEvent we) {
1023                 // Once window gets focus, set initial focus
1024                 if (!gotFocus) {
1025                     selectInitialValue();
1026                     gotFocus = true;
1027                 }
1028             }
1029         };
1030         dialog.addWindowListener(adapter);
1031         dialog.addWindowFocusListener(adapter);
1032         dialog.addComponentListener(new ComponentAdapter() {
1033             public void componentShown(ComponentEvent ce) {
1034                 // reset value to ensure closing works properly
1035                 setValue(JOptionPane.UNINITIALIZED_VALUE);
1036             }
1037         });
1038 
1039         addPropertyChangeListener(listener);
1040     }
1041 
1042 
1043     /**
1044      * Brings up an internal confirmation dialog panel. The dialog
1045      * is a information-message dialog titled "Message".
1046      *
1047      * @param parentComponent determines the <code>Frame</code>
1048      *          in which the dialog is displayed; if <code>null</code>,
1049      *          or if the <code>parentComponent</code> has no
1050      *          <code>Frame</code>, a default <code>Frame</code> is used
1051      * @param message   the object to display
1052      */
1053     public static void showInternalMessageDialog(Component parentComponent,
1054                                                  Object message) {
1055         showInternalMessageDialog(parentComponent, message, UIManager.
1056                                  getString("OptionPane.messageDialogTitle",
1057                                  parentComponent), INFORMATION_MESSAGE);
1058     }
1059 
1060     /**
1061      * Brings up an internal dialog panel that displays a message
1062      * using a default icon determined by the <code>messageType</code>
1063      * parameter.
1064      *
1065      * @param parentComponent determines the <code>Frame</code>
1066      *          in which the dialog is displayed; if <code>null</code>,
1067      *          or if the <code>parentComponent</code> has no
1068      *          <code>Frame</code>, a default <code>Frame</code> is used
1069      * @param message   the <code>Object</code> to display
1070      * @param title     the title string for the dialog
1071      * @param messageType the type of message to be displayed:
1072      *                  <code>ERROR_MESSAGE</code>,
1073      *                  <code>INFORMATION_MESSAGE</code>,
1074      *                  <code>WARNING_MESSAGE</code>,
1075      *                  <code>QUESTION_MESSAGE</code>,
1076      *                  or <code>PLAIN_MESSAGE</code>
1077      */
1078     public static void showInternalMessageDialog(Component parentComponent,
1079                                                  Object message, String title,
1080                                                  int messageType) {
1081         showInternalMessageDialog(parentComponent, message, title, messageType,null);
1082     }
1083 
1084     /**
1085      * Brings up an internal dialog panel displaying a message,
1086      * specifying all parameters.
1087      *
1088      * @param parentComponent determines the <code>Frame</code>
1089      *          in which the dialog is displayed; if <code>null</code>,
1090      *          or if the <code>parentComponent</code> has no
1091      *          <code>Frame</code>, a default <code>Frame</code> is used
1092      * @param message   the <code>Object</code> to display
1093      * @param title     the title string for the dialog
1094      * @param messageType the type of message to be displayed:
1095      *                  <code>ERROR_MESSAGE</code>,
1096      *                  <code>INFORMATION_MESSAGE</code>,
1097      *                  <code>WARNING_MESSAGE</code>,
1098      *                  <code>QUESTION_MESSAGE</code>,
1099      *                  or <code>PLAIN_MESSAGE</code>
1100      * @param icon      an icon to display in the dialog that helps the user
1101      *                  identify the kind of message that is being displayed
1102      */
1103     public static void showInternalMessageDialog(Component parentComponent,
1104                                          Object message,
1105                                          String title, int messageType,
1106                                          Icon icon){
1107         showInternalOptionDialog(parentComponent, message, title, DEFAULT_OPTION,
1108                                  messageType, icon, null, null);
1109     }
1110 
1111     /**
1112      * Brings up an internal dialog panel with the options <i>Yes</i>, <i>No</i>
1113      * and <i>Cancel</i>; with the title, <b>Select an Option</b>.
1114      *
1115      * @param parentComponent determines the <code>Frame</code> in
1116      *          which the dialog is displayed; if <code>null</code>,
1117      *          or if the <code>parentComponent</code> has no
1118      *          <code>Frame</code>, a default <code>Frame</code> is used
1119      * @param message   the <code>Object</code> to display
1120      * @return an integer indicating the option selected by the user
1121      */
1122     public static int showInternalConfirmDialog(Component parentComponent,
1123                                                 Object message) {
1124         return showInternalConfirmDialog(parentComponent, message,
1125                                  UIManager.getString("OptionPane.titleText"),
1126                                  YES_NO_CANCEL_OPTION);
1127     }
1128 
1129     /**
1130      * Brings up a internal dialog panel where the number of choices
1131      * is determined by the <code>optionType</code> parameter.
1132      *
1133      * @param parentComponent determines the <code>Frame</code>
1134      *          in which the dialog is displayed; if <code>null</code>,
1135      *          or if the <code>parentComponent</code> has no
1136      *          <code>Frame</code>, a default <code>Frame</code> is used
1137      * @param message   the object to display in the dialog; a
1138      *          <code>Component</code> object is rendered as a
1139      *          <code>Component</code>; a <code>String</code>
1140      *          object is rendered as a string; other objects
1141      *          are converted to a <code>String</code> using the
1142      *          <code>toString</code> method
1143      * @param title     the title string for the dialog
1144      * @param optionType an integer designating the options
1145      *          available on the dialog: <code>YES_NO_OPTION</code>,
1146      *          or <code>YES_NO_CANCEL_OPTION</code>
1147      * @return an integer indicating the option selected by the user
1148      */
1149     public static int showInternalConfirmDialog(Component parentComponent,
1150                                                 Object message, String title,
1151                                                 int optionType) {
1152         return showInternalConfirmDialog(parentComponent, message, title, optionType,
1153                                          QUESTION_MESSAGE);
1154     }
1155 
1156     /**
1157      * Brings up an internal dialog panel where the number of choices
1158      * is determined by the <code>optionType</code> parameter, where
1159      * the <code>messageType</code> parameter determines the icon to display.
1160      * The <code>messageType</code> parameter is primarily used to supply
1161      * a default icon from the Look and Feel.
1162      *
1163      * @param parentComponent determines the <code>Frame</code> in
1164      *          which the dialog is displayed; if <code>null</code>,
1165      *          or if the <code>parentComponent</code> has no
1166      *          <code>Frame</code>, a default <code>Frame</code> is used
1167      * @param message   the object to display in the dialog; a
1168      *          <code>Component</code> object is rendered as a
1169      *          <code>Component</code>; a <code>String</code>
1170      *          object is rendered as a string; other objects are
1171      *          converted to a <code>String</code> using the
1172      *          <code>toString</code> method
1173      * @param title     the title string for the dialog
1174      * @param optionType an integer designating the options
1175      *          available on the dialog:
1176      *          <code>YES_NO_OPTION</code>, or <code>YES_NO_CANCEL_OPTION</code>
1177      * @param messageType an integer designating the kind of message this is,
1178      *          primarily used to determine the icon from the
1179      *          pluggable Look and Feel: <code>ERROR_MESSAGE</code>,
1180      *          <code>INFORMATION_MESSAGE</code>,
1181      *          <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
1182      *          or <code>PLAIN_MESSAGE</code>
1183      * @return an integer indicating the option selected by the user
1184      */
1185     public static int showInternalConfirmDialog(Component parentComponent,
1186                                         Object message,
1187                                         String title, int optionType,
1188                                         int messageType) {
1189         return showInternalConfirmDialog(parentComponent, message, title, optionType,
1190                                          messageType, null);
1191     }
1192 
1193     /**
1194      * Brings up an internal dialog panel with a specified icon, where
1195      * the number of choices is determined by the <code>optionType</code>
1196      * parameter.
1197      * The <code>messageType</code> parameter is primarily used to supply
1198      * a default icon from the look and feel.
1199      *
1200      * @param parentComponent determines the <code>Frame</code>
1201      *          in which the dialog is displayed; if <code>null</code>,
1202      *          or if the parentComponent has no Frame, a
1203      *          default <code>Frame</code> is used
1204      * @param message   the object to display in the dialog; a
1205      *          <code>Component</code> object is rendered as a
1206      *          <code>Component</code>; a <code>String</code>
1207      *          object is rendered as a string; other objects are
1208      *          converted to a <code>String</code> using the
1209      *          <code>toString</code> method
1210      * @param title     the title string for the dialog
1211      * @param optionType an integer designating the options available
1212      *          on the dialog:
1213      *          <code>YES_NO_OPTION</code>, or
1214      *          <code>YES_NO_CANCEL_OPTION</code>.
1215      * @param messageType an integer designating the kind of message this is,
1216      *          primarily used to determine the icon from the pluggable
1217      *          Look and Feel: <code>ERROR_MESSAGE</code>,
1218      *          <code>INFORMATION_MESSAGE</code>,
1219      *          <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
1220      *          or <code>PLAIN_MESSAGE</code>
1221      * @param icon      the icon to display in the dialog
1222      * @return an integer indicating the option selected by the user
1223      */
1224     public static int showInternalConfirmDialog(Component parentComponent,
1225                                         Object message,
1226                                         String title, int optionType,
1227                                         int messageType, Icon icon) {
1228         return showInternalOptionDialog(parentComponent, message, title, optionType,
1229                                         messageType, icon, null, null);
1230     }
1231 
1232     /**
1233      * Brings up an internal dialog panel with a specified icon, where
1234      * the initial choice is determined by the <code>initialValue</code>
1235      * parameter and the number of choices is determined by the
1236      * <code>optionType</code> parameter.
1237      * <p>
1238      * If <code>optionType</code> is <code>YES_NO_OPTION</code>, or
1239      * <code>YES_NO_CANCEL_OPTION</code>
1240      * and the <code>options</code> parameter is <code>null</code>,
1241      * then the options are supplied by the Look and Feel.
1242      * <p>
1243      * The <code>messageType</code> parameter is primarily used to supply
1244      * a default icon from the look and feel.
1245      *
1246      * @param parentComponent determines the <code>Frame</code>
1247      *          in which the dialog is displayed; if <code>null</code>,
1248      *          or if the <code>parentComponent</code> has no
1249      *          <code>Frame</code>, a default <code>Frame</code> is used
1250      * @param message   the object to display in the dialog; a
1251      *          <code>Component</code> object is rendered as a
1252      *          <code>Component</code>; a <code>String</code>
1253      *          object is rendered as a string. Other objects are
1254      *          converted to a <code>String</code> using the
1255      *          <code>toString</code> method
1256      * @param title     the title string for the dialog
1257      * @param optionType an integer designating the options available
1258      *          on the dialog: <code>YES_NO_OPTION</code>,
1259      *          or <code>YES_NO_CANCEL_OPTION</code>
1260      * @param messageType an integer designating the kind of message this is;
1261      *          primarily used to determine the icon from the
1262      *          pluggable Look and Feel: <code>ERROR_MESSAGE</code>,
1263      *          <code>INFORMATION_MESSAGE</code>,
1264      *          <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
1265      *          or <code>PLAIN_MESSAGE</code>
1266      * @param icon      the icon to display in the dialog
1267      * @param options   an array of objects indicating the possible choices
1268      *          the user can make; if the objects are components, they
1269      *          are rendered properly; non-<code>String</code>
1270      *          objects are rendered using their <code>toString</code>
1271      *          methods; if this parameter is <code>null</code>,
1272      *          the options are determined by the Look and Feel
1273      * @param initialValue the object that represents the default selection
1274      *          for the dialog; only meaningful if <code>options</code>
1275      *          is used; can be <code>null</code>
1276      * @return an integer indicating the option chosen by the user,
1277      *          or <code>CLOSED_OPTION</code> if the user closed the Dialog
1278      */
1279     public static int showInternalOptionDialog(Component parentComponent,
1280                                        Object message,
1281                                        String title, int optionType,
1282                                        int messageType, Icon icon,
1283                                        Object[] options, Object initialValue) {
1284         JOptionPane pane = new JOptionPane(message, messageType,
1285                 optionType, icon, options, initialValue);
1286         pane.putClientProperty(PopupFactory_FORCE_HEAVYWEIGHT_POPUP,
1287                 Boolean.TRUE);
1288         Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager().
1289                 getFocusOwner();
1290 
1291         pane.setInitialValue(initialValue);
1292 
1293         JInternalFrame dialog =
1294             pane.createInternalFrame(parentComponent, title);
1295         pane.selectInitialValue();
1296         dialog.setVisible(true);
1297 
1298         /* Since all input will be blocked until this dialog is dismissed,
1299          * make sure its parent containers are visible first (this component
1300          * is tested below).  This is necessary for JApplets, because
1301          * because an applet normally isn't made visible until after its
1302          * start() method returns -- if this method is called from start(),
1303          * the applet will appear to hang while an invisible modal frame
1304          * waits for input.
1305          */
1306         if (dialog.isVisible() && !dialog.isShowing()) {
1307             Container parent = dialog.getParent();
1308             while (parent != null) {
1309                 if (parent.isVisible() == false) {
1310                     parent.setVisible(true);
1311                 }
1312                 parent = parent.getParent();
1313             }
1314         }
1315 
1316         AWTAccessor.getContainerAccessor().startLWModal(dialog);
1317 
1318         if (parentComponent instanceof JInternalFrame) {
1319             try {
1320                 ((JInternalFrame)parentComponent).setSelected(true);
1321             } catch (java.beans.PropertyVetoException e) {
1322             }
1323         }
1324 
1325         Object selectedValue = pane.getValue();
1326 
1327         if (fo != null && fo.isShowing()) {
1328             fo.requestFocus();
1329         }
1330         if (selectedValue == null) {
1331             return CLOSED_OPTION;
1332         }
1333         if (options == null) {
1334             if (selectedValue instanceof Integer) {
1335                 return ((Integer)selectedValue).intValue();
1336             }
1337             return CLOSED_OPTION;
1338         }
1339         for(int counter = 0, maxCounter = options.length;
1340             counter < maxCounter; counter++) {
1341             if (options[counter].equals(selectedValue)) {
1342                 return counter;
1343             }
1344         }
1345         return CLOSED_OPTION;
1346     }
1347 
1348     /**
1349      * Shows an internal question-message dialog requesting input from
1350      * the user parented to <code>parentComponent</code>. The dialog
1351      * is displayed in the <code>Component</code>'s frame,
1352      * and is usually positioned below the <code>Component</code>.
1353      *
1354      * @param parentComponent  the parent <code>Component</code>
1355      *          for the dialog
1356      * @param message  the <code>Object</code> to display
1357      * @return user's input
1358      */
1359     public static String showInternalInputDialog(Component parentComponent,
1360                                                  Object message) {
1361         return showInternalInputDialog(parentComponent, message, UIManager.
1362                getString("OptionPane.inputDialogTitle", parentComponent),
1363                QUESTION_MESSAGE);
1364     }
1365 
1366     /**
1367      * Shows an internal dialog requesting input from the user parented
1368      * to <code>parentComponent</code> with the dialog having the title
1369      * <code>title</code> and message type <code>messageType</code>.
1370      *
1371      * @param parentComponent the parent <code>Component</code> for the dialog
1372      * @param message  the <code>Object</code> to display
1373      * @param title    the <code>String</code> to display in the
1374      *          dialog title bar
1375      * @param messageType the type of message that is to be displayed:
1376      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
1377      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE
1378      * @return user's input
1379      */
1380     public static String showInternalInputDialog(Component parentComponent,
1381                              Object message, String title, int messageType) {
1382         return (String)showInternalInputDialog(parentComponent, message, title,
1383                                        messageType, null, null, null);
1384     }
1385 
1386     /**
1387      * Prompts the user for input in a blocking internal dialog where
1388      * the initial selection, possible selections, and all other
1389      * options can be specified. The user will able to choose from
1390      * <code>selectionValues</code>, where <code>null</code>
1391      * implies the user can input
1392      * whatever they wish, usually by means of a <code>JTextField</code>.
1393      * <code>initialSelectionValue</code> is the initial value to prompt
1394      * the user with. It is up to the UI to decide how best to represent
1395      * the <code>selectionValues</code>, but usually a
1396      * <code>JComboBox</code>, <code>JList</code>, or
1397      * <code>JTextField</code> will be used.
1398      *
1399      * @param parentComponent the parent <code>Component</code> for the dialog
1400      * @param message  the <code>Object</code> to display
1401      * @param title    the <code>String</code> to display in the dialog
1402      *          title bar
1403      * @param messageType the type of message to be displayed:
1404      *                  <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
1405      *                  <code>WARNING_MESSAGE</code>,
1406      *                  <code>QUESTION_MESSAGE</code>, or <code>PLAIN_MESSAGE</code>
1407      * @param icon     the <code>Icon</code> image to display
1408      * @param selectionValues an array of <code>Objects</code> that
1409      *                  gives the possible selections
1410      * @param initialSelectionValue the value used to initialize the input
1411      *                  field
1412      * @return user's input, or <code>null</code> meaning the user
1413      *          canceled the input
1414      */
1415     public static Object showInternalInputDialog(Component parentComponent,
1416             Object message, String title, int messageType, Icon icon,
1417             Object[] selectionValues, Object initialSelectionValue) {
1418         JOptionPane pane = new JOptionPane(message, messageType,
1419                 OK_CANCEL_OPTION, icon, null, null);
1420         pane.putClientProperty(PopupFactory_FORCE_HEAVYWEIGHT_POPUP,
1421                 Boolean.TRUE);
1422         Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager().
1423                 getFocusOwner();
1424 
1425         pane.setWantsInput(true);
1426         pane.setSelectionValues(selectionValues);
1427         pane.setInitialSelectionValue(initialSelectionValue);
1428 
1429         JInternalFrame dialog =
1430             pane.createInternalFrame(parentComponent, title);
1431 
1432         pane.selectInitialValue();
1433         dialog.setVisible(true);
1434 
1435         /* Since all input will be blocked until this dialog is dismissed,
1436          * make sure its parent containers are visible first (this component
1437          * is tested below).  This is necessary for JApplets, because
1438          * because an applet normally isn't made visible until after its
1439          * start() method returns -- if this method is called from start(),
1440          * the applet will appear to hang while an invisible modal frame
1441          * waits for input.
1442          */
1443         if (dialog.isVisible() && !dialog.isShowing()) {
1444             Container parent = dialog.getParent();
1445             while (parent != null) {
1446                 if (parent.isVisible() == false) {
1447                     parent.setVisible(true);
1448                 }
1449                 parent = parent.getParent();
1450             }
1451         }
1452 
1453         AWTAccessor.getContainerAccessor().startLWModal(dialog);
1454 
1455         if (parentComponent instanceof JInternalFrame) {
1456             try {
1457                 ((JInternalFrame)parentComponent).setSelected(true);
1458             } catch (java.beans.PropertyVetoException e) {
1459             }
1460         }
1461 
1462         if (fo != null && fo.isShowing()) {
1463             fo.requestFocus();
1464         }
1465         Object value = pane.getInputValue();
1466 
1467         if (value == UNINITIALIZED_VALUE) {
1468             return null;
1469         }
1470         return value;
1471     }
1472 
1473     /**
1474      * Creates and returns an instance of <code>JInternalFrame</code>.
1475      * The internal frame is created with the specified title,
1476      * and wrapping the <code>JOptionPane</code>.
1477      * The returned <code>JInternalFrame</code> is
1478      * added to the <code>JDesktopPane</code> ancestor of
1479      * <code>parentComponent</code>, or components
1480      * parent if one its ancestors isn't a <code>JDesktopPane</code>,
1481      * or if <code>parentComponent</code>
1482      * doesn't have a parent then a <code>RuntimeException</code> is thrown.
1483      *
1484      * @param parentComponent  the parent <code>Component</code> for
1485      *          the internal frame
1486      * @param title    the <code>String</code> to display in the
1487      *          frame's title bar
1488      * @return a <code>JInternalFrame</code> containing a
1489      *          <code>JOptionPane</code>
1490      * @exception RuntimeException if <code>parentComponent</code> does
1491      *          not have a valid parent
1492      */
1493     public JInternalFrame createInternalFrame(Component parentComponent,
1494                                  String title) {
1495         Container parent =
1496                 JOptionPane.getDesktopPaneForComponent(parentComponent);
1497 
1498         if (parent == null && (parentComponent == null ||
1499                 (parent = parentComponent.getParent()) == null)) {
1500             throw new RuntimeException("JOptionPane: parentComponent does " +
1501                     "not have a valid parent");
1502         }
1503 
1504         // Option dialogs should be closable only
1505         final JInternalFrame  iFrame = new JInternalFrame(title, false, true,
1506                                                            false, false);
1507 
1508         iFrame.putClientProperty("JInternalFrame.frameType", "optionDialog");
1509         iFrame.putClientProperty("JInternalFrame.messageType",
1510                                  Integer.valueOf(getMessageType()));
1511 
1512         iFrame.addInternalFrameListener(new InternalFrameAdapter() {
1513             public void internalFrameClosing(InternalFrameEvent e) {
1514                 if (getValue() == UNINITIALIZED_VALUE) {
1515                     setValue(null);
1516                 }
1517             }
1518         });
1519         addPropertyChangeListener(new PropertyChangeListener() {
1520             public void propertyChange(PropertyChangeEvent event) {
1521                 // Let the defaultCloseOperation handle the closing
1522                 // if the user closed the iframe without selecting a button
1523                 // (newValue = null in that case).  Otherwise, close the dialog.
1524                 if (iFrame.isVisible() &&
1525                         event.getSource() == JOptionPane.this &&
1526                         event.getPropertyName().equals(VALUE_PROPERTY)) {
1527                     AWTAccessor.getContainerAccessor().stopLWModal(iFrame);
1528 
1529                 try {
1530                     iFrame.setClosed(true);
1531                 }
1532                 catch (java.beans.PropertyVetoException e) {
1533                 }
1534 
1535                 iFrame.setVisible(false);
1536                 }
1537             }
1538         });
1539         iFrame.getContentPane().add(this, BorderLayout.CENTER);
1540         if (parent instanceof JDesktopPane) {
1541             parent.add(iFrame, JLayeredPane.MODAL_LAYER);
1542         } else {
1543             parent.add(iFrame, BorderLayout.CENTER);
1544         }
1545         Dimension iFrameSize = iFrame.getPreferredSize();
1546         Dimension rootSize = parent.getSize();
1547         Dimension parentSize = parentComponent.getSize();
1548 
1549         iFrame.setBounds((rootSize.width - iFrameSize.width) / 2,
1550                          (rootSize.height - iFrameSize.height) / 2,
1551                          iFrameSize.width, iFrameSize.height);
1552         // We want dialog centered relative to its parent component
1553         Point iFrameCoord =
1554           SwingUtilities.convertPoint(parentComponent, 0, 0, parent);
1555         int x = (parentSize.width - iFrameSize.width) / 2 + iFrameCoord.x;
1556         int y = (parentSize.height - iFrameSize.height) / 2 + iFrameCoord.y;
1557 
1558         // If possible, dialog should be fully visible
1559         int ovrx = x + iFrameSize.width - rootSize.width;
1560         int ovry = y + iFrameSize.height - rootSize.height;
1561         x = Math.max((ovrx > 0? x - ovrx: x), 0);
1562         y = Math.max((ovry > 0? y - ovry: y), 0);
1563         iFrame.setBounds(x, y, iFrameSize.width, iFrameSize.height);
1564 
1565         parent.validate();
1566         try {
1567             iFrame.setSelected(true);
1568         } catch (java.beans.PropertyVetoException e) {}
1569 
1570         return iFrame;
1571     }
1572 
1573     /**
1574      * Returns the specified component's <code>Frame</code>.
1575      *
1576      * @param parentComponent the <code>Component</code> to check for a
1577      *          <code>Frame</code>
1578      * @return the <code>Frame</code> that contains the component,
1579      *          or <code>getRootFrame</code>
1580      *          if the component is <code>null</code>,
1581      *          or does not have a valid <code>Frame</code> parent
1582      * @exception HeadlessException if
1583      *   <code>GraphicsEnvironment.isHeadless</code> returns
1584      *   <code>true</code>
1585      * @see #getRootFrame
1586      * @see java.awt.GraphicsEnvironment#isHeadless
1587      */
1588     public static Frame getFrameForComponent(Component parentComponent)
1589         throws HeadlessException {
1590         if (parentComponent == null)
1591             return getRootFrame();
1592         if (parentComponent instanceof Frame)
1593             return (Frame)parentComponent;
1594         return JOptionPane.getFrameForComponent(parentComponent.getParent());
1595     }
1596 
1597     /**
1598      * Returns the specified component's toplevel <code>Frame</code> or
1599      * <code>Dialog</code>.
1600      *
1601      * @param parentComponent the <code>Component</code> to check for a
1602      *          <code>Frame</code> or <code>Dialog</code>
1603      * @return the <code>Frame</code> or <code>Dialog</code> that
1604      *          contains the component, or the default
1605      *          frame if the component is <code>null</code>,
1606      *          or does not have a valid
1607      *          <code>Frame</code> or <code>Dialog</code> parent
1608      * @exception HeadlessException if
1609      *   <code>GraphicsEnvironment.isHeadless</code> returns
1610      *   <code>true</code>
1611      * @see java.awt.GraphicsEnvironment#isHeadless
1612      */
1613     static Window getWindowForComponent(Component parentComponent)
1614         throws HeadlessException {
1615         if (parentComponent == null)
1616             return getRootFrame();
1617         if (parentComponent instanceof Frame || parentComponent instanceof Dialog)
1618             return (Window)parentComponent;
1619         return JOptionPane.getWindowForComponent(parentComponent.getParent());
1620     }
1621 
1622 
1623     /**
1624      * Returns the specified component's desktop pane.
1625      *
1626      * @param parentComponent the <code>Component</code> to check for a
1627      *          desktop
1628      * @return the <code>JDesktopPane</code> that contains the component,
1629      *          or <code>null</code> if the component is <code>null</code>
1630      *          or does not have an ancestor that is a
1631      *          <code>JInternalFrame</code>
1632      */
1633     public static JDesktopPane getDesktopPaneForComponent(Component parentComponent) {
1634         if(parentComponent == null)
1635             return null;
1636         if(parentComponent instanceof JDesktopPane)
1637             return (JDesktopPane)parentComponent;
1638         return getDesktopPaneForComponent(parentComponent.getParent());
1639     }
1640 
1641     private static final Object sharedFrameKey = JOptionPane.class;
1642 
1643     /**
1644      * Sets the frame to use for class methods in which a frame is
1645      * not provided.
1646      * <p>
1647      * <strong>Note:</strong>
1648      * It is recommended that rather than using this method you supply a valid parent.
1649      *
1650      * @param newRootFrame the default <code>Frame</code> to use
1651      */
1652     public static void setRootFrame(Frame newRootFrame) {
1653         if (newRootFrame != null) {
1654             SwingUtilities.appContextPut(sharedFrameKey, newRootFrame);
1655         } else {
1656             SwingUtilities.appContextRemove(sharedFrameKey);
1657         }
1658     }
1659 
1660     /**
1661      * Returns the <code>Frame</code> to use for the class methods in
1662      * which a frame is not provided.
1663      *
1664      * @return the default <code>Frame</code> to use
1665      * @exception HeadlessException if
1666      *   <code>GraphicsEnvironment.isHeadless</code> returns
1667      *   <code>true</code>
1668      * @see #setRootFrame
1669      * @see java.awt.GraphicsEnvironment#isHeadless
1670      */
1671     public static Frame getRootFrame() throws HeadlessException {
1672         Frame sharedFrame =
1673             (Frame)SwingUtilities.appContextGet(sharedFrameKey);
1674         if (sharedFrame == null) {
1675             sharedFrame = SwingUtilities.getSharedOwnerFrame();
1676             SwingUtilities.appContextPut(sharedFrameKey, sharedFrame);
1677         }
1678         return sharedFrame;
1679     }
1680 
1681     /**
1682      * Creates a <code>JOptionPane</code> with a test message.
1683      */
1684     public JOptionPane() {
1685         this("JOptionPane message");
1686     }
1687 
1688     /**
1689      * Creates a instance of <code>JOptionPane</code> to display a
1690      * message using the
1691      * plain-message message type and the default options delivered by
1692      * the UI.
1693      *
1694      * @param message the <code>Object</code> to display
1695      */
1696     public JOptionPane(Object message) {
1697         this(message, PLAIN_MESSAGE);
1698     }
1699 
1700     /**
1701      * Creates an instance of <code>JOptionPane</code> to display a message
1702      * with the specified message type and the default options,
1703      *
1704      * @param message the <code>Object</code> to display
1705      * @param messageType the type of message to be displayed:
1706      *                  <code>ERROR_MESSAGE</code>,
1707      *                  <code>INFORMATION_MESSAGE</code>,
1708      *                  <code>WARNING_MESSAGE</code>,
1709      *                  <code>QUESTION_MESSAGE</code>,
1710      *                  or <code>PLAIN_MESSAGE</code>
1711      */
1712     public JOptionPane(Object message, int messageType) {
1713         this(message, messageType, DEFAULT_OPTION);
1714     }
1715 
1716     /**
1717      * Creates an instance of <code>JOptionPane</code> to display a message
1718      * with the specified message type and options.
1719      *
1720      * @param message the <code>Object</code> to display
1721      * @param messageType the type of message to be displayed:
1722      *                  <code>ERROR_MESSAGE</code>,
1723      *                  <code>INFORMATION_MESSAGE</code>,
1724      *                  <code>WARNING_MESSAGE</code>,
1725      *                  <code>QUESTION_MESSAGE</code>,
1726      *                  or <code>PLAIN_MESSAGE</code>
1727      * @param optionType the options to display in the pane:
1728      *                  <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>,
1729      *                  <code>YES_NO_CANCEL_OPTION</code>,
1730      *                  <code>OK_CANCEL_OPTION</code>
1731      */
1732     public JOptionPane(Object message, int messageType, int optionType) {
1733         this(message, messageType, optionType, null);
1734     }
1735 
1736     /**
1737      * Creates an instance of <code>JOptionPane</code> to display a message
1738      * with the specified message type, options, and icon.
1739      *
1740      * @param message the <code>Object</code> to display
1741      * @param messageType the type of message to be displayed:
1742      *                  <code>ERROR_MESSAGE</code>,
1743      *                  <code>INFORMATION_MESSAGE</code>,
1744      *                  <code>WARNING_MESSAGE</code>,
1745      *                  <code>QUESTION_MESSAGE</code>,
1746      *                  or <code>PLAIN_MESSAGE</code>
1747      * @param optionType the options to display in the pane:
1748      *                  <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>,
1749      *                  <code>YES_NO_CANCEL_OPTION</code>,
1750      *                  <code>OK_CANCEL_OPTION</code>
1751      * @param icon the <code>Icon</code> image to display
1752      */
1753     public JOptionPane(Object message, int messageType, int optionType,
1754                        Icon icon) {
1755         this(message, messageType, optionType, icon, null);
1756     }
1757 
1758     /**
1759      * Creates an instance of <code>JOptionPane</code> to display a message
1760      * with the specified message type, icon, and options.
1761      * None of the options is initially selected.
1762      * <p>
1763      * The options objects should contain either instances of
1764      * <code>Component</code>s, (which are added directly) or
1765      * <code>Strings</code> (which are wrapped in a <code>JButton</code>).
1766      * If you provide <code>Component</code>s, you must ensure that when the
1767      * <code>Component</code> is clicked it messages <code>setValue</code>
1768      * in the created <code>JOptionPane</code>.
1769      *
1770      * @param message the <code>Object</code> to display
1771      * @param messageType the type of message to be displayed:
1772      *                  <code>ERROR_MESSAGE</code>,
1773      *                  <code>INFORMATION_MESSAGE</code>,
1774      *                  <code>WARNING_MESSAGE</code>,
1775      *                  <code>QUESTION_MESSAGE</code>,
1776      *                  or <code>PLAIN_MESSAGE</code>
1777      * @param optionType the options to display in the pane:
1778      *                  <code>DEFAULT_OPTION</code>,
1779      *                  <code>YES_NO_OPTION</code>,
1780      *                  <code>YES_NO_CANCEL_OPTION</code>,
1781      *                  <code>OK_CANCEL_OPTION</code>
1782      * @param icon the <code>Icon</code> image to display
1783      * @param options  the choices the user can select
1784      */
1785     public JOptionPane(Object message, int messageType, int optionType,
1786                        Icon icon, Object[] options) {
1787         this(message, messageType, optionType, icon, options, null);
1788     }
1789 
1790     /**
1791      * Creates an instance of <code>JOptionPane</code> to display a message
1792      * with the specified message type, icon, and options, with the
1793      * initially-selected option specified.
1794      *
1795      * @param message the <code>Object</code> to display
1796      * @param messageType the type of message to be displayed:
1797      *                  <code>ERROR_MESSAGE</code>,
1798      *                  <code>INFORMATION_MESSAGE</code>,
1799      *                  <code>WARNING_MESSAGE</code>,
1800      *                  <code>QUESTION_MESSAGE</code>,
1801      *                  or <code>PLAIN_MESSAGE</code>
1802      * @param optionType the options to display in the pane:
1803      *                  <code>DEFAULT_OPTION</code>,
1804      *                  <code>YES_NO_OPTION</code>,
1805      *                  <code>YES_NO_CANCEL_OPTION</code>,
1806      *                  <code>OK_CANCEL_OPTION</code>
1807      * @param icon the Icon image to display
1808      * @param options  the choices the user can select
1809      * @param initialValue the choice that is initially selected; if
1810      *                  <code>null</code>, then nothing will be initially selected;
1811      *                  only meaningful if <code>options</code> is used
1812      */
1813     public JOptionPane(Object message, int messageType, int optionType,
1814                        Icon icon, Object[] options, Object initialValue) {
1815 
1816         this.message = message;
1817         this.options = options;
1818         this.initialValue = initialValue;
1819         this.icon = icon;
1820         setMessageType(messageType);
1821         setOptionType(optionType);
1822         value = UNINITIALIZED_VALUE;
1823         inputValue = UNINITIALIZED_VALUE;
1824         updateUI();
1825     }
1826 
1827     /**
1828      * Sets the UI object which implements the {@literal L&F} for this component.
1829      *
1830      * @param ui  the <code>OptionPaneUI</code> {@literal L&F} object
1831      * @see UIDefaults#getUI
1832      * @beaninfo
1833      *       bound: true
1834      *      hidden: true
1835      * description: The UI object that implements the optionpane's LookAndFeel
1836      */
1837     public void setUI(OptionPaneUI ui) {
1838         if (this.ui != ui) {
1839             super.setUI(ui);
1840             invalidate();
1841         }
1842     }
1843 
1844     /**
1845      * Returns the UI object which implements the {@literal L&F} for this component.
1846      *
1847      * @return the <code>OptionPaneUI</code> object
1848      */
1849     public OptionPaneUI getUI() {
1850         return (OptionPaneUI)ui;
1851     }
1852 
1853     /**
1854      * Notification from the <code>UIManager</code> that the {@literal L&F} has changed.
1855      * Replaces the current UI object with the latest version from the
1856      * <code>UIManager</code>.
1857      *
1858      * @see JComponent#updateUI
1859      */
1860     public void updateUI() {
1861         setUI((OptionPaneUI)UIManager.getUI(this));
1862     }
1863 
1864 
1865     /**
1866      * Returns the name of the UI class that implements the
1867      * {@literal L&F} for this component.
1868      *
1869      * @return the string "OptionPaneUI"
1870      * @see JComponent#getUIClassID
1871      * @see UIDefaults#getUI
1872      */
1873     public String getUIClassID() {
1874         return uiClassID;
1875     }
1876 
1877 
1878     /**
1879      * Sets the option pane's message-object.
1880      * @param newMessage the <code>Object</code> to display
1881      * @see #getMessage
1882      *
1883      * @beaninfo
1884      *   preferred: true
1885      *   bound: true
1886      * description: The optionpane's message object.
1887      */
1888     public void setMessage(Object newMessage) {
1889         Object           oldMessage = message;
1890 
1891         message = newMessage;
1892         firePropertyChange(MESSAGE_PROPERTY, oldMessage, message);
1893     }
1894 
1895     /**
1896      * Returns the message-object this pane displays.
1897      * @see #setMessage
1898      *
1899      * @return the <code>Object</code> that is displayed
1900      */
1901     public Object getMessage() {
1902         return message;
1903     }
1904 
1905     /**
1906      * Sets the icon to display. If non-<code>null</code>, the look and feel
1907      * does not provide an icon.
1908      * @param newIcon the <code>Icon</code> to display
1909      *
1910      * @see #getIcon
1911      * @beaninfo
1912      *   preferred: true
1913      *       bound: true
1914      * description: The option pane's type icon.
1915      */
1916     public void setIcon(Icon newIcon) {
1917         Object              oldIcon = icon;
1918 
1919         icon = newIcon;
1920         firePropertyChange(ICON_PROPERTY, oldIcon, icon);
1921     }
1922 
1923     /**
1924      * Returns the icon this pane displays.
1925      * @return the <code>Icon</code> that is displayed
1926      *
1927      * @see #setIcon
1928      */
1929     public Icon getIcon() {
1930         return icon;
1931     }
1932 
1933     /**
1934      * Sets the value the user has chosen.
1935      * @param newValue  the chosen value
1936      *
1937      * @see #getValue
1938      * @beaninfo
1939      *   preferred: true
1940      *       bound: true
1941      * description: The option pane's value object.
1942      */
1943     public void setValue(Object newValue) {
1944         Object               oldValue = value;
1945 
1946         value = newValue;
1947         firePropertyChange(VALUE_PROPERTY, oldValue, value);
1948     }
1949 
1950     /**
1951      * Returns the value the user has selected. <code>UNINITIALIZED_VALUE</code>
1952      * implies the user has not yet made a choice, <code>null</code> means the
1953      * user closed the window with out choosing anything. Otherwise
1954      * the returned value will be one of the options defined in this
1955      * object.
1956      *
1957      * @return the <code>Object</code> chosen by the user,
1958      *         <code>UNINITIALIZED_VALUE</code>
1959      *         if the user has not yet made a choice, or <code>null</code> if
1960      *         the user closed the window without making a choice
1961      *
1962      * @see #setValue
1963      */
1964     public Object getValue() {
1965         return value;
1966     }
1967 
1968     /**
1969      * Sets the options this pane displays. If an element in
1970      * <code>newOptions</code> is a <code>Component</code>
1971      * it is added directly to the pane,
1972      * otherwise a button is created for the element.
1973      *
1974      * @param newOptions an array of <code>Objects</code> that create the
1975      *          buttons the user can click on, or arbitrary
1976      *          <code>Components</code> to add to the pane
1977      *
1978      * @see #getOptions
1979      * @beaninfo
1980      *       bound: true
1981      * description: The option pane's options objects.
1982      */
1983     public void setOptions(Object[] newOptions) {
1984         Object[]           oldOptions = options;
1985 
1986         options = newOptions;
1987         firePropertyChange(OPTIONS_PROPERTY, oldOptions, options);
1988     }
1989 
1990     /**
1991      * Returns the choices the user can make.
1992      * @return the array of <code>Objects</code> that give the user's choices
1993      *
1994      * @see #setOptions
1995      */
1996     public Object[] getOptions() {
1997         if(options != null) {
1998             int             optionCount = options.length;
1999             Object[]        retOptions = new Object[optionCount];
2000 
2001             System.arraycopy(options, 0, retOptions, 0, optionCount);
2002             return retOptions;
2003         }
2004         return options;
2005     }
2006 
2007     /**
2008      * Sets the initial value that is to be enabled -- the
2009      * <code>Component</code>
2010      * that has the focus when the pane is initially displayed.
2011      *
2012      * @param newInitialValue the <code>Object</code> that gets the initial
2013      *                         keyboard focus
2014      *
2015      * @see #getInitialValue
2016      * @beaninfo
2017      *   preferred: true
2018      *       bound: true
2019      * description: The option pane's initial value object.
2020      */
2021     public void setInitialValue(Object newInitialValue) {
2022         Object            oldIV = initialValue;
2023 
2024         initialValue = newInitialValue;
2025         firePropertyChange(INITIAL_VALUE_PROPERTY, oldIV, initialValue);
2026     }
2027 
2028     /**
2029      * Returns the initial value.
2030      *
2031      * @return the <code>Object</code> that gets the initial keyboard focus
2032      *
2033      * @see #setInitialValue
2034      */
2035     public Object getInitialValue() {
2036         return initialValue;
2037     }
2038 
2039     /**
2040      * Sets the option pane's message type.
2041      * The message type is used by the Look and Feel to determine the
2042      * icon to display (if not supplied) as well as potentially how to
2043      * lay out the <code>parentComponent</code>.
2044      * @param newType an integer specifying the kind of message to display:
2045      *                <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
2046      *                <code>WARNING_MESSAGE</code>,
2047      *                <code>QUESTION_MESSAGE</code>, or <code>PLAIN_MESSAGE</code>
2048      * @exception RuntimeException if <code>newType</code> is not one of the
2049      *          legal values listed above
2050 
2051      * @see #getMessageType
2052      * @beaninfo
2053      *   preferred: true
2054      *       bound: true
2055      * description: The option pane's message type.
2056      */
2057     public void setMessageType(int newType) {
2058         if(newType != ERROR_MESSAGE && newType != INFORMATION_MESSAGE &&
2059            newType != WARNING_MESSAGE && newType != QUESTION_MESSAGE &&
2060            newType != PLAIN_MESSAGE)
2061             throw new RuntimeException("JOptionPane: type must be one of JOptionPane.ERROR_MESSAGE, JOptionPane.INFORMATION_MESSAGE, JOptionPane.WARNING_MESSAGE, JOptionPane.QUESTION_MESSAGE or JOptionPane.PLAIN_MESSAGE");
2062 
2063         int           oldType = messageType;
2064 
2065         messageType = newType;
2066         firePropertyChange(MESSAGE_TYPE_PROPERTY, oldType, messageType);
2067     }
2068 
2069     /**
2070      * Returns the message type.
2071      *
2072      * @return an integer specifying the message type
2073      *
2074      * @see #setMessageType
2075      */
2076     public int getMessageType() {
2077         return messageType;
2078     }
2079 
2080     /**
2081      * Sets the options to display.
2082      * The option type is used by the Look and Feel to
2083      * determine what buttons to show (unless options are supplied).
2084      * @param newType an integer specifying the options the {@literal L&F} is to display:
2085      *                  <code>DEFAULT_OPTION</code>,
2086      *                  <code>YES_NO_OPTION</code>,
2087      *                  <code>YES_NO_CANCEL_OPTION</code>,
2088      *                  or <code>OK_CANCEL_OPTION</code>
2089      * @exception RuntimeException if <code>newType</code> is not one of
2090      *          the legal values listed above
2091      *
2092      * @see #getOptionType
2093      * @see #setOptions
2094      * @beaninfo
2095      *   preferred: true
2096      *       bound: true
2097      * description: The option pane's option type.
2098       */
2099     public void setOptionType(int newType) {
2100         if(newType != DEFAULT_OPTION && newType != YES_NO_OPTION &&
2101            newType != YES_NO_CANCEL_OPTION && newType != OK_CANCEL_OPTION)
2102             throw new RuntimeException("JOptionPane: option type must be one of JOptionPane.DEFAULT_OPTION, JOptionPane.YES_NO_OPTION, JOptionPane.YES_NO_CANCEL_OPTION or JOptionPane.OK_CANCEL_OPTION");
2103 
2104         int            oldType = optionType;
2105 
2106         optionType = newType;
2107         firePropertyChange(OPTION_TYPE_PROPERTY, oldType, optionType);
2108     }
2109 
2110     /**
2111      * Returns the type of options that are displayed.
2112      *
2113      * @return an integer specifying the user-selectable options
2114      *
2115      * @see #setOptionType
2116      */
2117     public int getOptionType() {
2118         return optionType;
2119     }
2120 
2121     /**
2122      * Sets the input selection values for a pane that provides the user
2123      * with a list of items to choose from. (The UI provides a widget
2124      * for choosing one of the values.)  A <code>null</code> value
2125      * implies the user can input whatever they wish, usually by means
2126      * of a <code>JTextField</code>.
2127      * <p>
2128      * Sets <code>wantsInput</code> to true. Use
2129      * <code>setInitialSelectionValue</code> to specify the initially-chosen
2130      * value. After the pane as been enabled, <code>inputValue</code> is
2131      * set to the value the user has selected.
2132      * @param newValues an array of <code>Objects</code> the user to be
2133      *                  displayed
2134      *                  (usually in a list or combo-box) from which
2135      *                  the user can make a selection
2136      * @see #setWantsInput
2137      * @see #setInitialSelectionValue
2138      * @see #getSelectionValues
2139      * @beaninfo
2140      *       bound: true
2141      * description: The option pane's selection values.
2142      */
2143     public void setSelectionValues(Object[] newValues) {
2144         Object[]           oldValues = selectionValues;
2145 
2146         selectionValues = newValues;
2147         firePropertyChange(SELECTION_VALUES_PROPERTY, oldValues, newValues);
2148         if(selectionValues != null)
2149             setWantsInput(true);
2150     }
2151 
2152     /**
2153      * Returns the input selection values.
2154      *
2155      * @return the array of <code>Objects</code> the user can select
2156      * @see #setSelectionValues
2157      */
2158     public Object[] getSelectionValues() {
2159         return selectionValues;
2160     }
2161 
2162     /**
2163      * Sets the input value that is initially displayed as selected to the user.
2164      * Only used if <code>wantsInput</code> is true.
2165      * @param newValue the initially selected value
2166      * @see #setSelectionValues
2167      * @see #getInitialSelectionValue
2168      * @beaninfo
2169      *       bound: true
2170      * description: The option pane's initial selection value object.
2171      */
2172     public void setInitialSelectionValue(Object newValue) {
2173         Object          oldValue = initialSelectionValue;
2174 
2175         initialSelectionValue = newValue;
2176         firePropertyChange(INITIAL_SELECTION_VALUE_PROPERTY, oldValue,
2177                            newValue);
2178     }
2179 
2180     /**
2181      * Returns the input value that is displayed as initially selected to the user.
2182      *
2183      * @return the initially selected value
2184      * @see #setInitialSelectionValue
2185      * @see #setSelectionValues
2186      */
2187     public Object getInitialSelectionValue() {
2188         return initialSelectionValue;
2189     }
2190 
2191     /**
2192      * Sets the input value that was selected or input by the user.
2193      * Only used if <code>wantsInput</code> is true.  Note that this method
2194      * is invoked internally by the option pane (in response to user action)
2195      * and should generally not be called by client programs.  To set the
2196      * input value initially displayed as selected to the user, use
2197      * <code>setInitialSelectionValue</code>.
2198      *
2199      * @param newValue the <code>Object</code> used to set the
2200      *          value that the user specified (usually in a text field)
2201      * @see #setSelectionValues
2202      * @see #setInitialSelectionValue
2203      * @see #setWantsInput
2204      * @see #getInputValue
2205      * @beaninfo
2206      *   preferred: true
2207      *       bound: true
2208      * description: The option pane's input value object.
2209      */
2210     public void setInputValue(Object newValue) {
2211         Object              oldValue = inputValue;
2212 
2213         inputValue = newValue;
2214         firePropertyChange(INPUT_VALUE_PROPERTY, oldValue, newValue);
2215     }
2216 
2217     /**
2218      * Returns the value the user has input, if <code>wantsInput</code>
2219      * is true.
2220      *
2221      * @return the <code>Object</code> the user specified,
2222      *          if it was one of the objects, or a
2223      *          <code>String</code> if it was a value typed into a
2224      *          field
2225      * @see #setSelectionValues
2226      * @see #setWantsInput
2227      * @see #setInputValue
2228      */
2229     public Object getInputValue() {
2230         return inputValue;
2231     }
2232 
2233     /**
2234      * Returns the maximum number of characters to place on a line in a
2235      * message. Default is to return <code>Integer.MAX_VALUE</code>.
2236      * The value can be
2237      * changed by overriding this method in a subclass.
2238      *
2239      * @return an integer giving the maximum number of characters on a line
2240      */
2241     public int getMaxCharactersPerLineCount() {
2242         return Integer.MAX_VALUE;
2243     }
2244 
2245     /**
2246      * Sets the <code>wantsInput</code> property.
2247      * If <code>newValue</code> is true, an input component
2248      * (such as a text field or combo box) whose parent is
2249      * <code>parentComponent</code> is provided to
2250      * allow the user to input a value. If <code>getSelectionValues</code>
2251      * returns a non-<code>null</code> array, the input value is one of the
2252      * objects in that array. Otherwise the input value is whatever
2253      * the user inputs.
2254      * <p>
2255      * This is a bound property.
2256      *
2257      * @param newValue if true, an input component whose parent is {@code parentComponent}
2258      *                 is provided to allow the user to input a value.
2259      * @see #setSelectionValues
2260      * @see #setInputValue
2261      * @beaninfo
2262      *   preferred: true
2263      *       bound: true
2264      * description: Flag which allows the user to input a value.
2265      */
2266     public void setWantsInput(boolean newValue) {
2267         boolean            oldValue = wantsInput;
2268 
2269         wantsInput = newValue;
2270         firePropertyChange(WANTS_INPUT_PROPERTY, oldValue, newValue);
2271     }
2272 
2273     /**
2274      * Returns the value of the <code>wantsInput</code> property.
2275      *
2276      * @return true if an input component will be provided
2277      * @see #setWantsInput
2278      */
2279     public boolean getWantsInput() {
2280         return wantsInput;
2281     }
2282 
2283     /**
2284      * Requests that the initial value be selected, which will set
2285      * focus to the initial value. This method
2286      * should be invoked after the window containing the option pane
2287      * is made visible.
2288      */
2289     public void selectInitialValue() {
2290         OptionPaneUI         ui = getUI();
2291         if (ui != null) {
2292             ui.selectInitialValue(this);
2293         }
2294     }
2295 
2296 
2297     private static int styleFromMessageType(int messageType) {
2298         switch (messageType) {
2299         case ERROR_MESSAGE:
2300             return JRootPane.ERROR_DIALOG;
2301         case QUESTION_MESSAGE:
2302             return JRootPane.QUESTION_DIALOG;
2303         case WARNING_MESSAGE:
2304             return JRootPane.WARNING_DIALOG;
2305         case INFORMATION_MESSAGE:
2306             return JRootPane.INFORMATION_DIALOG;
2307         case PLAIN_MESSAGE:
2308         default:
2309             return JRootPane.PLAIN_DIALOG;
2310         }
2311     }
2312 
2313     // Serialization support.
2314     private void writeObject(ObjectOutputStream s) throws IOException {
2315         Vector<Object> values = new Vector<Object>();
2316 
2317         s.defaultWriteObject();
2318         // Save the icon, if its Serializable.
2319         if(icon != null && icon instanceof Serializable) {
2320             values.addElement("icon");
2321             values.addElement(icon);
2322         }
2323         // Save the message, if its Serializable.
2324         if(message != null && message instanceof Serializable) {
2325             values.addElement("message");
2326             values.addElement(message);
2327         }
2328         // Save the treeModel, if its Serializable.
2329         if(options != null) {
2330             Vector<Object> serOptions = new Vector<Object>();
2331 
2332             for(int counter = 0, maxCounter = options.length;
2333                 counter < maxCounter; counter++)
2334                 if(options[counter] instanceof Serializable)
2335                     serOptions.addElement(options[counter]);
2336             if(serOptions.size() > 0) {
2337                 int             optionCount = serOptions.size();
2338                 Object[]        arrayOptions = new Object[optionCount];
2339 
2340                 serOptions.copyInto(arrayOptions);
2341                 values.addElement("options");
2342                 values.addElement(arrayOptions);
2343             }
2344         }
2345         // Save the initialValue, if its Serializable.
2346         if(initialValue != null && initialValue instanceof Serializable) {
2347             values.addElement("initialValue");
2348             values.addElement(initialValue);
2349         }
2350         // Save the value, if its Serializable.
2351         if(value != null && value instanceof Serializable) {
2352             values.addElement("value");
2353             values.addElement(value);
2354         }
2355         // Save the selectionValues, if its Serializable.
2356         if(selectionValues != null) {
2357             boolean            serialize = true;
2358 
2359             for(int counter = 0, maxCounter = selectionValues.length;
2360                 counter < maxCounter; counter++) {
2361                 if(selectionValues[counter] != null &&
2362                    !(selectionValues[counter] instanceof Serializable)) {
2363                     serialize = false;
2364                     break;
2365                 }
2366             }
2367             if(serialize) {
2368                 values.addElement("selectionValues");
2369                 values.addElement(selectionValues);
2370             }
2371         }
2372         // Save the inputValue, if its Serializable.
2373         if(inputValue != null && inputValue instanceof Serializable) {
2374             values.addElement("inputValue");
2375             values.addElement(inputValue);
2376         }
2377         // Save the initialSelectionValue, if its Serializable.
2378         if(initialSelectionValue != null &&
2379            initialSelectionValue instanceof Serializable) {
2380             values.addElement("initialSelectionValue");
2381             values.addElement(initialSelectionValue);
2382         }
2383         s.writeObject(values);
2384     }
2385 
2386     private void readObject(ObjectInputStream s)
2387         throws IOException, ClassNotFoundException {
2388         s.defaultReadObject();
2389 
2390         Vector<?>       values = (Vector)s.readObject();
2391         int             indexCounter = 0;
2392         int             maxCounter = values.size();
2393 
2394         if(indexCounter < maxCounter && values.elementAt(indexCounter).
2395            equals("icon")) {
2396             icon = (Icon)values.elementAt(++indexCounter);
2397             indexCounter++;
2398         }
2399         if(indexCounter < maxCounter && values.elementAt(indexCounter).
2400            equals("message")) {
2401             message = values.elementAt(++indexCounter);
2402             indexCounter++;
2403         }
2404         if(indexCounter < maxCounter && values.elementAt(indexCounter).
2405            equals("options")) {
2406             options = (Object[])values.elementAt(++indexCounter);
2407             indexCounter++;
2408         }
2409         if(indexCounter < maxCounter && values.elementAt(indexCounter).
2410            equals("initialValue")) {
2411             initialValue = values.elementAt(++indexCounter);
2412             indexCounter++;
2413         }
2414         if(indexCounter < maxCounter && values.elementAt(indexCounter).
2415            equals("value")) {
2416             value = values.elementAt(++indexCounter);
2417             indexCounter++;
2418         }
2419         if(indexCounter < maxCounter && values.elementAt(indexCounter).
2420            equals("selectionValues")) {
2421             selectionValues = (Object[])values.elementAt(++indexCounter);
2422             indexCounter++;
2423         }
2424         if(indexCounter < maxCounter && values.elementAt(indexCounter).
2425            equals("inputValue")) {
2426             inputValue = values.elementAt(++indexCounter);
2427             indexCounter++;
2428         }
2429         if(indexCounter < maxCounter && values.elementAt(indexCounter).
2430            equals("initialSelectionValue")) {
2431             initialSelectionValue = values.elementAt(++indexCounter);
2432             indexCounter++;
2433         }
2434         if (getUIClassID().equals(uiClassID)) {
2435             byte count = JComponent.getWriteObjCounter(this);
2436             JComponent.setWriteObjCounter(this, --count);
2437             if (count == 0 && ui != null) {
2438                 ui.installUI(this);
2439             }
2440         }
2441     }
2442 
2443 
2444     /**
2445      * Returns a string representation of this <code>JOptionPane</code>.
2446      * This method
2447      * is intended to be used only for debugging purposes, and the
2448      * content and format of the returned string may vary between
2449      * implementations. The returned string may be empty but may not
2450      * be <code>null</code>.
2451      *
2452      * @return  a string representation of this <code>JOptionPane</code>
2453      */
2454     protected String paramString() {
2455         String iconString = (icon != null ?
2456                              icon.toString() : "");
2457         String initialValueString = (initialValue != null ?
2458                                      initialValue.toString() : "");
2459         String messageString = (message != null ?
2460                                 message.toString() : "");
2461         String messageTypeString;
2462         if (messageType == ERROR_MESSAGE) {
2463             messageTypeString = "ERROR_MESSAGE";
2464         } else if (messageType == INFORMATION_MESSAGE) {
2465             messageTypeString = "INFORMATION_MESSAGE";
2466         } else if (messageType == WARNING_MESSAGE) {
2467             messageTypeString = "WARNING_MESSAGE";
2468         } else if (messageType == QUESTION_MESSAGE) {
2469             messageTypeString = "QUESTION_MESSAGE";
2470         } else if (messageType == PLAIN_MESSAGE)  {
2471             messageTypeString = "PLAIN_MESSAGE";
2472         } else messageTypeString = "";
2473         String optionTypeString;
2474         if (optionType == DEFAULT_OPTION) {
2475             optionTypeString = "DEFAULT_OPTION";
2476         } else if (optionType == YES_NO_OPTION) {
2477             optionTypeString = "YES_NO_OPTION";
2478         } else if (optionType == YES_NO_CANCEL_OPTION) {
2479             optionTypeString = "YES_NO_CANCEL_OPTION";
2480         } else if (optionType == OK_CANCEL_OPTION) {
2481             optionTypeString = "OK_CANCEL_OPTION";
2482         } else optionTypeString = "";
2483         String wantsInputString = (wantsInput ?
2484                                    "true" : "false");
2485 
2486         return super.paramString() +
2487         ",icon=" + iconString +
2488         ",initialValue=" + initialValueString +
2489         ",message=" + messageString +
2490         ",messageType=" + messageTypeString +
2491         ",optionType=" + optionTypeString +
2492         ",wantsInput=" + wantsInputString;
2493     }
2494 
2495 ///////////////////
2496 // Accessibility support
2497 ///////////////////
2498 
2499     /**
2500      * Returns the <code>AccessibleContext</code> associated with this JOptionPane.
2501      * For option panes, the <code>AccessibleContext</code> takes the form of an
2502      * <code>AccessibleJOptionPane</code>.
2503      * A new <code>AccessibleJOptionPane</code> instance is created if necessary.
2504      *
2505      * @return an AccessibleJOptionPane that serves as the
2506      *         AccessibleContext of this AccessibleJOptionPane
2507      * @beaninfo
2508      *       expert: true
2509      *  description: The AccessibleContext associated with this option pane
2510      */
2511     public AccessibleContext getAccessibleContext() {
2512         if (accessibleContext == null) {
2513             accessibleContext = new AccessibleJOptionPane();
2514         }
2515         return accessibleContext;
2516     }
2517 
2518     /**
2519      * This class implements accessibility support for the
2520      * <code>JOptionPane</code> class.  It provides an implementation of the
2521      * Java Accessibility API appropriate to option pane user-interface
2522      * elements.
2523      * <p>
2524      * <strong>Warning:</strong>
2525      * Serialized objects of this class will not be compatible with
2526      * future Swing releases. The current serialization support is
2527      * appropriate for short term storage or RMI between applications running
2528      * the same version of Swing.  As of 1.4, support for long term storage
2529      * of all JavaBeans&trade;
2530      * has been added to the <code>java.beans</code> package.
2531      * Please see {@link java.beans.XMLEncoder}.
2532      */
2533     @SuppressWarnings("serial") // Same-version serialization only
2534     protected class AccessibleJOptionPane extends AccessibleJComponent {
2535 
2536         /**
2537          * Get the role of this object.
2538          *
2539          * @return an instance of AccessibleRole describing the role of the object
2540          * @see AccessibleRole
2541          */
2542         public AccessibleRole getAccessibleRole() {
2543             switch (messageType) {
2544             case ERROR_MESSAGE:
2545             case INFORMATION_MESSAGE:
2546             case WARNING_MESSAGE:
2547                 return AccessibleRole.ALERT;
2548 
2549             default:
2550                 return AccessibleRole.OPTION_PANE;
2551             }
2552         }
2553 
2554     } // inner class AccessibleJOptionPane
2555 }