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