|
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 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 } |