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