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