1 /*
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
26 package javax.swing;
27
28 import java.awt.BorderLayout;
29 import java.awt.Component;
30 import java.awt.Container;
31 import java.awt.Dialog;
32 import java.awt.Dimension;
33 import java.awt.KeyboardFocusManager;
34 import java.awt.Frame;
35 import java.awt.Point;
36 import java.awt.HeadlessException;
37 import java.awt.Toolkit;
38 import java.awt.Window;
39 import java.beans.PropertyChangeEvent;
40 import java.beans.PropertyChangeListener;
41 import java.awt.event.WindowListener;
42 import java.awt.event.WindowAdapter;
43 import java.awt.event.WindowEvent;
44 import java.awt.event.ComponentAdapter;
45 import java.awt.event.ComponentEvent;
46 import java.io.IOException;
47 import java.io.ObjectInputStream;
48 import java.io.ObjectOutputStream;
49 import java.io.Serializable;
50 import java.lang.reflect.Method;
51 import java.lang.reflect.InvocationTargetException;
52 import java.security.AccessController;
53 import java.security.PrivilegedAction;
54 import java.util.Vector;
55 import javax.swing.plaf.OptionPaneUI;
56 import javax.swing.event.InternalFrameEvent;
57 import javax.swing.event.InternalFrameAdapter;
58 import javax.accessibility;
59 import 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 */
315 public 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 Integer.valueOf(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