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