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