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