0001 /*
0002 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package javax.swing;
0027
0028 import java.awt.BorderLayout;
0029 import java.awt.Component;
0030 import java.awt.Container;
0031 import java.awt.Dialog;
0032 import java.awt.Dimension;
0033 import java.awt.KeyboardFocusManager;
0034 import java.awt.Frame;
0035 import java.awt.Point;
0036 import java.awt.HeadlessException;
0037 import java.awt.Toolkit;
0038 import java.awt.Window;
0039 import java.beans.PropertyChangeEvent;
0040 import java.beans.PropertyChangeListener;
0041 import java.awt.event.WindowListener;
0042 import java.awt.event.WindowAdapter;
0043 import java.awt.event.WindowEvent;
0044 import java.awt.event.ComponentAdapter;
0045 import java.awt.event.ComponentEvent;
0046 import java.io.IOException;
0047 import java.io.ObjectInputStream;
0048 import java.io.ObjectOutputStream;
0049 import java.io.Serializable;
0050 import java.lang.reflect.Method;
0051 import java.lang.reflect.InvocationTargetException;
0052 import java.security.AccessController;
0053 import java.security.PrivilegedAction;
0054 import java.util.Vector;
0055 import javax.swing.plaf.OptionPaneUI;
0056 import javax.swing.event.InternalFrameEvent;
0057 import javax.swing.event.InternalFrameAdapter;
0058 import javax.accessibility.*;
0059 import static javax.swing.ClientPropertyKey.PopupFactory_FORCE_HEAVYWEIGHT_POPUP;
0060
0061 /**
0062 * <code>JOptionPane</code> makes it easy to pop up a standard dialog box that
0063 * prompts users for a value or informs them of something.
0064 * For information about using <code>JOptionPane</code>, see
0065 * <a
0066 href="http://java.sun.com/docs/books/tutorial/uiswing/components/dialog.html">How to Make Dialogs</a>,
0067 * a section in <em>The Java Tutorial</em>.
0068 *
0069 * <p>
0070 *
0071 * While the <code>JOptionPane</code>
0072 * class may appear complex because of the large number of methods, almost
0073 * all uses of this class are one-line calls to one of the static
0074 * <code>showXxxDialog</code> methods shown below:
0075 * <blockquote>
0076 *
0077 *
0078 * <table border=1 summary="Common JOptionPane method names and their descriptions">
0079 * <tr>
0080 * <th>Method Name</th>
0081 * <th>Description</th>
0082 * </tr>
0083 * <tr>
0084 * <td>showConfirmDialog</td>
0085 * <td>Asks a confirming question, like yes/no/cancel.</td>
0086 * </tr>
0087 * <tr>
0088 * <td>showInputDialog</td>
0089 * <td>Prompt for some input.</td>
0090 * </tr>
0091 * <tr>
0092 * <td>showMessageDialog</td>
0093 * <td>Tell the user about something that has happened.</td>
0094 * </tr>
0095 * <tr>
0096 * <td>showOptionDialog</td>
0097 * <td>The Grand Unification of the above three.</td>
0098 * </tr>
0099 * </table>
0100 *
0101 * </blockquote>
0102 * Each of these methods also comes in a <code>showInternalXXX</code>
0103 * flavor, which uses an internal frame to hold the dialog box (see
0104 * {@link JInternalFrame}).
0105 * Multiple convenience methods have also been defined -- overloaded
0106 * versions of the basic methods that use different parameter lists.
0107 * <p>
0108 * All dialogs are modal. Each <code>showXxxDialog</code> method blocks
0109 * the caller until the user's interaction is complete.
0110 * <p>
0111 *
0112 * <table cellspacing=6 cellpadding=4 border=0 align=right summary="layout">
0113 * <tr>
0114 * <td bgcolor=#FFe0d0 rowspan=2>icon</td>
0115 * <td bgcolor=#FFe0d0>message</td>
0116 * </tr>
0117 * <tr>
0118 * <td bgcolor=#FFe0d0>input value</td>
0119 * </tr>
0120 * <tr>
0121 * <td bgcolor=#FFe0d0 colspan=2>option buttons</td>
0122 * </tr>
0123 * </table>
0124 *
0125 * The basic appearance of one of these dialog boxes is generally
0126 * similar to the picture at the right, although the various
0127 * look-and-feels are
0128 * ultimately responsible for the final result. In particular, the
0129 * look-and-feels will adjust the layout to accommodate the option pane's
0130 * <code>ComponentOrientation</code> property.
0131 * <br clear=all>
0132 * <p>
0133 * <b>Parameters:</b><br>
0134 * The parameters to these methods follow consistent patterns:
0135 * <blockquote>
0136 * <dl compact>
0137 * <dt>parentComponent<dd>
0138 * Defines the <code>Component</code> that is to be the parent of this
0139 * dialog box.
0140 * It is used in two ways: the <code>Frame</code> that contains
0141 * it is used as the <code>Frame</code>
0142 * parent for the dialog box, and its screen coordinates are used in
0143 * the placement of the dialog box. In general, the dialog box is placed
0144 * just below the component. This parameter may be <code>null</code>,
0145 * in which case a default <code>Frame</code> is used as the parent,
0146 * and the dialog will be
0147 * centered on the screen (depending on the L&F).
0148 * <dt><a name=message>message</a><dd>
0149 * A descriptive message to be placed in the dialog box.
0150 * In the most common usage, message is just a <code>String</code> or
0151 * <code>String</code> constant.
0152 * However, the type of this parameter is actually <code>Object</code>. Its
0153 * interpretation depends on its type:
0154 * <dl compact>
0155 * <dt>Object[]<dd>An array of objects is interpreted as a series of
0156 * messages (one per object) arranged in a vertical stack.
0157 * The interpretation is recursive -- each object in the
0158 * array is interpreted according to its type.
0159 * <dt>Component<dd>The <code>Component</code> is displayed in the dialog.
0160 * <dt>Icon<dd>The <code>Icon</code> is wrapped in a <code>JLabel</code>
0161 * and displayed in the dialog.
0162 * <dt>others<dd>The object is converted to a <code>String</code> by calling
0163 * its <code>toString</code> method. The result is wrapped in a
0164 * <code>JLabel</code> and displayed.
0165 * </dl>
0166 * <dt>messageType<dd>Defines the style of the message. The Look and Feel
0167 * manager may lay out the dialog differently depending on this value, and
0168 * will often provide a default icon. The possible values are:
0169 * <ul>
0170 * <li><code>ERROR_MESSAGE</code>
0171 * <li><code>INFORMATION_MESSAGE</code>
0172 * <li><code>WARNING_MESSAGE</code>
0173 * <li><code>QUESTION_MESSAGE</code>
0174 * <li><code>PLAIN_MESSAGE</code>
0175 * </ul>
0176 * <dt>optionType<dd>Defines the set of option buttons that appear at
0177 * the bottom of the dialog box:
0178 * <ul>
0179 * <li><code>DEFAULT_OPTION</code>
0180 * <li><code>YES_NO_OPTION</code>
0181 * <li><code>YES_NO_CANCEL_OPTION</code>
0182 * <li><code>OK_CANCEL_OPTION</code>
0183 * </ul>
0184 * You aren't limited to this set of option buttons. You can provide any
0185 * buttons you want using the options parameter.
0186 * <dt>options<dd>A more detailed description of the set of option buttons
0187 * that will appear at the bottom of the dialog box.
0188 * The usual value for the options parameter is an array of
0189 * <code>String</code>s. But
0190 * the parameter type is an array of <code>Objects</code>.
0191 * A button is created for each object depending on its type:
0192 * <dl compact>
0193 * <dt>Component<dd>The component is added to the button row directly.
0194 * <dt>Icon<dd>A <code>JButton</code> is created with this as its label.
0195 * <dt>other<dd>The <code>Object</code> is converted to a string using its
0196 * <code>toString</code> method and the result is used to
0197 * label a <code>JButton</code>.
0198 * </dl>
0199 * <dt>icon<dd>A decorative icon to be placed in the dialog box. A default
0200 * value for this is determined by the <code>messageType</code> parameter.
0201 * <dt>title<dd>The title for the dialog box.
0202 * <dt>initialValue<dd>The default selection (input value).
0203 * </dl>
0204 * </blockquote>
0205 * <p>
0206 * When the selection is changed, <code>setValue</code> is invoked,
0207 * which generates a <code>PropertyChangeEvent</code>.
0208 * <p>
0209 * If a <code>JOptionPane</code> has configured to all input
0210 * <code>setWantsInput</code>
0211 * the bound property <code>JOptionPane.INPUT_VALUE_PROPERTY</code>
0212 * can also be listened
0213 * to, to determine when the user has input or selected a value.
0214 * <p>
0215 * When one of the <code>showXxxDialog</code> methods returns an integer,
0216 * the possible values are:
0217 * <ul>
0218 * <li><code>YES_OPTION</code>
0219 * <li><code>NO_OPTION</code>
0220 * <li><code>CANCEL_OPTION</code>
0221 * <li><code>OK_OPTION</code>
0222 * <li><code>CLOSED_OPTION</code>
0223 * </ul>
0224 * <b>Examples:</b>
0225 * <dl>
0226 * <dt>Show an error dialog that displays the message, 'alert':
0227 * <dd><code>
0228 * JOptionPane.showMessageDialog(null, "alert", "alert", JOptionPane.ERROR_MESSAGE);
0229 * </code><p>
0230 * <dt>Show an internal information dialog with the message, 'information':
0231 * <dd><code>
0232 * JOptionPane.showInternalMessageDialog(frame, "information",<br>
0233 * <ul><ul>"information", JOptionPane.INFORMATION_MESSAGE);</ul></ul>
0234 * </code><p>
0235 * <dt>Show an information panel with the options yes/no and message 'choose one':
0236 * <dd><code>JOptionPane.showConfirmDialog(null,
0237 * <ul><ul>"choose one", "choose one", JOptionPane.YES_NO_OPTION);</ul></ul>
0238 * </code><p>
0239 * <dt>Show an internal information dialog with the options yes/no/cancel and
0240 * message 'please choose one' and title information:
0241 * <dd><code>JOptionPane.showInternalConfirmDialog(frame,
0242 * <ul><ul>"please choose one", "information",</ul></ul>
0243 * <ul><ul>JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);</ul></ul>
0244 * </code><p>
0245 * <dt>Show a warning dialog with the options OK, CANCEL, title 'Warning', and
0246 * message 'Click OK to continue':
0247 * <dd><code>
0248 * Object[] options = { "OK", "CANCEL" };<br>
0249 * JOptionPane.showOptionDialog(null, "Click OK to continue", "Warning",
0250 * <ul><ul>JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,</ul></ul>
0251 * <ul><ul>null, options, options[0]);</ul></ul>
0252 * </code><p>
0253 * <dt>Show a dialog asking the user to type in a String:
0254 * <dd><code>
0255 * String inputValue = JOptionPane.showInputDialog("Please input a value");
0256 * </code><p>
0257 * <dt>Show a dialog asking the user to select a String:
0258 * <dd><code>
0259 * Object[] possibleValues = { "First", "Second", "Third" };<br>
0260 * Object selectedValue = JOptionPane.showInputDialog(null,
0261 * <ul><ul>"Choose one", "Input",</ul></ul>
0262 * <ul><ul>JOptionPane.INFORMATION_MESSAGE, null,</ul></ul>
0263 * <ul><ul>possibleValues, possibleValues[0]);</ul></ul>
0264 * </code><p>
0265 * </dl>
0266 * <b>Direct Use:</b><br>
0267 * To create and use an <code>JOptionPane</code> directly, the
0268 * standard pattern is roughly as follows:
0269 * <pre>
0270 * JOptionPane pane = new JOptionPane(<i>arguments</i>);
0271 * pane.set<i>.Xxxx(...); // Configure</i>
0272 * JDialog dialog = pane.createDialog(<i>parentComponent, title</i>);
0273 * dialog.show();
0274 * Object selectedValue = pane.getValue();
0275 * if(selectedValue == null)
0276 * return CLOSED_OPTION;
0277 * <i>//If there is <b>not</b> an array of option buttons:</i>
0278 * if(options == null) {
0279 * if(selectedValue instanceof Integer)
0280 * return ((Integer)selectedValue).intValue();
0281 * return CLOSED_OPTION;
0282 * }
0283 * <i>//If there is an array of option buttons:</i>
0284 * for(int counter = 0, maxCounter = options.length;
0285 * counter < maxCounter; counter++) {
0286 * if(options[counter].equals(selectedValue))
0287 * return counter;
0288 * }
0289 * return CLOSED_OPTION;
0290 * </pre>
0291 * <p>
0292 * <strong>Warning:</strong> Swing is not thread safe. For more
0293 * information see <a
0294 * href="package-summary.html#threading">Swing's Threading
0295 * Policy</a>.
0296 * <p>
0297 * <strong>Warning:</strong>
0298 * Serialized objects of this class will not be compatible with
0299 * future Swing releases. The current serialization support is
0300 * appropriate for short term storage or RMI between applications running
0301 * the same version of Swing. As of 1.4, support for long term storage
0302 * of all JavaBeans<sup><font size="-2">TM</font></sup>
0303 * has been added to the <code>java.beans</code> package.
0304 * Please see {@link java.beans.XMLEncoder}.
0305 *
0306 * @see JInternalFrame
0307 *
0308 * @beaninfo
0309 * attribute: isContainer true
0310 * description: A component which implements standard dialog box controls.
0311 *
0312 * @version 1.108 05/05/07
0313 * @author James Gosling
0314 * @author Scott Violet
0315 */
0316 public class JOptionPane extends JComponent implements Accessible {
0317 /**
0318 * @see #getUIClassID
0319 * @see #readObject
0320 */
0321 private static final String uiClassID = "OptionPaneUI";
0322
0323 /**
0324 * Indicates that the user has not yet selected a value.
0325 */
0326 public static final Object UNINITIALIZED_VALUE = "uninitializedValue";
0327
0328 //
0329 // Option types
0330 //
0331
0332 /**
0333 * Type meaning Look and Feel should not supply any options -- only
0334 * use the options from the <code>JOptionPane</code>.
0335 */
0336 public static final int DEFAULT_OPTION = -1;
0337 /** Type used for <code>showConfirmDialog</code>. */
0338 public static final int YES_NO_OPTION = 0;
0339 /** Type used for <code>showConfirmDialog</code>. */
0340 public static final int YES_NO_CANCEL_OPTION = 1;
0341 /** Type used for <code>showConfirmDialog</code>. */
0342 public static final int OK_CANCEL_OPTION = 2;
0343
0344 //
0345 // Return values.
0346 //
0347 /** Return value from class method if YES is chosen. */
0348 public static final int YES_OPTION = 0;
0349 /** Return value from class method if NO is chosen. */
0350 public static final int NO_OPTION = 1;
0351 /** Return value from class method if CANCEL is chosen. */
0352 public static final int CANCEL_OPTION = 2;
0353 /** Return value form class method if OK is chosen. */
0354 public static final int OK_OPTION = 0;
0355 /** Return value from class method if user closes window without selecting
0356 * anything, more than likely this should be treated as either a
0357 * <code>CANCEL_OPTION</code> or <code>NO_OPTION</code>. */
0358 public static final int CLOSED_OPTION = -1;
0359
0360 //
0361 // Message types. Used by the UI to determine what icon to display,
0362 // and possibly what behavior to give based on the type.
0363 //
0364 /** Used for error messages. */
0365 public static final int ERROR_MESSAGE = 0;
0366 /** Used for information messages. */
0367 public static final int INFORMATION_MESSAGE = 1;
0368 /** Used for warning messages. */
0369 public static final int WARNING_MESSAGE = 2;
0370 /** Used for questions. */
0371 public static final int QUESTION_MESSAGE = 3;
0372 /** No icon is used. */
0373 public static final int PLAIN_MESSAGE = -1;
0374
0375 /** Bound property name for <code>icon</code>. */
0376 public static final String ICON_PROPERTY = "icon";
0377 /** Bound property name for <code>message</code>. */
0378 public static final String MESSAGE_PROPERTY = "message";
0379 /** Bound property name for <code>value</code>. */
0380 public static final String VALUE_PROPERTY = "value";
0381 /** Bound property name for <code>option</code>. */
0382 public static final String OPTIONS_PROPERTY = "options";
0383 /** Bound property name for <code>initialValue</code>. */
0384 public static final String INITIAL_VALUE_PROPERTY = "initialValue";
0385 /** Bound property name for <code>type</code>. */
0386 public static final String MESSAGE_TYPE_PROPERTY = "messageType";
0387 /** Bound property name for <code>optionType</code>. */
0388 public static final String OPTION_TYPE_PROPERTY = "optionType";
0389 /** Bound property name for <code>selectionValues</code>. */
0390 public static final String SELECTION_VALUES_PROPERTY = "selectionValues";
0391 /** Bound property name for <code>initialSelectionValue</code>. */
0392 public static final String INITIAL_SELECTION_VALUE_PROPERTY = "initialSelectionValue";
0393 /** Bound property name for <code>inputValue</code>. */
0394 public static final String INPUT_VALUE_PROPERTY = "inputValue";
0395 /** Bound property name for <code>wantsInput</code>. */
0396 public static final String WANTS_INPUT_PROPERTY = "wantsInput";
0397
0398 /** Icon used in pane. */
0399 transient protected Icon icon;
0400 /** Message to display. */
0401 transient protected Object message;
0402 /** Options to display to the user. */
0403 transient protected Object[] options;
0404 /** Value that should be initially selected in <code>options</code>. */
0405 transient protected Object initialValue;
0406 /** Message type. */
0407 protected int messageType;
0408 /**
0409 * Option type, one of <code>DEFAULT_OPTION</code>,
0410 * <code>YES_NO_OPTION</code>,
0411 * <code>YES_NO_CANCEL_OPTION</code> or
0412 * <code>OK_CANCEL_OPTION</code>.
0413 */
0414 protected int optionType;
0415 /** Currently selected value, will be a valid option, or
0416 * <code>UNINITIALIZED_VALUE</code> or <code>null</code>. */
0417 transient protected Object value;
0418 /** Array of values the user can choose from. Look and feel will
0419 * provide the UI component to choose this from. */
0420 protected transient Object[] selectionValues;
0421 /** Value the user has input. */
0422 protected transient Object inputValue;
0423 /** Initial value to select in <code>selectionValues</code>. */
0424 protected transient Object initialSelectionValue;
0425 /** If true, a UI widget will be provided to the user to get input. */
0426 protected boolean wantsInput;
0427
0428 /**
0429 * Shows a question-message dialog requesting input from the user. The
0430 * dialog uses the default frame, which usually means it is centered on
0431 * the screen.
0432 *
0433 * @param message the <code>Object</code> to display
0434 * @exception HeadlessException if
0435 * <code>GraphicsEnvironment.isHeadless</code> returns
0436 * <code>true</code>
0437 * @see java.awt.GraphicsEnvironment#isHeadless
0438 */
0439 public static String showInputDialog(Object message)
0440 throws HeadlessException {
0441 return showInputDialog(null, message);
0442 }
0443
0444 /**
0445 * Shows a question-message dialog requesting input from the user, with
0446 * the input value initialized to <code>initialSelectionValue</code>. The
0447 * dialog uses the default frame, which usually means it is centered on
0448 * the screen.
0449 *
0450 * @param message the <code>Object</code> to display
0451 * @param initialSelectionValue the value used to initialize the input
0452 * field
0453 * @since 1.4
0454 */
0455 public static String showInputDialog(Object message,
0456 Object initialSelectionValue) {
0457 return showInputDialog(null, message, initialSelectionValue);
0458 }
0459
0460 /**
0461 * Shows a question-message dialog requesting input from the user
0462 * parented to <code>parentComponent</code>.
0463 * The dialog is displayed on top of the <code>Component</code>'s
0464 * frame, and is usually positioned below the <code>Component</code>.
0465 *
0466 * @param parentComponent the parent <code>Component</code> for the
0467 * dialog
0468 * @param message the <code>Object</code> to display
0469 * @exception HeadlessException if
0470 * <code>GraphicsEnvironment.isHeadless</code> returns
0471 * <code>true</code>
0472 * @see java.awt.GraphicsEnvironment#isHeadless
0473 */
0474 public static String showInputDialog(Component parentComponent,
0475 Object message) throws HeadlessException {
0476 return showInputDialog(parentComponent, message, UIManager
0477 .getString("OptionPane.inputDialogTitle",
0478 parentComponent), QUESTION_MESSAGE);
0479 }
0480
0481 /**
0482 * Shows a question-message dialog requesting input from the user and
0483 * parented to <code>parentComponent</code>. The input value will be
0484 * initialized to <code>initialSelectionValue</code>.
0485 * The dialog is displayed on top of the <code>Component</code>'s
0486 * frame, and is usually positioned below the <code>Component</code>.
0487 *
0488 * @param parentComponent the parent <code>Component</code> for the
0489 * dialog
0490 * @param message the <code>Object</code> to display
0491 * @param initialSelectionValue the value used to initialize the input
0492 * field
0493 * @since 1.4
0494 */
0495 public static String showInputDialog(Component parentComponent,
0496 Object message, Object initialSelectionValue) {
0497 return (String) showInputDialog(parentComponent, message,
0498 UIManager.getString("OptionPane.inputDialogTitle",
0499 parentComponent), QUESTION_MESSAGE, null, null,
0500 initialSelectionValue);
0501 }
0502
0503 /**
0504 * Shows a dialog requesting input from the user parented to
0505 * <code>parentComponent</code> with the dialog having the title
0506 * <code>title</code> and message type <code>messageType</code>.
0507 *
0508 * @param parentComponent the parent <code>Component</code> for the
0509 * dialog
0510 * @param message the <code>Object</code> to display
0511 * @param title the <code>String</code> to display in the dialog
0512 * title bar
0513 * @param messageType the type of message that is to be displayed:
0514 * <code>ERROR_MESSAGE</code>,
0515 * <code>INFORMATION_MESSAGE</code>,
0516 * <code>WARNING_MESSAGE</code>,
0517 * <code>QUESTION_MESSAGE</code>,
0518 * or <code>PLAIN_MESSAGE</code>
0519 * @exception HeadlessException if
0520 * <code>GraphicsEnvironment.isHeadless</code> returns
0521 * <code>true</code>
0522 * @see java.awt.GraphicsEnvironment#isHeadless
0523 */
0524 public static String showInputDialog(Component parentComponent,
0525 Object message, String title, int messageType)
0526 throws HeadlessException {
0527 return (String) showInputDialog(parentComponent, message,
0528 title, messageType, null, null, null);
0529 }
0530
0531 /**
0532 * Prompts the user for input in a blocking dialog where the
0533 * initial selection, possible selections, and all other options can
0534 * be specified. The user will able to choose from
0535 * <code>selectionValues</code>, where <code>null</code> implies the
0536 * user can input
0537 * whatever they wish, usually by means of a <code>JTextField</code>.
0538 * <code>initialSelectionValue</code> is the initial value to prompt
0539 * the user with. It is up to the UI to decide how best to represent
0540 * the <code>selectionValues</code>, but usually a
0541 * <code>JComboBox</code>, <code>JList</code>, or
0542 * <code>JTextField</code> will be used.
0543 *
0544 * @param parentComponent the parent <code>Component</code> for the
0545 * dialog
0546 * @param message the <code>Object</code> to display
0547 * @param title the <code>String</code> to display in the
0548 * dialog title bar
0549 * @param messageType the type of message to be displayed:
0550 * <code>ERROR_MESSAGE</code>,
0551 * <code>INFORMATION_MESSAGE</code>,
0552 * <code>WARNING_MESSAGE</code>,
0553 * <code>QUESTION_MESSAGE</code>,
0554 * or <code>PLAIN_MESSAGE</code>
0555 * @param icon the <code>Icon</code> image to display
0556 * @param selectionValues an array of <code>Object</code>s that
0557 * gives the possible selections
0558 * @param initialSelectionValue the value used to initialize the input
0559 * field
0560 * @return user's input, or <code>null</code> meaning the user
0561 * canceled the input
0562 * @exception HeadlessException if
0563 * <code>GraphicsEnvironment.isHeadless</code> returns
0564 * <code>true</code>
0565 * @see java.awt.GraphicsEnvironment#isHeadless
0566 */
0567 public static Object showInputDialog(Component parentComponent,
0568 Object message, String title, int messageType, Icon icon,
0569 Object[] selectionValues, Object initialSelectionValue)
0570 throws HeadlessException {
0571 JOptionPane pane = new JOptionPane(message, messageType,
0572 OK_CANCEL_OPTION, icon, null, null);
0573
0574 pane.setWantsInput(true);
0575 pane.setSelectionValues(selectionValues);
0576 pane.setInitialSelectionValue(initialSelectionValue);
0577 pane
0578 .setComponentOrientation(((parentComponent == null) ? getRootFrame()
0579 : parentComponent).getComponentOrientation());
0580
0581 int style = styleFromMessageType(messageType);
0582 JDialog dialog = pane.createDialog(parentComponent, title,
0583 style);
0584
0585 pane.selectInitialValue();
0586 dialog.show();
0587 dialog.dispose();
0588
0589 Object value = pane.getInputValue();
0590
0591 if (value == UNINITIALIZED_VALUE) {
0592 return null;
0593 }
0594 return value;
0595 }
0596
0597 /**
0598 * Brings up an information-message dialog titled "Message".
0599 *
0600 * @param parentComponent determines the <code>Frame</code> in
0601 * which the dialog is displayed; if <code>null</code>,
0602 * or if the <code>parentComponent</code> has no
0603 * <code>Frame</code>, a default <code>Frame</code> is used
0604 * @param message the <code>Object</code> to display
0605 * @exception HeadlessException if
0606 * <code>GraphicsEnvironment.isHeadless</code> returns
0607 * <code>true</code>
0608 * @see java.awt.GraphicsEnvironment#isHeadless
0609 */
0610 public static void showMessageDialog(Component parentComponent,
0611 Object message) throws HeadlessException {
0612 showMessageDialog(parentComponent, message, UIManager
0613 .getString("OptionPane.messageDialogTitle",
0614 parentComponent), INFORMATION_MESSAGE);
0615 }
0616
0617 /**
0618 * Brings up a dialog that displays a message using a default
0619 * icon determined by the <code>messageType</code> parameter.
0620 *
0621 * @param parentComponent determines the <code>Frame</code>
0622 * in which the dialog is displayed; if <code>null</code>,
0623 * or if the <code>parentComponent</code> has no
0624 * <code>Frame</code>, a default <code>Frame</code> is used
0625 * @param message the <code>Object</code> to display
0626 * @param title the title string for the dialog
0627 * @param messageType the type of message to be displayed:
0628 * <code>ERROR_MESSAGE</code>,
0629 * <code>INFORMATION_MESSAGE</code>,
0630 * <code>WARNING_MESSAGE</code>,
0631 * <code>QUESTION_MESSAGE</code>,
0632 * or <code>PLAIN_MESSAGE</code>
0633 * @exception HeadlessException if
0634 * <code>GraphicsEnvironment.isHeadless</code> returns
0635 * <code>true</code>
0636 * @see java.awt.GraphicsEnvironment#isHeadless
0637 */
0638 public static void showMessageDialog(Component parentComponent,
0639 Object message, String title, int messageType)
0640 throws HeadlessException {
0641 showMessageDialog(parentComponent, message, title, messageType,
0642 null);
0643 }
0644
0645 /**
0646 * Brings up a dialog displaying a message, specifying all parameters.
0647 *
0648 * @param parentComponent determines the <code>Frame</code> in which the
0649 * dialog is displayed; if <code>null</code>,
0650 * or if the <code>parentComponent</code> has no
0651 * <code>Frame</code>, a
0652 * default <code>Frame</code> is used
0653 * @param message the <code>Object</code> to display
0654 * @param title the title string for the dialog
0655 * @param messageType the type of message to be displayed:
0656 * <code>ERROR_MESSAGE</code>,
0657 * <code>INFORMATION_MESSAGE</code>,
0658 * <code>WARNING_MESSAGE</code>,
0659 * <code>QUESTION_MESSAGE</code>,
0660 * or <code>PLAIN_MESSAGE</code>
0661 * @param icon an icon to display in the dialog that helps the user
0662 * identify the kind of message that is being displayed
0663 * @exception HeadlessException if
0664 * <code>GraphicsEnvironment.isHeadless</code> returns
0665 * <code>true</code>
0666 * @see java.awt.GraphicsEnvironment#isHeadless
0667 */
0668 public static void showMessageDialog(Component parentComponent,
0669 Object message, String title, int messageType, Icon icon)
0670 throws HeadlessException {
0671 showOptionDialog(parentComponent, message, title,
0672 DEFAULT_OPTION, messageType, icon, null, null);
0673 }
0674
0675 /**
0676 * Brings up a dialog with the options <i>Yes</i>,
0677 * <i>No</i> and <i>Cancel</i>; with the
0678 * title, <b>Select an Option</b>.
0679 *
0680 * @param parentComponent determines the <code>Frame</code> in which the
0681 * dialog is displayed; if <code>null</code>,
0682 * or if the <code>parentComponent</code> has no
0683 * <code>Frame</code>, a
0684 * default <code>Frame</code> is used
0685 * @param message the <code>Object</code> to display
0686 * @return an integer indicating the option selected by the user
0687 * @exception HeadlessException if
0688 * <code>GraphicsEnvironment.isHeadless</code> returns
0689 * <code>true</code>
0690 * @see java.awt.GraphicsEnvironment#isHeadless
0691 */
0692 public static int showConfirmDialog(Component parentComponent,
0693 Object message) throws HeadlessException {
0694 return showConfirmDialog(parentComponent, message, UIManager
0695 .getString("OptionPane.titleText"),
0696 YES_NO_CANCEL_OPTION);
0697 }
0698
0699 /**
0700 * Brings up a dialog where the number of choices is determined
0701 * by the <code>optionType</code> parameter.
0702 *
0703 * @param parentComponent determines the <code>Frame</code> in which the
0704 * dialog is displayed; if <code>null</code>,
0705 * or if the <code>parentComponent</code> has no
0706 * <code>Frame</code>, a
0707 * default <code>Frame</code> is used
0708 * @param message the <code>Object</code> to display
0709 * @param title the title string for the dialog
0710 * @param optionType an int designating the options available on the dialog:
0711 * <code>YES_NO_OPTION</code>,
0712 * <code>YES_NO_CANCEL_OPTION</code>,
0713 * or <code>OK_CANCEL_OPTION</code>
0714 * @return an int indicating the option selected by the user
0715 * @exception HeadlessException if
0716 * <code>GraphicsEnvironment.isHeadless</code> returns
0717 * <code>true</code>
0718 * @see java.awt.GraphicsEnvironment#isHeadless
0719 */
0720 public static int showConfirmDialog(Component parentComponent,
0721 Object message, String title, int optionType)
0722 throws HeadlessException {
0723 return showConfirmDialog(parentComponent, message, title,
0724 optionType, QUESTION_MESSAGE);
0725 }
0726
0727 /**
0728 * Brings up a dialog where the number of choices is determined
0729 * by the <code>optionType</code> parameter, where the
0730 * <code>messageType</code>
0731 * parameter determines the icon to display.
0732 * The <code>messageType</code> parameter is primarily used to supply
0733 * a default icon from the Look and Feel.
0734 *
0735 * @param parentComponent determines the <code>Frame</code> in
0736 * which the dialog is displayed; if <code>null</code>,
0737 * or if the <code>parentComponent</code> has no
0738 * <code>Frame</code>, a
0739 * default <code>Frame</code> is used.
0740 * @param message the <code>Object</code> to display
0741 * @param title the title string for the dialog
0742 * @param optionType an integer designating the options available
0743 * on the dialog: <code>YES_NO_OPTION</code>,
0744 * <code>YES_NO_CANCEL_OPTION</code>,
0745 * or <code>OK_CANCEL_OPTION</code>
0746 * @param messageType an integer designating the kind of message this is;
0747 * primarily used to determine the icon from the pluggable
0748 * Look and Feel: <code>ERROR_MESSAGE</code>,
0749 * <code>INFORMATION_MESSAGE</code>,
0750 * <code>WARNING_MESSAGE</code>,
0751 * <code>QUESTION_MESSAGE</code>,
0752 * or <code>PLAIN_MESSAGE</code>
0753 * @return an integer indicating the option selected by the user
0754 * @exception HeadlessException if
0755 * <code>GraphicsEnvironment.isHeadless</code> returns
0756 * <code>true</code>
0757 * @see java.awt.GraphicsEnvironment#isHeadless
0758 */
0759 public static int showConfirmDialog(Component parentComponent,
0760 Object message, String title, int optionType,
0761 int messageType) throws HeadlessException {
0762 return showConfirmDialog(parentComponent, message, title,
0763 optionType, messageType, null);
0764 }
0765
0766 /**
0767 * Brings up a dialog with a specified icon, where the number of
0768 * choices is determined by the <code>optionType</code> parameter.
0769 * The <code>messageType</code> parameter is primarily used to supply
0770 * a default icon from the look and feel.
0771 *
0772 * @param parentComponent determines the <code>Frame</code> in which the
0773 * dialog is displayed; if <code>null</code>,
0774 * or if the <code>parentComponent</code> has no
0775 * <code>Frame</code>, a
0776 * default <code>Frame</code> is used
0777 * @param message the Object to display
0778 * @param title the title string for the dialog
0779 * @param optionType an int designating the options available on the dialog:
0780 * <code>YES_NO_OPTION</code>,
0781 * <code>YES_NO_CANCEL_OPTION</code>,
0782 * or <code>OK_CANCEL_OPTION</code>
0783 * @param messageType an int designating the kind of message this is,
0784 * primarily used to determine the icon from the pluggable
0785 * Look and Feel: <code>ERROR_MESSAGE</code>,
0786 * <code>INFORMATION_MESSAGE</code>,
0787 * <code>WARNING_MESSAGE</code>,
0788 * <code>QUESTION_MESSAGE</code>,
0789 * or <code>PLAIN_MESSAGE</code>
0790 * @param icon the icon to display in the dialog
0791 * @return an int indicating the option selected by the user
0792 * @exception HeadlessException if
0793 * <code>GraphicsEnvironment.isHeadless</code> returns
0794 * <code>true</code>
0795 * @see java.awt.GraphicsEnvironment#isHeadless
0796 */
0797 public static int showConfirmDialog(Component parentComponent,
0798 Object message, String title, int optionType,
0799 int messageType, Icon icon) throws HeadlessException {
0800 return showOptionDialog(parentComponent, message, title,
0801 optionType, messageType, icon, null, null);
0802 }
0803
0804 /**
0805 * Brings up a dialog with a specified icon, where the initial
0806 * choice is determined by the <code>initialValue</code> parameter and
0807 * the number of choices is determined by the <code>optionType</code>
0808 * parameter.
0809 * <p>
0810 * If <code>optionType</code> is <code>YES_NO_OPTION</code>,
0811 * or <code>YES_NO_CANCEL_OPTION</code>
0812 * and the <code>options</code> parameter is <code>null</code>,
0813 * then the options are
0814 * supplied by the look and feel.
0815 * <p>
0816 * The <code>messageType</code> parameter is primarily used to supply
0817 * a default icon from the look and feel.
0818 *
0819 * @param parentComponent determines the <code>Frame</code>
0820 * in which the dialog is displayed; if
0821 * <code>null</code>, or if the
0822 * <code>parentComponent</code> has no
0823 * <code>Frame</code>, a
0824 * default <code>Frame</code> is used
0825 * @param message the <code>Object</code> to display
0826 * @param title the title string for the dialog
0827 * @param optionType an integer designating the options available on the
0828 * dialog: <code>DEFAULT_OPTION</code>,
0829 * <code>YES_NO_OPTION</code>,
0830 * <code>YES_NO_CANCEL_OPTION</code>,
0831 * or <code>OK_CANCEL_OPTION</code>
0832 * @param messageType an integer designating the kind of message this is,
0833 * primarily used to determine the icon from the
0834 * pluggable Look and Feel: <code>ERROR_MESSAGE</code>,
0835 * <code>INFORMATION_MESSAGE</code>,
0836 * <code>WARNING_MESSAGE</code>,
0837 * <code>QUESTION_MESSAGE</code>,
0838 * or <code>PLAIN_MESSAGE</code>
0839 * @param icon the icon to display in the dialog
0840 * @param options an array of objects indicating the possible choices
0841 * the user can make; if the objects are components, they
0842 * are rendered properly; non-<code>String</code>
0843 * objects are
0844 * rendered using their <code>toString</code> methods;
0845 * if this parameter is <code>null</code>,
0846 * the options are determined by the Look and Feel
0847 * @param initialValue the object that represents the default selection
0848 * for the dialog; only meaningful if <code>options</code>
0849 * is used; can be <code>null</code>
0850 * @return an integer indicating the option chosen by the user,
0851 * or <code>CLOSED_OPTION</code> if the user closed
0852 * the dialog
0853 * @exception HeadlessException if
0854 * <code>GraphicsEnvironment.isHeadless</code> returns
0855 * <code>true</code>
0856 * @see java.awt.GraphicsEnvironment#isHeadless
0857 */
0858 public static int showOptionDialog(Component parentComponent,
0859 Object message, String title, int optionType,
0860 int messageType, Icon icon, Object[] options,
0861 Object initialValue) throws HeadlessException {
0862 JOptionPane pane = new JOptionPane(message, messageType,
0863 optionType, icon, options, initialValue);
0864
0865 pane.setInitialValue(initialValue);
0866 pane
0867 .setComponentOrientation(((parentComponent == null) ? getRootFrame()
0868 : parentComponent).getComponentOrientation());
0869
0870 int style = styleFromMessageType(messageType);
0871 JDialog dialog = pane.createDialog(parentComponent, title,
0872 style);
0873
0874 pane.selectInitialValue();
0875 dialog.show();
0876 dialog.dispose();
0877
0878 Object selectedValue = pane.getValue();
0879
0880 if (selectedValue == null)
0881 return CLOSED_OPTION;
0882 if (options == null) {
0883 if (selectedValue instanceof Integer)
0884 return ((Integer) selectedValue).intValue();
0885 return CLOSED_OPTION;
0886 }
0887 for (int counter = 0, maxCounter = options.length; counter < maxCounter; counter++) {
0888 if (options[counter].equals(selectedValue))
0889 return counter;
0890 }
0891 return CLOSED_OPTION;
0892 }
0893
0894 /**
0895 * Creates and returns a new <code>JDialog</code> wrapping
0896 * <code>this</code> centered on the <code>parentComponent</code>
0897 * in the <code>parentComponent</code>'s frame.
0898 * <code>title</code> is the title of the returned dialog.
0899 * The returned <code>JDialog</code> will not be resizable by the
0900 * user, however programs can invoke <code>setResizable</code> on
0901 * the <code>JDialog</code> instance to change this property.
0902 * The returned <code>JDialog</code> will be set up such that
0903 * once it is closed, or the user clicks on one of the buttons,
0904 * the optionpane's value property will be set accordingly and
0905 * the dialog will be closed. Each time the dialog is made visible,
0906 * it will reset the option pane's value property to
0907 * <code>JOptionPane.UNINITIALIZED_VALUE</code> to ensure the
0908 * user's subsequent action closes the dialog properly.
0909 *
0910 * @param parentComponent determines the frame in which the dialog
0911 * is displayed; if the <code>parentComponent</code> has
0912 * no <code>Frame</code>, a default <code>Frame</code> is used
0913 * @param title the title string for the dialog
0914 * @return a new <code>JDialog</code> containing this instance
0915 * @exception HeadlessException if
0916 * <code>GraphicsEnvironment.isHeadless</code> returns
0917 * <code>true</code>
0918 * @see java.awt.GraphicsEnvironment#isHeadless
0919 */
0920 public JDialog createDialog(Component parentComponent, String title)
0921 throws HeadlessException {
0922 int style = styleFromMessageType(getMessageType());
0923 return createDialog(parentComponent, title, style);
0924 }
0925
0926 /**
0927 * Creates and returns a new parentless <code>JDialog</code>
0928 * with the specified title.
0929 * The returned <code>JDialog</code> will not be resizable by the
0930 * user, however programs can invoke <code>setResizable</code> on
0931 * the <code>JDialog</code> instance to change this property.
0932 * The returned <code>JDialog</code> will be set up such that
0933 * once it is closed, or the user clicks on one of the buttons,
0934 * the optionpane's value property will be set accordingly and
0935 * the dialog will be closed. Each time the dialog is made visible,
0936 * it will reset the option pane's value property to
0937 * <code>JOptionPane.UNINITIALIZED_VALUE</code> to ensure the
0938 * user's subsequent action closes the dialog properly.
0939 *
0940 * @param title the title string for the dialog
0941 * @return a new <code>JDialog</code> containing this instance
0942 * @exception HeadlessException if
0943 * <code>GraphicsEnvironment.isHeadless</code> returns
0944 * <code>true</code>
0945 * @see java.awt.GraphicsEnvironment#isHeadless
0946 * @since 1.6
0947 */
0948 public JDialog createDialog(String title) throws HeadlessException {
0949 int style = styleFromMessageType(getMessageType());
0950 JDialog dialog = new JDialog((Dialog) null, title, true);
0951 initDialog(dialog, style, null);
0952 return dialog;
0953 }
0954
0955 private JDialog createDialog(Component parentComponent,
0956 String title, int style) throws HeadlessException {
0957
0958 final JDialog dialog;
0959
0960 Window window = JOptionPane
0961 .getWindowForComponent(parentComponent);
0962 if (window instanceof Frame) {
0963 dialog = new JDialog((Frame) window, title, true);
0964 } else {
0965 dialog = new JDialog((Dialog) window, title, true);
0966 }
0967 if (window instanceof SwingUtilities.SharedOwnerFrame) {
0968 WindowListener ownerShutdownListener = (WindowListener) SwingUtilities
0969 .getSharedOwnerFrameShutdownListener();
0970 dialog.addWindowListener(ownerShutdownListener);
0971 }
0972 initDialog(dialog, style, parentComponent);
0973 return dialog;
0974 }
0975
0976 private void initDialog(final JDialog dialog, int style,
0977 Component parentComponent) {
0978 dialog.setComponentOrientation(this .getComponentOrientation());
0979 Container contentPane = dialog.getContentPane();
0980
0981 contentPane.setLayout(new BorderLayout());
0982 contentPane.add(this , BorderLayout.CENTER);
0983 dialog.setResizable(false);
0984 if (JDialog.isDefaultLookAndFeelDecorated()) {
0985 boolean supportsWindowDecorations = UIManager
0986 .getLookAndFeel().getSupportsWindowDecorations();
0987 if (supportsWindowDecorations) {
0988 dialog.setUndecorated(true);
0989 getRootPane().setWindowDecorationStyle(style);
0990 }
0991 }
0992 dialog.pack();
0993 dialog.setLocationRelativeTo(parentComponent);
0994 WindowAdapter adapter = new WindowAdapter() {
0995 private boolean gotFocus = false;
0996
0997 public void windowClosing(WindowEvent we) {
0998 setValue(null);
0999 }
1000
1001 public void windowGainedFocus(WindowEvent we) {
1002 // Once window gets focus, set initial focus
1003 if (!gotFocus) {
1004 selectInitialValue();
1005 gotFocus = true;
1006 }
1007 }
1008 };
1009 dialog.addWindowListener(adapter);
1010 dialog.addWindowFocusListener(adapter);
1011 dialog.addComponentListener(new ComponentAdapter() {
1012 public void componentShown(ComponentEvent ce) {
1013 // reset value to ensure closing works properly
1014 setValue(JOptionPane.UNINITIALIZED_VALUE);
1015 }
1016 });
1017 addPropertyChangeListener(new PropertyChangeListener() {
1018 public void propertyChange(PropertyChangeEvent event) {
1019 // Let the defaultCloseOperation handle the closing
1020 // if the user closed the window without selecting a button
1021 // (newValue = null in that case). Otherwise, close the dialog.
1022 if (dialog.isVisible()
1023 && event.getSource() == JOptionPane.this
1024 && (event.getPropertyName().equals(
1025 VALUE_PROPERTY) || event
1026 .getPropertyName().equals(
1027 INPUT_VALUE_PROPERTY))
1028 && event.getNewValue() != null
1029 && event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) {
1030 dialog.setVisible(false);
1031 }
1032 }
1033 });
1034 }
1035
1036 /**
1037 * Brings up an internal confirmation dialog panel. The dialog
1038 * is a information-message dialog titled "Message".
1039 *
1040 * @param parentComponent determines the <code>Frame</code>
1041 * in which the dialog is displayed; if <code>null</code>,
1042 * or if the <code>parentComponent</code> has no
1043 * <code>Frame</code>, a default <code>Frame</code> is used
1044 * @param message the object to display
1045 */
1046 public static void showInternalMessageDialog(
1047 Component parentComponent, Object message) {
1048 showInternalMessageDialog(parentComponent, message, UIManager
1049 .getString("OptionPane.messageDialogTitle",
1050 parentComponent), INFORMATION_MESSAGE);
1051 }
1052
1053 /**
1054 * Brings up an internal dialog panel that displays a message
1055 * using a default icon determined by the <code>messageType</code>
1056 * parameter.
1057 *
1058 * @param parentComponent determines the <code>Frame</code>
1059 * in which the dialog is displayed; if <code>null</code>,
1060 * or if the <code>parentComponent</code> has no
1061 * <code>Frame</code>, a default <code>Frame</code> is used
1062 * @param message the <code>Object</code> to display
1063 * @param title the title string for the dialog
1064 * @param messageType the type of message to be displayed:
1065 * <code>ERROR_MESSAGE</code>,
1066 * <code>INFORMATION_MESSAGE</code>,
1067 * <code>WARNING_MESSAGE</code>,
1068 * <code>QUESTION_MESSAGE</code>,
1069 * or <code>PLAIN_MESSAGE</code>
1070 */
1071 public static void showInternalMessageDialog(
1072 Component parentComponent, Object message, String title,
1073 int messageType) {
1074 showInternalMessageDialog(parentComponent, message, title,
1075 messageType, null);
1076 }
1077
1078 /**
1079 * Brings up an internal dialog panel displaying a message,
1080 * specifying all parameters.
1081 *
1082 * @param parentComponent determines the <code>Frame</code>
1083 * in which the dialog is displayed; if <code>null</code>,
1084 * or if the <code>parentComponent</code> has no
1085 * <code>Frame</code>, a default <code>Frame</code> is used
1086 * @param message the <code>Object</code> to display
1087 * @param title the title string for the dialog
1088 * @param messageType the type of message to be displayed:
1089 * <code>ERROR_MESSAGE</code>,
1090 * <code>INFORMATION_MESSAGE</code>,
1091 * <code>WARNING_MESSAGE</code>,
1092 * <code>QUESTION_MESSAGE</code>,
1093 * or <code>PLAIN_MESSAGE</code>
1094 * @param icon an icon to display in the dialog that helps the user
1095 * identify the kind of message that is being displayed
1096 */
1097 public static void showInternalMessageDialog(
1098 Component parentComponent, Object message, String title,
1099 int messageType, Icon icon) {
1100 showInternalOptionDialog(parentComponent, message, title,
1101 DEFAULT_OPTION, messageType, icon, null, null);
1102 }
1103
1104 /**
1105 * Brings up an internal dialog panel with the options <i>Yes</i>, <i>No</i>
1106 * and <i>Cancel</i>; with the title, <b>Select an Option</b>.
1107 *
1108 * @param parentComponent determines the <code>Frame</code> in
1109 * which the dialog is displayed; if <code>null</code>,
1110 * or if the <code>parentComponent</code> has no
1111 * <code>Frame</code>, a default <code>Frame</code> is used
1112 * @param message the <code>Object</code> to display
1113 * @return an integer indicating the option selected by the user
1114 */
1115 public static int showInternalConfirmDialog(
1116 Component parentComponent, Object message) {
1117 return showInternalConfirmDialog(parentComponent, message,
1118 UIManager.getString("OptionPane.titleText"),
1119 YES_NO_CANCEL_OPTION);
1120 }
1121
1122 /**
1123 * Brings up a internal dialog panel where the number of choices
1124 * is determined by the <code>optionType</code> parameter.
1125 *
1126 * @param parentComponent determines the <code>Frame</code>
1127 * in which the dialog is displayed; if <code>null</code>,
1128 * or if the <code>parentComponent</code> has no
1129 * <code>Frame</code>, a default <code>Frame</code> is used
1130 * @param message the object to display in the dialog; a
1131 * <code>Component</code> object is rendered as a
1132 * <code>Component</code>; a <code>String</code>
1133 * object is rendered as a string; other objects
1134 * are converted to a <code>String</code> using the
1135 * <code>toString</code> method
1136 * @param title the title string for the dialog
1137 * @param optionType an integer designating the options
1138 * available on the dialog: <code>YES_NO_OPTION</code>,
1139 * or <code>YES_NO_CANCEL_OPTION</code>
1140 * @return an integer indicating the option selected by the user
1141 */
1142 public static int showInternalConfirmDialog(
1143 Component parentComponent, Object message, String title,
1144 int optionType) {
1145 return showInternalConfirmDialog(parentComponent, message,
1146 title, optionType, QUESTION_MESSAGE);
1147 }
1148
1149 /**
1150 * Brings up an internal dialog panel where the number of choices
1151 * is determined by the <code>optionType</code> parameter, where
1152 * the <code>messageType</code> parameter determines the icon to display.
1153 * The <code>messageType</code> parameter is primarily used to supply
1154 * a default icon from the Look and Feel.
1155 *
1156 * @param parentComponent determines the <code>Frame</code> in
1157 * which the dialog is displayed; if <code>null</code>,
1158 * or if the <code>parentComponent</code> has no
1159 * <code>Frame</code>, a default <code>Frame</code> is used
1160 * @param message the object to display in the dialog; a
1161 * <code>Component</code> object is rendered as a
1162 * <code>Component</code>; a <code>String</code>
1163 * object is rendered as a string; other objects are
1164 * converted to a <code>String</code> using the
1165 * <code>toString</code> method
1166 * @param title the title string for the dialog
1167 * @param optionType an integer designating the options
1168 * available on the dialog:
1169 * <code>YES_NO_OPTION</code>, or <code>YES_NO_CANCEL_OPTION</code>
1170 * @param messageType an integer designating the kind of message this is,
1171 * primarily used to determine the icon from the
1172 * pluggable Look and Feel: <code>ERROR_MESSAGE</code>,
1173 * <code>INFORMATION_MESSAGE</code>,
1174 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
1175 * or <code>PLAIN_MESSAGE</code>
1176 * @return an integer indicating the option selected by the user
1177 */
1178 public static int showInternalConfirmDialog(
1179 Component parentComponent, Object message, String title,
1180 int optionType, int messageType) {
1181 return showInternalConfirmDialog(parentComponent, message,
1182 title, optionType, messageType, null);
1183 }
1184
1185 /**
1186 * Brings up an internal dialog panel with a specified icon, where
1187 * the number of choices is determined by the <code>optionType</code>
1188 * parameter.
1189 * The <code>messageType</code> parameter is primarily used to supply
1190 * a default icon from the look and feel.
1191 *
1192 * @param parentComponent determines the <code>Frame</code>
1193 * in which the dialog is displayed; if <code>null</code>,
1194 * or if the parentComponent has no Frame, a
1195 * default <code>Frame</code> is used
1196 * @param message the object to display in the dialog; a
1197 * <code>Component</code> object is rendered as a
1198 * <code>Component</code>; a <code>String</code>
1199 * object is rendered as a string; other objects are
1200 * converted to a <code>String</code> using the
1201 * <code>toString</code> method
1202 * @param title the title string for the dialog
1203 * @param optionType an integer designating the options available
1204 * on the dialog:
1205 * <code>YES_NO_OPTION</code>, or
1206 * <code>YES_NO_CANCEL_OPTION</code>.
1207 * @param messageType an integer designating the kind of message this is,
1208 * primarily used to determine the icon from the pluggable
1209 * Look and Feel: <code>ERROR_MESSAGE</code>,
1210 * <code>INFORMATION_MESSAGE</code>,
1211 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
1212 * or <code>PLAIN_MESSAGE</code>
1213 * @param icon the icon to display in the dialog
1214 * @return an integer indicating the option selected by the user
1215 */
1216 public static int showInternalConfirmDialog(
1217 Component parentComponent, Object message, String title,
1218 int optionType, int messageType, Icon icon) {
1219 return showInternalOptionDialog(parentComponent, message,
1220 title, optionType, messageType, icon, null, null);
1221 }
1222
1223 /**
1224 * Brings up an internal dialog panel with a specified icon, where
1225 * the initial choice is determined by the <code>initialValue</code>
1226 * parameter and the number of choices is determined by the
1227 * <code>optionType</code> parameter.
1228 * <p>
1229 * If <code>optionType</code> is <code>YES_NO_OPTION</code>, or
1230 * <code>YES_NO_CANCEL_OPTION</code>
1231 * and the <code>options</code> parameter is <code>null</code>,
1232 * then the options are supplied by the Look and Feel.
1233 * <p>
1234 * The <code>messageType</code> parameter is primarily used to supply
1235 * a default icon from the look and feel.
1236 *
1237 * @param parentComponent determines the <code>Frame</code>
1238 * in which the dialog is displayed; if <code>null</code>,
1239 * or if the <code>parentComponent</code> has no
1240 * <code>Frame</code>, a default <code>Frame</code> is used
1241 * @param message the object to display in the dialog; a
1242 * <code>Component</code> object is rendered as a
1243 * <code>Component</code>; a <code>String</code>
1244 * object is rendered as a string. Other objects are
1245 * converted to a <code>String</code> using the
1246 * <code>toString</code> method
1247 * @param title the title string for the dialog
1248 * @param optionType an integer designating the options available
1249 * on the dialog: <code>YES_NO_OPTION</code>,
1250 * or <code>YES_NO_CANCEL_OPTION</code>
1251 * @param messageType an integer designating the kind of message this is;
1252 * primarily used to determine the icon from the
1253 * pluggable Look and Feel: <code>ERROR_MESSAGE</code>,
1254 * <code>INFORMATION_MESSAGE</code>,
1255 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
1256 * or <code>PLAIN_MESSAGE</code>
1257 * @param icon the icon to display in the dialog
1258 * @param options an array of objects indicating the possible choices
1259 * the user can make; if the objects are components, they
1260 * are rendered properly; non-<code>String</code>
1261 * objects are rendered using their <code>toString</code>
1262 * methods; if this parameter is <code>null</code>,
1263 * the options are determined by the Look and Feel
1264 * @param initialValue the object that represents the default selection
1265 * for the dialog; only meaningful if <code>options</code>
1266 * is used; can be <code>null</code>
1267 * @return an integer indicating the option chosen by the user,
1268 * or <code>CLOSED_OPTION</code> if the user closed the Dialog
1269 */
1270 public static int showInternalOptionDialog(
1271 Component parentComponent, Object message, String title,
1272 int optionType, int messageType, Icon icon,
1273 Object[] options, Object initialValue) {
1274 JOptionPane pane = new JOptionPane(message, messageType,
1275 optionType, icon, options, initialValue);
1276 pane.putClientProperty(PopupFactory_FORCE_HEAVYWEIGHT_POPUP,
1277 Boolean.TRUE);
1278 Component fo = KeyboardFocusManager
1279 .getCurrentKeyboardFocusManager().getFocusOwner();
1280
1281 pane.setInitialValue(initialValue);
1282
1283 JInternalFrame dialog = pane.createInternalFrame(
1284 parentComponent, title);
1285 pane.selectInitialValue();
1286 dialog.setVisible(true);
1287
1288 /* Since all input will be blocked until this dialog is dismissed,
1289 * make sure its parent containers are visible first (this component
1290 * is tested below). This is necessary for JApplets, because
1291 * because an applet normally isn't made visible until after its
1292 * start() method returns -- if this method is called from start(),
1293 * the applet will appear to hang while an invisible modal frame
1294 * waits for input.
1295 */
1296 if (dialog.isVisible() && !dialog.isShowing()) {
1297 Container parent = dialog.getParent();
1298 while (parent != null) {
1299 if (parent.isVisible() == false) {
1300 parent.setVisible(true);
1301 }
1302 parent = parent.getParent();
1303 }
1304 }
1305
1306 // Use reflection to get Container.startLWModal.
1307 try {
1308 Object obj;
1309 obj = AccessController
1310 .doPrivileged(new ModalPrivilegedAction(
1311 Container.class, "startLWModal"));
1312 if (obj != null) {
1313 ((Method) obj).invoke(dialog, (Object[]) null);
1314 }
1315 } catch (IllegalAccessException ex) {
1316 } catch (IllegalArgumentException ex) {
1317 } catch (InvocationTargetException ex) {
1318 }
1319
1320 if (parentComponent instanceof JInternalFrame) {
1321 try {
1322 ((JInternalFrame) parentComponent).setSelected(true);
1323 } catch (java.beans.PropertyVetoException e) {
1324 }
1325 }
1326
1327 Object selectedValue = pane.getValue();
1328
1329 if (fo != null && fo.isShowing()) {
1330 fo.requestFocus();
1331 }
1332 if (selectedValue == null) {
1333 return CLOSED_OPTION;
1334 }
1335 if (options == null) {
1336 if (selectedValue instanceof Integer) {
1337 return ((Integer) selectedValue).intValue();
1338 }
1339 return CLOSED_OPTION;
1340 }
1341 for (int counter = 0, maxCounter = options.length; counter < maxCounter; counter++) {
1342 if (options[counter].equals(selectedValue)) {
1343 return counter;
1344 }
1345 }
1346 return CLOSED_OPTION;
1347 }
1348
1349 /**
1350 * Shows an internal question-message dialog requesting input from
1351 * the user parented to <code>parentComponent</code>. The dialog
1352 * is displayed in the <code>Component</code>'s frame,
1353 * and is usually positioned below the <code>Component</code>.
1354 *
1355 * @param parentComponent the parent <code>Component</code>
1356 * for the dialog
1357 * @param message the <code>Object</code> to display
1358 */
1359 public static String showInternalInputDialog(
1360 Component parentComponent, Object message) {
1361 return showInternalInputDialog(parentComponent, message,
1362 UIManager.getString("OptionPane.inputDialogTitle",
1363 parentComponent), QUESTION_MESSAGE);
1364 }
1365
1366 /**
1367 * Shows an internal dialog requesting input from the user parented
1368 * to <code>parentComponent</code> with the dialog having the title
1369 * <code>title</code> and message type <code>messageType</code>.
1370 *
1371 * @param parentComponent the parent <code>Component</code> for the dialog
1372 * @param message the <code>Object</code> to display
1373 * @param title the <code>String</code> to display in the
1374 * dialog title bar
1375 * @param messageType the type of message that is to be displayed:
1376 * ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
1377 * QUESTION_MESSAGE, or PLAIN_MESSAGE
1378 */
1379 public static String showInternalInputDialog(
1380 Component parentComponent, Object message, String title,
1381 int messageType) {
1382 return (String) showInternalInputDialog(parentComponent,
1383 message, title, messageType, null, null, null);
1384 }
1385
1386 /**
1387 * Prompts the user for input in a blocking internal dialog where
1388 * the initial selection, possible selections, and all other
1389 * options can be specified. The user will able to choose from
1390 * <code>selectionValues</code>, where <code>null</code>
1391 * implies the user can input
1392 * whatever they wish, usually by means of a <code>JTextField</code>.
1393 * <code>initialSelectionValue</code> is the initial value to prompt
1394 * the user with. It is up to the UI to decide how best to represent
1395 * the <code>selectionValues</code>, but usually a
1396 * <code>JComboBox</code>, <code>JList</code>, or
1397 * <code>JTextField</code> will be used.
1398 *
1399 * @param parentComponent the parent <code>Component</code> for the dialog
1400 * @param message the <code>Object</code> to display
1401 * @param title the <code>String</code> to display in the dialog
1402 * title bar
1403 * @param messageType the type of message to be displayed:
1404 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
1405 * <code>WARNING_MESSAGE</code>,
1406 * <code>QUESTION_MESSAGE</code>, or <code>PLAIN_MESSAGE</code>
1407 * @param icon the <code>Icon</code> image to display
1408 * @param selectionValues an array of <code>Objects</code> that
1409 * gives the possible selections
1410 * @param initialSelectionValue the value used to initialize the input
1411 * field
1412 * @return user's input, or <code>null</code> meaning the user
1413 * canceled the input
1414 */
1415 public static Object showInternalInputDialog(
1416 Component parentComponent, Object message, String title,
1417 int messageType, Icon icon, Object[] selectionValues,
1418 Object initialSelectionValue) {
1419 JOptionPane pane = new JOptionPane(message, messageType,
1420 OK_CANCEL_OPTION, icon, null, null);
1421 pane.putClientProperty(PopupFactory_FORCE_HEAVYWEIGHT_POPUP,
1422 Boolean.TRUE);
1423 Component fo = KeyboardFocusManager
1424 .getCurrentKeyboardFocusManager().getFocusOwner();
1425
1426 pane.setWantsInput(true);
1427 pane.setSelectionValues(selectionValues);
1428 pane.setInitialSelectionValue(initialSelectionValue);
1429
1430 JInternalFrame dialog = pane.createInternalFrame(
1431 parentComponent, title);
1432
1433 pane.selectInitialValue();
1434 dialog.setVisible(true);
1435
1436 /* Since all input will be blocked until this dialog is dismissed,
1437 * make sure its parent containers are visible first (this component
1438 * is tested below). This is necessary for JApplets, because
1439 * because an applet normally isn't made visible until after its
1440 * start() method returns -- if this method is called from start(),
1441 * the applet will appear to hang while an invisible modal frame
1442 * waits for input.
1443 */
1444 if (dialog.isVisible() && !dialog.isShowing()) {
1445 Container parent = dialog.getParent();
1446 while (parent != null) {
1447 if (parent.isVisible() == false) {
1448 parent.setVisible(true);
1449 }
1450 parent = parent.getParent();
1451 }
1452 }
1453
1454 // Use reflection to get Container.startLWModal.
1455 try {
1456 Object obj;
1457 obj = AccessController
1458 .doPrivileged(new ModalPrivilegedAction(
1459 Container.class, "startLWModal"));
1460 if (obj != null) {
1461 ((Method) obj).invoke(dialog, (Object[]) null);
1462 }
1463 } catch (IllegalAccessException ex) {
1464 } catch (IllegalArgumentException ex) {
1465 } catch (InvocationTargetException ex) {
1466 }
1467
1468 if (parentComponent instanceof JInternalFrame) {
1469 try {
1470 ((JInternalFrame) parentComponent).setSelected(true);
1471 } catch (java.beans.PropertyVetoException e) {
1472 }
1473 }
1474
1475 if (fo != null && fo.isShowing()) {
1476 fo.requestFocus();
1477 }
1478 Object value = pane.getInputValue();
1479
1480 if (value == UNINITIALIZED_VALUE) {
1481 return null;
1482 }
1483 return value;
1484 }
1485
1486 /**
1487 * Creates and returns an instance of <code>JInternalFrame</code>.
1488 * The internal frame is created with the specified title,
1489 * and wrapping the <code>JOptionPane</code>.
1490 * The returned <code>JInternalFrame</code> is
1491 * added to the <code>JDesktopPane</code> ancestor of
1492 * <code>parentComponent</code>, or components
1493 * parent if one its ancestors isn't a <code>JDesktopPane</code>,
1494 * or if <code>parentComponent</code>
1495 * doesn't have a parent then a <code>RuntimeException</code> is thrown.
1496 *
1497 * @param parentComponent the parent <code>Component</code> for
1498 * the internal frame
1499 * @param title the <code>String</code> to display in the
1500 * frame's title bar
1501 * @return a <code>JInternalFrame</code> containing a
1502 * <code>JOptionPane</code>
1503 * @exception RuntimeException if <code>parentComponent</code> does
1504 * not have a valid parent
1505 */
1506 public JInternalFrame createInternalFrame(
1507 Component parentComponent, String title) {
1508 Container parent = JOptionPane
1509 .getDesktopPaneForComponent(parentComponent);
1510
1511 if (parent == null
1512 && (parentComponent == null || (parent = parentComponent
1513 .getParent()) == null)) {
1514 throw new RuntimeException(
1515 "JOptionPane: parentComponent does "
1516 + "not have a valid parent");
1517 }
1518
1519 // Option dialogs should be closable only
1520 final JInternalFrame iFrame = new JInternalFrame(title, false,
1521 true, false, false);
1522
1523 iFrame.putClientProperty("JInternalFrame.frameType",
1524 "optionDialog");
1525 iFrame.putClientProperty("JInternalFrame.messageType",
1526 new Integer(getMessageType()));
1527
1528 iFrame.addInternalFrameListener(new InternalFrameAdapter() {
1529 public void internalFrameClosing(InternalFrameEvent e) {
1530 if (getValue() == UNINITIALIZED_VALUE) {
1531 setValue(null);
1532 }
1533 }
1534 });
1535 addPropertyChangeListener(new PropertyChangeListener() {
1536 public void propertyChange(PropertyChangeEvent event) {
1537 // Let the defaultCloseOperation handle the closing
1538 // if the user closed the iframe without selecting a button
1539 // (newValue = null in that case). Otherwise, close the dialog.
1540 if (iFrame.isVisible()
1541 && event.getSource() == JOptionPane.this
1542 && event.getPropertyName().equals(
1543 VALUE_PROPERTY)) {
1544 // Use reflection to get Container.stopLWModal().
1545 try {
1546 Object obj;
1547 obj = AccessController
1548 .doPrivileged(new ModalPrivilegedAction(
1549 Container.class, "stopLWModal"));
1550 if (obj != null) {
1551 ((Method) obj).invoke(iFrame,
1552 (Object[]) null);
1553 }
1554 } catch (IllegalAccessException ex) {
1555 } catch (IllegalArgumentException ex) {
1556 } catch (InvocationTargetException ex) {
1557 }
1558
1559 try {
1560 iFrame.setClosed(true);
1561 } catch (java.beans.PropertyVetoException e) {
1562 }
1563
1564 iFrame.setVisible(false);
1565 }
1566 }
1567 });
1568 iFrame.getContentPane().add(this , BorderLayout.CENTER);
1569 if (parent instanceof JDesktopPane) {
1570 parent.add(iFrame, JLayeredPane.MODAL_LAYER);
1571 } else {
1572 parent.add(iFrame, BorderLayout.CENTER);
1573 }
1574 Dimension iFrameSize = iFrame.getPreferredSize();
1575 Dimension rootSize = parent.getSize();
1576 Dimension parentSize = parentComponent.getSize();
1577
1578 iFrame.setBounds((rootSize.width - iFrameSize.width) / 2,
1579 (rootSize.height - iFrameSize.height) / 2,
1580 iFrameSize.width, iFrameSize.height);
1581 // We want dialog centered relative to its parent component
1582 Point iFrameCoord = SwingUtilities.convertPoint(
1583 parentComponent, 0, 0, parent);
1584 int x = (parentSize.width - iFrameSize.width) / 2
1585 + iFrameCoord.x;
1586 int y = (parentSize.height - iFrameSize.height) / 2
1587 + iFrameCoord.y;
1588
1589 // If possible, dialog should be fully visible
1590 int ovrx = x + iFrameSize.width - rootSize.width;
1591 int ovry = y + iFrameSize.height - rootSize.height;
1592 x = Math.max((ovrx > 0 ? x - ovrx : x), 0);
1593 y = Math.max((ovry > 0 ? y - ovry : y), 0);
1594 iFrame.setBounds(x, y, iFrameSize.width, iFrameSize.height);
1595
1596 parent.validate();
1597 try {
1598 iFrame.setSelected(true);
1599 } catch (java.beans.PropertyVetoException e) {
1600 }
1601
1602 return iFrame;
1603 }
1604
1605 /**
1606 * Returns the specified component's <code>Frame</code>.
1607 *
1608 * @param parentComponent the <code>Component</code> to check for a
1609 * <code>Frame</code>
1610 * @return the <code>Frame</code> that contains the component,
1611 * or <code>getRootFrame</code>
1612 * if the component is <code>null</code>,
1613 * or does not have a valid <code>Frame</code> parent
1614 * @exception HeadlessException if
1615 * <code>GraphicsEnvironment.isHeadless</code> returns
1616 * <code>true</code>
1617 * @see #getRootFrame
1618 * @see java.awt.GraphicsEnvironment#isHeadless
1619 */
1620 public static Frame getFrameForComponent(Component parentComponent)
1621 throws HeadlessException {
1622 if (parentComponent == null)
1623 return getRootFrame();
1624 if (parentComponent instanceof Frame)
1625 return (Frame) parentComponent;
1626 return JOptionPane.getFrameForComponent(parentComponent
1627 .getParent());
1628 }
1629
1630 /**
1631 * Returns the specified component's toplevel <code>Frame</code> or
1632 * <code>Dialog</code>.
1633 *
1634 * @param parentComponent the <code>Component</code> to check for a
1635 * <code>Frame</code> or <code>Dialog</code>
1636 * @return the <code>Frame</code> or <code>Dialog</code> that
1637 * contains the component, or the default
1638 * frame if the component is <code>null</code>,
1639 * or does not have a valid
1640 * <code>Frame</code> or <code>Dialog</code> parent
1641 * @exception HeadlessException if
1642 * <code>GraphicsEnvironment.isHeadless</code> returns
1643 * <code>true</code>
1644 * @see java.awt.GraphicsEnvironment#isHeadless
1645 */
1646 static Window getWindowForComponent(Component parentComponent)
1647 throws HeadlessException {
1648 if (parentComponent == null)
1649 return getRootFrame();
1650 if (parentComponent instanceof Frame
1651 || parentComponent instanceof Dialog)
1652 return (Window) parentComponent;
1653 return JOptionPane.getWindowForComponent(parentComponent
1654 .getParent());
1655 }
1656
1657 /**
1658 * Returns the specified component's desktop pane.
1659 *
1660 * @param parentComponent the <code>Component</code> to check for a
1661 * desktop
1662 * @return the <code>JDesktopPane</code> that contains the component,
1663 * or <code>null</code> if the component is <code>null</code>
1664 * or does not have an ancestor that is a
1665 * <code>JInternalFrame</code>
1666 */
1667 public static JDesktopPane getDesktopPaneForComponent(
1668 Component parentComponent) {
1669 if (parentComponent == null)
1670 return null;
1671 if (parentComponent instanceof JDesktopPane)
1672 return (JDesktopPane) parentComponent;
1673 return getDesktopPaneForComponent(parentComponent.getParent());
1674 }
1675
1676 private static final Object sharedFrameKey = JOptionPane.class;
1677
1678 /**
1679 * Sets the frame to use for class methods in which a frame is
1680 * not provided.
1681 * <p>
1682 * <strong>Note:</strong>
1683 * It is recommended that rather than using this method you supply a valid parent.
1684 *
1685 * @param newRootFrame the default <code>Frame</code> to use
1686 */
1687 public static void setRootFrame(Frame newRootFrame) {
1688 if (newRootFrame != null) {
1689 SwingUtilities.appContextPut(sharedFrameKey, newRootFrame);
1690 } else {
1691 SwingUtilities.appContextRemove(sharedFrameKey);
1692 }
1693 }
1694
1695 /**
1696 * Returns the <code>Frame</code> to use for the class methods in
1697 * which a frame is not provided.
1698 *
1699 * @return the default <code>Frame</code> to use
1700 * @exception HeadlessException if
1701 * <code>GraphicsEnvironment.isHeadless</code> returns
1702 * <code>true</code>
1703 * @see #setRootFrame
1704 * @see java.awt.GraphicsEnvironment#isHeadless
1705 */
1706 public static Frame getRootFrame() throws HeadlessException {
1707 Frame sharedFrame = (Frame) SwingUtilities
1708 .appContextGet(sharedFrameKey);
1709 if (sharedFrame == null) {
1710 sharedFrame = SwingUtilities.getSharedOwnerFrame();
1711 SwingUtilities.appContextPut(sharedFrameKey, sharedFrame);
1712 }
1713 return sharedFrame;
1714 }
1715
1716 /**
1717 * Creates a <code>JOptionPane</code> with a test message.
1718 */
1719 public JOptionPane() {
1720 this ("JOptionPane message");
1721 }
1722
1723 /**
1724 * Creates a instance of <code>JOptionPane</code> to display a
1725 * message using the
1726 * plain-message message type and the default options delivered by
1727 * the UI.
1728 *
1729 * @param message the <code>Object</code> to display
1730 */
1731 public JOptionPane(Object message) {
1732 this (message, PLAIN_MESSAGE);
1733 }
1734
1735 /**
1736 * Creates an instance of <code>JOptionPane</code> to display a message
1737 * with the specified message type and the default options,
1738 *
1739 * @param message the <code>Object</code> to display
1740 * @param messageType the type of message to be displayed:
1741 * <code>ERROR_MESSAGE</code>,
1742 * <code>INFORMATION_MESSAGE</code>,
1743 * <code>WARNING_MESSAGE</code>,
1744 * <code>QUESTION_MESSAGE</code>,
1745 * or <code>PLAIN_MESSAGE</code>
1746 */
1747 public JOptionPane(Object message, int messageType) {
1748 this (message, messageType, DEFAULT_OPTION);
1749 }
1750
1751 /**
1752 * Creates an instance of <code>JOptionPane</code> to display a message
1753 * with the specified message type and options.
1754 *
1755 * @param message the <code>Object</code> to display
1756 * @param messageType the type of message to be displayed:
1757 * <code>ERROR_MESSAGE</code>,
1758 * <code>INFORMATION_MESSAGE</code>,
1759 * <code>WARNING_MESSAGE</code>,
1760 * <code>QUESTION_MESSAGE</code>,
1761 * or <code>PLAIN_MESSAGE</code>
1762 * @param optionType the options to display in the pane:
1763 * <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>,
1764 * <code>YES_NO_CANCEL_OPTION</code>,
1765 * <code>OK_CANCEL_OPTION</code>
1766 */
1767 public JOptionPane(Object message, int messageType, int optionType) {
1768 this (message, messageType, optionType, null);
1769 }
1770
1771 /**
1772 * Creates an instance of <code>JOptionPane</code> to display a message
1773 * with the specified message type, options, and icon.
1774 *
1775 * @param message the <code>Object</code> to display
1776 * @param messageType the type of message to be displayed:
1777 * <code>ERROR_MESSAGE</code>,
1778 * <code>INFORMATION_MESSAGE</code>,
1779 * <code>WARNING_MESSAGE</code>,
1780 * <code>QUESTION_MESSAGE</code>,
1781 * or <code>PLAIN_MESSAGE</code>
1782 * @param optionType the options to display in the pane:
1783 * <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>,
1784 * <code>YES_NO_CANCEL_OPTION</code>,
1785 * <code>OK_CANCEL_OPTION</code>
1786 * @param icon the <code>Icon</code> image to display
1787 */
1788 public JOptionPane(Object message, int messageType, int optionType,
1789 Icon icon) {
1790 this (message, messageType, optionType, icon, null);
1791 }
1792
1793 /**
1794 * Creates an instance of <code>JOptionPane</code> to display a message
1795 * with the specified message type, icon, and options.
1796 * None of the options is initially selected.
1797 * <p>
1798 * The options objects should contain either instances of
1799 * <code>Component</code>s, (which are added directly) or
1800 * <code>Strings</code> (which are wrapped in a <code>JButton</code>).
1801 * If you provide <code>Component</code>s, you must ensure that when the
1802 * <code>Component</code> is clicked it messages <code>setValue</code>
1803 * in the created <code>JOptionPane</code>.
1804 *
1805 * @param message the <code>Object</code> to display
1806 * @param messageType the type of message to be displayed:
1807 * <code>ERROR_MESSAGE</code>,
1808 * <code>INFORMATION_MESSAGE</code>,
1809 * <code>WARNING_MESSAGE</code>,
1810 * <code>QUESTION_MESSAGE</code>,
1811 * or <code>PLAIN_MESSAGE</code>
1812 * @param optionType the options to display in the pane:
1813 * <code>DEFAULT_OPTION</code>,
1814 * <code>YES_NO_OPTION</code>,
1815 * <code>YES_NO_CANCEL_OPTION</code>,
1816 * <code>OK_CANCEL_OPTION</code>
1817 * @param icon the <code>Icon</code> image to display
1818 * @param options the choices the user can select
1819 */
1820 public JOptionPane(Object message, int messageType, int optionType,
1821 Icon icon, Object[] options) {
1822 this (message, messageType, optionType, icon, options, null);
1823 }
1824
1825 /**
1826 * Creates an instance of <code>JOptionPane</code> to display a message
1827 * with the specified message type, icon, and options, with the
1828 * initially-selected option specified.
1829 *
1830 * @param message the <code>Object</code> to display
1831 * @param messageType the type of message to be displayed:
1832 * <code>ERROR_MESSAGE</code>,
1833 * <code>INFORMATION_MESSAGE</code>,
1834 * <code>WARNING_MESSAGE</code>,
1835 * <code>QUESTION_MESSAGE</code>,
1836 * or <code>PLAIN_MESSAGE</code>
1837 * @param optionType the options to display in the pane:
1838 * <code>DEFAULT_OPTION</code>,
1839 * <code>YES_NO_OPTION</code>,
1840 * <code>YES_NO_CANCEL_OPTION</code>,
1841 * <code>OK_CANCEL_OPTION</code>
1842 * @param icon the Icon image to display
1843 * @param options the choices the user can select
1844 * @param initialValue the choice that is initially selected; if
1845 * <code>null</code>, then nothing will be initially selected;
1846 * only meaningful if <code>options</code> is used
1847 */
1848 public JOptionPane(Object message, int messageType, int optionType,
1849 Icon icon, Object[] options, Object initialValue) {
1850
1851 this .message = message;
1852 this .options = options;
1853 this .initialValue = initialValue;
1854 this .icon = icon;
1855 setMessageType(messageType);
1856 setOptionType(optionType);
1857 value = UNINITIALIZED_VALUE;
1858 inputValue = UNINITIALIZED_VALUE;
1859 updateUI();
1860 }
1861
1862 /**
1863 * Sets the UI object which implements the L&F for this component.
1864 *
1865 * @param ui the <code>OptionPaneUI</code> L&F object
1866 * @see UIDefaults#getUI
1867 * @beaninfo
1868 * bound: true
1869 * hidden: true
1870 * description: The UI object that implements the optionpane's LookAndFeel
1871 */
1872 public void setUI(OptionPaneUI ui) {
1873 if ((OptionPaneUI) this .ui != ui) {
1874 super .setUI(ui);
1875 invalidate();
1876 }
1877 }
1878
1879 /**
1880 * Returns the UI object which implements the L&F for this component.
1881 *
1882 * @return the <code>OptionPaneUI</code> object
1883 */
1884 public OptionPaneUI getUI() {
1885 return (OptionPaneUI) ui;
1886 }
1887
1888 /**
1889 * Notification from the <code>UIManager</code> that the L&F has changed.
1890 * Replaces the current UI object with the latest version from the
1891 * <code>UIManager</code>.
1892 *
1893 * @see JComponent#updateUI
1894 */
1895 public void updateUI() {
1896 setUI((OptionPaneUI) UIManager.getUI(this ));
1897 }
1898
1899 /**
1900 * Returns the name of the UI class that implements the
1901 * L&F for this component.
1902 *
1903 * @return the string "OptionPaneUI"
1904 * @see JComponent#getUIClassID
1905 * @see UIDefaults#getUI
1906 */
1907 public String getUIClassID() {
1908 return uiClassID;
1909 }
1910
1911 /**
1912 * Sets the option pane's message-object.
1913 * @param newMessage the <code>Object</code> to display
1914 * @see #getMessage
1915 *
1916 * @beaninfo
1917 * preferred: true
1918 * bound: true
1919 * description: The optionpane's message object.
1920 */
1921 public void setMessage(Object newMessage) {
1922 Object oldMessage = message;
1923
1924 message = newMessage;
1925 firePropertyChange(MESSAGE_PROPERTY, oldMessage, message);
1926 }
1927
1928 /**
1929 * Returns the message-object this pane displays.
1930 * @see #setMessage
1931 *
1932 * @return the <code>Object</code> that is displayed
1933 */
1934 public Object getMessage() {
1935 return message;
1936 }
1937
1938 /**
1939 * Sets the icon to display. If non-<code>null</code>, the look and feel
1940 * does not provide an icon.
1941 * @param newIcon the <code>Icon</code> to display
1942 *
1943 * @see #getIcon
1944 * @beaninfo
1945 * preferred: true
1946 * bound: true
1947 * description: The option pane's type icon.
1948 */
1949 public void setIcon(Icon newIcon) {
1950 Object oldIcon = icon;
1951
1952 icon = newIcon;
1953 firePropertyChange(ICON_PROPERTY, oldIcon, icon);
1954 }
1955
1956 /**
1957 * Returns the icon this pane displays.
1958 * @return the <code>Icon</code> that is displayed
1959 *
1960 * @see #setIcon
1961 */
1962 public Icon getIcon() {
1963 return icon;
1964 }
1965
1966 /**
1967 * Sets the value the user has chosen.
1968 * @param newValue the chosen value
1969 *
1970 * @see #getValue
1971 * @beaninfo
1972 * preferred: true
1973 * bound: true
1974 * description: The option pane's value object.
1975 */
1976 public void setValue(Object newValue) {
1977 Object oldValue = value;
1978
1979 value = newValue;
1980 firePropertyChange(VALUE_PROPERTY, oldValue, value);
1981 }
1982
1983 /**
1984 * Returns the value the user has selected. <code>UNINITIALIZED_VALUE</code>
1985 * implies the user has not yet made a choice, <code>null</code> means the
1986 * user closed the window with out choosing anything. Otherwise
1987 * the returned value will be one of the options defined in this
1988 * object.
1989 *
1990 * @return the <code>Object</code> chosen by the user,
1991 * <code>UNINITIALIZED_VALUE</code>
1992 * if the user has not yet made a choice, or <code>null</code> if
1993 * the user closed the window without making a choice
1994 *
1995 * @see #setValue
1996 */
1997 public Object getValue() {
1998 return value;
1999 }
2000
2001 /**
2002 * Sets the options this pane displays. If an element in
2003 * <code>newOptions</code> is a <code>Component</code>
2004 * it is added directly to the pane,
2005 * otherwise a button is created for the element.
2006 *
2007 * @param newOptions an array of <code>Objects</code> that create the
2008 * buttons the user can click on, or arbitrary
2009 * <code>Components</code> to add to the pane
2010 *
2011 * @see #getOptions
2012 * @beaninfo
2013 * bound: true
2014 * description: The option pane's options objects.
2015 */
2016 public void setOptions(Object[] newOptions) {
2017 Object[] oldOptions = options;
2018
2019 options = newOptions;
2020 firePropertyChange(OPTIONS_PROPERTY, oldOptions, options);
2021 }
2022
2023 /**
2024 * Returns the choices the user can make.
2025 * @return the array of <code>Objects</code> that give the user's choices
2026 *
2027 * @see #setOptions
2028 */
2029 public Object[] getOptions() {
2030 if (options != null) {
2031 int optionCount = options.length;
2032 Object[] retOptions = new Object[optionCount];
2033
2034 System.arraycopy(options, 0, retOptions, 0, optionCount);
2035 return retOptions;
2036 }
2037 return options;
2038 }
2039
2040 /**
2041 * Sets the initial value that is to be enabled -- the
2042 * <code>Component</code>
2043 * that has the focus when the pane is initially displayed.
2044 *
2045 * @param newInitialValue the <code>Object</code> that gets the initial
2046 * keyboard focus
2047 *
2048 * @see #getInitialValue
2049 * @beaninfo
2050 * preferred: true
2051 * bound: true
2052 * description: The option pane's initial value object.
2053 */
2054 public void setInitialValue(Object newInitialValue) {
2055 Object oldIV = initialValue;
2056
2057 initialValue = newInitialValue;
2058 firePropertyChange(INITIAL_VALUE_PROPERTY, oldIV, initialValue);
2059 }
2060
2061 /**
2062 * Returns the initial value.
2063 *
2064 * @return the <code>Object</code> that gets the initial keyboard focus
2065 *
2066 * @see #setInitialValue
2067 */
2068 public Object getInitialValue() {
2069 return initialValue;
2070 }
2071
2072 /**
2073 * Sets the option pane's message type.
2074 * The message type is used by the Look and Feel to determine the
2075 * icon to display (if not supplied) as well as potentially how to
2076 * lay out the <code>parentComponent</code>.
2077 * @param newType an integer specifying the kind of message to display:
2078 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
2079 * <code>WARNING_MESSAGE</code>,
2080 * <code>QUESTION_MESSAGE</code>, or <code>PLAIN_MESSAGE</code>
2081 * @exception RuntimeException if <code>newType</code> is not one of the
2082 * legal values listed above
2083
2084 * @see #getMessageType
2085 * @beaninfo
2086 * preferred: true
2087 * bound: true
2088 * description: The option pane's message type.
2089 */
2090 public void setMessageType(int newType) {
2091 if (newType != ERROR_MESSAGE && newType != INFORMATION_MESSAGE
2092 && newType != WARNING_MESSAGE
2093 && newType != QUESTION_MESSAGE
2094 && newType != PLAIN_MESSAGE)
2095 throw new RuntimeException(
2096 "JOptionPane: type must be one of JOptionPane.ERROR_MESSAGE, JOptionPane.INFORMATION_MESSAGE, JOptionPane.WARNING_MESSAGE, JOptionPane.QUESTION_MESSAGE or JOptionPane.PLAIN_MESSAGE");
2097
2098 int oldType = messageType;
2099
2100 messageType = newType;
2101 firePropertyChange(MESSAGE_TYPE_PROPERTY, oldType, messageType);
2102 }
2103
2104 /**
2105 * Returns the message type.
2106 *
2107 * @return an integer specifying the message type
2108 *
2109 * @see #setMessageType
2110 */
2111 public int getMessageType() {
2112 return messageType;
2113 }
2114
2115 /**
2116 * Sets the options to display.
2117 * The option type is used by the Look and Feel to
2118 * determine what buttons to show (unless options are supplied).
2119 * @param newType an integer specifying the options the L&F is to display:
2120 * <code>DEFAULT_OPTION</code>,
2121 * <code>YES_NO_OPTION</code>,
2122 * <code>YES_NO_CANCEL_OPTION</code>,
2123 * or <code>OK_CANCEL_OPTION</code>
2124 * @exception RuntimeException if <code>newType</code> is not one of
2125 * the legal values listed above
2126 *
2127 * @see #getOptionType
2128 * @see #setOptions
2129 * @beaninfo
2130 * preferred: true
2131 * bound: true
2132 * description: The option pane's option type.
2133 */
2134 public void setOptionType(int newType) {
2135 if (newType != DEFAULT_OPTION && newType != YES_NO_OPTION
2136 && newType != YES_NO_CANCEL_OPTION
2137 && newType != OK_CANCEL_OPTION)
2138 throw new RuntimeException(
2139 "JOptionPane: option type must be one of JOptionPane.DEFAULT_OPTION, JOptionPane.YES_NO_OPTION, JOptionPane.YES_NO_CANCEL_OPTION or JOptionPane.OK_CANCEL_OPTION");
2140
2141 int oldType = optionType;
2142
2143 optionType = newType;
2144 firePropertyChange(OPTION_TYPE_PROPERTY, oldType, optionType);
2145 }
2146
2147 /**
2148 * Returns the type of options that are displayed.
2149 *
2150 * @return an integer specifying the user-selectable options
2151 *
2152 * @see #setOptionType
2153 */
2154 public int getOptionType() {
2155 return optionType;
2156 }
2157
2158 /**
2159 * Sets the input selection values for a pane that provides the user
2160 * with a list of items to choose from. (The UI provides a widget
2161 * for choosing one of the values.) A <code>null</code> value
2162 * implies the user can input whatever they wish, usually by means
2163 * of a <code>JTextField</code>.
2164 * <p>
2165 * Sets <code>wantsInput</code> to true. Use
2166 * <code>setInitialSelectionValue</code> to specify the initially-chosen
2167 * value. After the pane as been enabled, <code>inputValue</code> is
2168 * set to the value the user has selected.
2169 * @param newValues an array of <code>Objects</code> the user to be
2170 * displayed
2171 * (usually in a list or combo-box) from which
2172 * the user can make a selection
2173 * @see #setWantsInput
2174 * @see #setInitialSelectionValue
2175 * @see #getSelectionValues
2176 * @beaninfo
2177 * bound: true
2178 * description: The option pane's selection values.
2179 */
2180 public void setSelectionValues(Object[] newValues) {
2181 Object[] oldValues = selectionValues;
2182
2183 selectionValues = newValues;
2184 firePropertyChange(SELECTION_VALUES_PROPERTY, oldValues,
2185 newValues);
2186 if (selectionValues != null)
2187 setWantsInput(true);
2188 }
2189
2190 /**
2191 * Returns the input selection values.
2192 *
2193 * @return the array of <code>Objects</code> the user can select
2194 * @see #setSelectionValues
2195 */
2196 public Object[] getSelectionValues() {
2197 return selectionValues;
2198 }
2199
2200 /**
2201 * Sets the input value that is initially displayed as selected to the user.
2202 * Only used if <code>wantsInput</code> is true.
2203 * @param newValue the initially selected value
2204 * @see #setSelectionValues
2205 * @see #getInitialSelectionValue
2206 * @beaninfo
2207 * bound: true
2208 * description: The option pane's initial selection value object.
2209 */
2210 public void setInitialSelectionValue(Object newValue) {
2211 Object oldValue = initialSelectionValue;
2212
2213 initialSelectionValue = newValue;
2214 firePropertyChange(INITIAL_SELECTION_VALUE_PROPERTY, oldValue,
2215 newValue);
2216 }
2217
2218 /**
2219 * Returns the input value that is displayed as initially selected to the user.
2220 *
2221 * @return the initially selected value
2222 * @see #setInitialSelectionValue
2223 * @see #setSelectionValues
2224 */
2225 public Object getInitialSelectionValue() {
2226 return initialSelectionValue;
2227 }
2228
2229 /**
2230 * Sets the input value that was selected or input by the user.
2231 * Only used if <code>wantsInput</code> is true. Note that this method
2232 * is invoked internally by the option pane (in response to user action)
2233 * and should generally not be called by client programs. To set the
2234 * input value initially displayed as selected to the user, use
2235 * <code>setInitialSelectionValue</code>.
2236 *
2237 * @param newValue the <code>Object</code> used to set the
2238 * value that the user specified (usually in a text field)
2239 * @see #setSelectionValues
2240 * @see #setInitialSelectionValue
2241 * @see #setWantsInput
2242 * @see #getInputValue
2243 * @beaninfo
2244 * preferred: true
2245 * bound: true
2246 * description: The option pane's input value object.
2247 */
2248 public void setInputValue(Object newValue) {
2249 Object oldValue = inputValue;
2250
2251 inputValue = newValue;
2252 firePropertyChange(INPUT_VALUE_PROPERTY, oldValue, newValue);
2253 }
2254
2255 /**
2256 * Returns the value the user has input, if <code>wantsInput</code>
2257 * is true.
2258 *
2259 * @return the <code>Object</code> the user specified,
2260 * if it was one of the objects, or a
2261 * <code>String</code> if it was a value typed into a
2262 * field
2263 * @see #setSelectionValues
2264 * @see #setWantsInput
2265 * @see #setInputValue
2266 */
2267 public Object getInputValue() {
2268 return inputValue;
2269 }
2270
2271 /**
2272 * Returns the maximum number of characters to place on a line in a
2273 * message. Default is to return <code>Integer.MAX_VALUE</code>.
2274 * The value can be
2275 * changed by overriding this method in a subclass.
2276 *
2277 * @return an integer giving the maximum number of characters on a line
2278 */
2279 public int getMaxCharactersPerLineCount() {
2280 return Integer.MAX_VALUE;
2281 }
2282
2283 /**
2284 * Sets the <code>wantsInput</code> property.
2285 * If <code>newValue</code> is true, an input component
2286 * (such as a text field or combo box) whose parent is
2287 * <code>parentComponent</code> is provided to
2288 * allow the user to input a value. If <code>getSelectionValues</code>
2289 * returns a non-<code>null</code> array, the input value is one of the
2290 * objects in that array. Otherwise the input value is whatever
2291 * the user inputs.
2292 * <p>
2293 * This is a bound property.
2294 *
2295 * @see #setSelectionValues
2296 * @see #setInputValue
2297 * @beaninfo
2298 * preferred: true
2299 * bound: true
2300 * description: Flag which allows the user to input a value.
2301 */
2302 public void setWantsInput(boolean newValue) {
2303 boolean oldValue = wantsInput;
2304
2305 wantsInput = newValue;
2306 firePropertyChange(WANTS_INPUT_PROPERTY, oldValue, newValue);
2307 }
2308
2309 /**
2310 * Returns the value of the <code>wantsInput</code> property.
2311 *
2312 * @return true if an input component will be provided
2313 * @see #setWantsInput
2314 */
2315 public boolean getWantsInput() {
2316 return wantsInput;
2317 }
2318
2319 /**
2320 * Requests that the initial value be selected, which will set
2321 * focus to the initial value. This method
2322 * should be invoked after the window containing the option pane
2323 * is made visible.
2324 */
2325 public void selectInitialValue() {
2326 OptionPaneUI ui = getUI();
2327 if (ui != null) {
2328 ui.selectInitialValue(this );
2329 }
2330 }
2331
2332 private static int styleFromMessageType(int messageType) {
2333 switch (messageType) {
2334 case ERROR_MESSAGE:
2335 return JRootPane.ERROR_DIALOG;
2336 case QUESTION_MESSAGE:
2337 return JRootPane.QUESTION_DIALOG;
2338 case WARNING_MESSAGE:
2339 return JRootPane.WARNING_DIALOG;
2340 case INFORMATION_MESSAGE:
2341 return JRootPane.INFORMATION_DIALOG;
2342 case PLAIN_MESSAGE:
2343 default:
2344 return JRootPane.PLAIN_DIALOG;
2345 }
2346 }
2347
2348 // Serialization support.
2349 private void writeObject(ObjectOutputStream s) throws IOException {
2350 Vector values = new Vector();
2351
2352 s.defaultWriteObject();
2353 // Save the icon, if its Serializable.
2354 if (icon != null && icon instanceof Serializable) {
2355 values.addElement("icon");
2356 values.addElement(icon);
2357 }
2358 // Save the message, if its Serializable.
2359 if (message != null && message instanceof Serializable) {
2360 values.addElement("message");
2361 values.addElement(message);
2362 }
2363 // Save the treeModel, if its Serializable.
2364 if (options != null) {
2365 Vector serOptions = new Vector();
2366
2367 for (int counter = 0, maxCounter = options.length; counter < maxCounter; counter++)
2368 if (options[counter] instanceof Serializable)
2369 serOptions.addElement(options[counter]);
2370 if (serOptions.size() > 0) {
2371 int optionCount = serOptions.size();
2372 Object[] arrayOptions = new Object[optionCount];
2373
2374 serOptions.copyInto(arrayOptions);
2375 values.addElement("options");
2376 values.addElement(arrayOptions);
2377 }
2378 }
2379 // Save the initialValue, if its Serializable.
2380 if (initialValue != null
2381 && initialValue instanceof Serializable) {
2382 values.addElement("initialValue");
2383 values.addElement(initialValue);
2384 }
2385 // Save the value, if its Serializable.
2386 if (value != null && value instanceof Serializable) {
2387 values.addElement("value");
2388 values.addElement(value);
2389 }
2390 // Save the selectionValues, if its Serializable.
2391 if (selectionValues != null) {
2392 boolean serialize = true;
2393
2394 for (int counter = 0, maxCounter = selectionValues.length; counter < maxCounter; counter++) {
2395 if (selectionValues[counter] != null
2396 && !(selectionValues[counter] instanceof Serializable)) {
2397 serialize = false;
2398 break;
2399 }
2400 }
2401 if (serialize) {
2402 values.addElement("selectionValues");
2403 values.addElement(selectionValues);
2404 }
2405 }
2406 // Save the inputValue, if its Serializable.
2407 if (inputValue != null && inputValue instanceof Serializable) {
2408 values.addElement("inputValue");
2409 values.addElement(inputValue);
2410 }
2411 // Save the initialSelectionValue, if its Serializable.
2412 if (initialSelectionValue != null
2413 && initialSelectionValue instanceof Serializable) {
2414 values.addElement("initialSelectionValue");
2415 values.addElement(initialSelectionValue);
2416 }
2417 s.writeObject(values);
2418 }
2419
2420 private void readObject(ObjectInputStream s) throws IOException,
2421 ClassNotFoundException {
2422 s.defaultReadObject();
2423
2424 Vector values = (Vector) s.readObject();
2425 int indexCounter = 0;
2426 int maxCounter = values.size();
2427
2428 if (indexCounter < maxCounter
2429 && values.elementAt(indexCounter).equals("icon")) {
2430 icon = (Icon) values.elementAt(++indexCounter);
2431 indexCounter++;
2432 }
2433 if (indexCounter < maxCounter
2434 && values.elementAt(indexCounter).equals("message")) {
2435 message = values.elementAt(++indexCounter);
2436 indexCounter++;
2437 }
2438 if (indexCounter < maxCounter
2439 && values.elementAt(indexCounter).equals("options")) {
2440 options = (Object[]) values.elementAt(++indexCounter);
2441 indexCounter++;
2442 }
2443 if (indexCounter < maxCounter
2444 && values.elementAt(indexCounter)
2445 .equals("initialValue")) {
2446 initialValue = values.elementAt(++indexCounter);
2447 indexCounter++;
2448 }
2449 if (indexCounter < maxCounter
2450 && values.elementAt(indexCounter).equals("value")) {
2451 value = values.elementAt(++indexCounter);
2452 indexCounter++;
2453 }
2454 if (indexCounter < maxCounter
2455 && values.elementAt(indexCounter).equals(
2456 "selectionValues")) {
2457 selectionValues = (Object[]) values
2458 .elementAt(++indexCounter);
2459 indexCounter++;
2460 }
2461 if (indexCounter < maxCounter
2462 && values.elementAt(indexCounter).equals("inputValue")) {
2463 inputValue = values.elementAt(++indexCounter);
2464 indexCounter++;
2465 }
2466 if (indexCounter < maxCounter
2467 && values.elementAt(indexCounter).equals(
2468 "initialSelectionValue")) {
2469 initialSelectionValue = values.elementAt(++indexCounter);
2470 indexCounter++;
2471 }
2472 if (getUIClassID().equals(uiClassID)) {
2473 byte count = JComponent.getWriteObjCounter(this );
2474 JComponent.setWriteObjCounter(this , --count);
2475 if (count == 0 && ui != null) {
2476 ui.installUI(this );
2477 }
2478 }
2479 }
2480
2481 /**
2482 * Returns a string representation of this <code>JOptionPane</code>.
2483 * This method
2484 * is intended to be used only for debugging purposes, and the
2485 * content and format of the returned string may vary between
2486 * implementations. The returned string may be empty but may not
2487 * be <code>null</code>.
2488 *
2489 * @return a string representation of this <code>JOptionPane</code>
2490 */
2491 protected String paramString() {
2492 String iconString = (icon != null ? icon.toString() : "");
2493 String initialValueString = (initialValue != null ? initialValue
2494 .toString()
2495 : "");
2496 String messageString = (message != null ? message.toString()
2497 : "");
2498 String messageTypeString;
2499 if (messageType == ERROR_MESSAGE) {
2500 messageTypeString = "ERROR_MESSAGE";
2501 } else if (messageType == INFORMATION_MESSAGE) {
2502 messageTypeString = "INFORMATION_MESSAGE";
2503 } else if (messageType == WARNING_MESSAGE) {
2504 messageTypeString = "WARNING_MESSAGE";
2505 } else if (messageType == QUESTION_MESSAGE) {
2506 messageTypeString = "QUESTION_MESSAGE";
2507 } else if (messageType == PLAIN_MESSAGE) {
2508 messageTypeString = "PLAIN_MESSAGE";
2509 } else
2510 messageTypeString = "";
2511 String optionTypeString;
2512 if (optionType == DEFAULT_OPTION) {
2513 optionTypeString = "DEFAULT_OPTION";
2514 } else if (optionType == YES_NO_OPTION) {
2515 optionTypeString = "YES_NO_OPTION";
2516 } else if (optionType == YES_NO_CANCEL_OPTION) {
2517 optionTypeString = "YES_NO_CANCEL_OPTION";
2518 } else if (optionType == OK_CANCEL_OPTION) {
2519 optionTypeString = "OK_CANCEL_OPTION";
2520 } else
2521 optionTypeString = "";
2522 String wantsInputString = (wantsInput ? "true" : "false");
2523
2524 return super .paramString() + ",icon=" + iconString
2525 + ",initialValue=" + initialValueString + ",message="
2526 + messageString + ",messageType=" + messageTypeString
2527 + ",optionType=" + optionTypeString + ",wantsInput="
2528 + wantsInputString;
2529 }
2530
2531 /**
2532 * Retrieves a method from the provided class and makes it accessible.
2533 */
2534 private static class ModalPrivilegedAction implements
2535 PrivilegedAction {
2536 private Class clazz;
2537 private String methodName;
2538
2539 public ModalPrivilegedAction(Class clazz, String methodName) {
2540 this .clazz = clazz;
2541 this .methodName = methodName;
2542 }
2543
2544 public Object run() {
2545 Method method = null;
2546 try {
2547 method = clazz.getDeclaredMethod(methodName,
2548 (Class[]) null);
2549 } catch (NoSuchMethodException ex) {
2550 }
2551 if (method != null) {
2552 method.setAccessible(true);
2553 }
2554 return method;
2555 }
2556 }
2557
2558 ///////////////////
2559 // Accessibility support
2560 ///////////////////
2561
2562 /**
2563 * Returns the <code>AccessibleContext</code> associated with this JOptionPane.
2564 * For option panes, the <code>AccessibleContext</code> takes the form of an
2565 * <code>AccessibleJOptionPane</code>.
2566 * A new <code>AccessibleJOptionPane</code> instance is created if necessary.
2567 *
2568 * @return an AccessibleJOptionPane that serves as the
2569 * AccessibleContext of this AccessibleJOptionPane
2570 * @beaninfo
2571 * expert: true
2572 * description: The AccessibleContext associated with this option pane
2573 */
2574 public AccessibleContext getAccessibleContext() {
2575 if (accessibleContext == null) {
2576 accessibleContext = new AccessibleJOptionPane();
2577 }
2578 return accessibleContext;
2579 }
2580
2581 /**
2582 * This class implements accessibility support for the
2583 * <code>JOptionPane</code> class. It provides an implementation of the
2584 * Java Accessibility API appropriate to option pane user-interface
2585 * elements.
2586 * <p>
2587 * <strong>Warning:</strong>
2588 * Serialized objects of this class will not be compatible with
2589 * future Swing releases. The current serialization support is
2590 * appropriate for short term storage or RMI between applications running
2591 * the same version of Swing. As of 1.4, support for long term storage
2592 * of all JavaBeans<sup><font size="-2">TM</font></sup>
2593 * has been added to the <code>java.beans</code> package.
2594 * Please see {@link java.beans.XMLEncoder}.
2595 */
2596 protected class AccessibleJOptionPane extends AccessibleJComponent {
2597
2598 /**
2599 * Get the role of this object.
2600 *
2601 * @return an instance of AccessibleRole describing the role of the object
2602 * @see AccessibleRole
2603 */
2604 public AccessibleRole getAccessibleRole() {
2605 switch (messageType) {
2606 case ERROR_MESSAGE:
2607 case INFORMATION_MESSAGE:
2608 case WARNING_MESSAGE:
2609 return AccessibleRole.ALERT;
2610
2611 default:
2612 return AccessibleRole.OPTION_PANE;
2613 }
2614 }
2615
2616 } // inner class AccessibleJOptionPane
2617 }
|