| CWOptionPane.java |
1 /**
2 * Distribution License:
3 * JSword is free software; you can redistribute it and/or modify it under
4 * the terms of the GNU Lesser General Public License, version 2.1 as published by
5 * the Free Software Foundation. This program is distributed in the hope
6 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8 * See the GNU Lesser General Public License for more details.
9 *
10 * The License is available on the internet at:
11 * http://www.gnu.org/copyleft/lgpl.html
12 * or by writing to:
13 * Free Software Foundation, Inc.
14 * 59 Temple Place - Suite 330
15 * Boston, MA 02111-1307, USA
16 *
17 * Copyright: 2008
18 * The copyright to this program is held by it's authors.
19 *
20 * ID: $Id: org.eclipse.jdt.ui.prefs 1178 2006-11-06 12:48:02Z dmsmith $
21 */
22 package org.crosswire.common.swing;
23
24 import java.awt.BorderLayout;
25 import java.awt.Component;
26 import java.awt.Container;
27 import java.awt.Dialog;
28 import java.awt.Frame;
29 import java.awt.HeadlessException;
30 import java.awt.Window;
31 import java.awt.event.ComponentAdapter;
32 import java.awt.event.ComponentEvent;
33 import java.awt.event.WindowAdapter;
34 import java.awt.event.WindowEvent;
35 import java.beans.PropertyChangeEvent;
36 import java.beans.PropertyChangeListener;
37
38 import javax.swing.Action;
39 import javax.swing.Icon;
40 import javax.swing.JDialog;
41 import javax.swing.JOptionPane;
42 import javax.swing.JRootPane;
43 import javax.swing.UIManager;
44
45 /**
46 * CWOptionPane is just like JOptionPane, but internationalize the button text
47 * for some languages that Java does not handle, for which JSword has
48 * translations.
49 *
50 * @see gnu.lgpl.License for license details.<br>
51 * The copyright to this program is held by it's authors.
52 * @author DM Smith [dmsmith555 at yahoo dot com]
53 */
54 public class CWOptionPane extends JOptionPane {
55
56 /**
57 * Creates a <code>CWOptionPane</code> with a test message.
58 */
59 public CWOptionPane() {
60 this("CWOptionPane message", PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null);
61 }
62
63 /**
64 * Creates a instance of <code>CWOptionPane</code> to display a message
65 * using the plain-message message type and the default options delivered by
66 * the UI.
67 *
68 * @param message
69 * the <code>Object</code> to display
70 */
71 public CWOptionPane(Object message) {
72 this(message, PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null);
73 }
74
75 /**
76 * Creates an instance of <code>CWOptionPane</code> to display a message
77 * with the specified message type and the default options,
78 *
79 * @param message
80 * the <code>Object</code> to display
81 * @param messageType
82 * the type of message to be displayed:
83 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
84 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
85 * or <code>PLAIN_MESSAGE</code>
86 */
87 public CWOptionPane(Object message, int messageType) {
88 this(message, messageType, DEFAULT_OPTION, null, null, null);
89 }
90
91 /**
92 * Creates an instance of <code>CWOptionPane</code> to display a message
93 * with the specified message type and options.
94 *
95 * @param message
96 * the <code>Object</code> to display
97 * @param messageType
98 * the type of message to be displayed:
99 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
100 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
101 * or <code>PLAIN_MESSAGE</code>
102 * @param optionType
103 * the options to display in the pane:
104 * <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>,
105 * <code>YES_NO_CANCEL_OPTION</code>,
106 * <code>OK_CANCEL_OPTION</code>
107 */
108 public CWOptionPane(Object message, int messageType, int optionType) {
109 this(message, messageType, optionType, null, null, null);
110 }
111
112 /**
113 * Creates an instance of <code>CWOptionPane</code> to display a message
114 * with the specified message type, options, and icon.
115 *
116 * @param message
117 * the <code>Object</code> to display
118 * @param messageType
119 * the type of message to be displayed:
120 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
121 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
122 * or <code>PLAIN_MESSAGE</code>
123 * @param optionType
124 * the options to display in the pane:
125 * <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>,
126 * <code>YES_NO_CANCEL_OPTION</code>,
127 * <code>OK_CANCEL_OPTION</code>
128 * @param icon
129 * the <code>Icon</code> image to display
130 */
131 public CWOptionPane(Object message, int messageType, int optionType, Icon icon) {
132 this(message, messageType, optionType, icon, null, null);
133 }
134
135 /**
136 * Creates an instance of <code>CWOptionPane</code> to display a message
137 * with the specified message type, icon, and options. None of the options
138 * is initially selected.
139 * <p>
140 * The options objects should contain either instances of
141 * <code>Component</code>s, (which are added directly) or
142 * <code>Strings</code> (which are wrapped in a <code>JButton</code>). If
143 * you provide <code>Component</code>s, you must ensure that when the
144 * <code>Component</code> is clicked it messages <code>setValue</code> in
145 * the created <code>CWOptionPane</code>.
146 *
147 * @param message
148 * the <code>Object</code> to display
149 * @param messageType
150 * the type of message to be displayed:
151 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
152 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
153 * or <code>PLAIN_MESSAGE</code>
154 * @param optionType
155 * the options to display in the pane:
156 * <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>,
157 * <code>YES_NO_CANCEL_OPTION</code>,
158 * <code>OK_CANCEL_OPTION</code>
159 * @param icon
160 * the <code>Icon</code> image to display
161 * @param options
162 * the choices the user can select
163 */
164 public CWOptionPane(Object message, int messageType, int optionType, Icon icon, Object[] options) {
165 this(message, messageType, optionType, icon, options, null);
166
167 GuiUtil.applyDefaultOrientation(this);
168 }
169
170 /**
171 * Creates an instance of <code>CWOptionPane</code> to display a message
172 * with the specified message type, icon, and options, with the
173 * initially-selected option specified.
174 *
175 * @param message
176 * the <code>Object</code> to display
177 * @param messageType
178 * the type of message to be displayed:
179 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
180 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
181 * or <code>PLAIN_MESSAGE</code>
182 * @param optionType
183 * the options to display in the pane:
184 * <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>,
185 * <code>YES_NO_CANCEL_OPTION</code>,
186 * <code>OK_CANCEL_OPTION</code>
187 * @param icon
188 * the Icon image to display
189 * @param options
190 * the choices the user can select
191 * @param initialValue
192 * the choice that is initially selected; if <code>null</code>,
193 * then nothing will be initially selected; only meaningful if
194 * <code>options</code> is used
195 */
196 public CWOptionPane(Object message, int messageType, int optionType, Icon icon, Object[] options, Object initialValue) {
197 super(message, messageType, optionType, icon, CWOptionPane.fixOptions(options, optionType, messageType), initialValue);
198 }
199
200 /**
201 * Shows a question-message dialog requesting input from the user. The
202 * dialog uses the default frame, which usually means it is centered on the
203 * screen.
204 *
205 * @param message
206 * the <code>Object</code> to display
207 * @exception HeadlessException
208 * if <code>GraphicsEnvironment.isHeadless</code> returns
209 * <code>true</code>
210 * @see java.awt.GraphicsEnvironment#isHeadless
211 */
212 public static String showInputDialog(Object message) throws HeadlessException {
213 return showInputDialog(null, message);
214 }
215
216 /**
217 * Shows a question-message dialog requesting input from the user, with the
218 * input value initialized to <code>initialSelectionValue</code>. The dialog
219 * uses the default frame, which usually means it is centered on the screen.
220 *
221 * @param message
222 * the <code>Object</code> to display
223 * @param initialSelectionValue
224 * the value used to initialize the input field
225 */
226 public static String showInputDialog(Object message, Object initialSelectionValue) {
227 return showInputDialog(null, message, initialSelectionValue);
228 }
229
230 /**
231 * Shows a question-message dialog requesting input from the user parented
232 * to <code>parentComponent</code>. The dialog is displayed on top of the
233 * <code>Component</code>'s frame, and is usually positioned below the
234 * <code>Component</code>.
235 *
236 * @param parentComponent
237 * the parent <code>Component</code> for the dialog
238 * @param message
239 * the <code>Object</code> to display
240 * @exception HeadlessException
241 * if <code>GraphicsEnvironment.isHeadless</code> returns
242 * <code>true</code>
243 * @see java.awt.GraphicsEnvironment#isHeadless
244 */
245 public static String showInputDialog(Component parentComponent, Object message) throws HeadlessException {
246 return showInputDialog(parentComponent, message, "?", QUESTION_MESSAGE);
247 }
248
249 /**
250 * Shows a question-message dialog requesting input from the user and
251 * parented to <code>parentComponent</code>. The input value will be
252 * initialized to <code>initialSelectionValue</code>. The dialog is
253 * displayed on top of the <code>Component</code>'s frame, and is usually
254 * positioned below the <code>Component</code>.
255 *
256 * @param parentComponent
257 * the parent <code>Component</code> for the dialog
258 * @param message
259 * the <code>Object</code> to display
260 * @param initialSelectionValue
261 * the value used to initialize the input field
262 */
263 public static String showInputDialog(Component parentComponent, Object message, Object initialSelectionValue) {
264 return (String) showInputDialog(parentComponent, message, "?", QUESTION_MESSAGE, null, null, initialSelectionValue);
265 }
266
267 /**
268 * Shows a dialog requesting input from the user parented to
269 * <code>parentComponent</code> with the dialog having the title
270 * <code>title</code> and message type <code>messageType</code>.
271 *
272 * @param parentComponent
273 * the parent <code>Component</code> for the dialog
274 * @param message
275 * the <code>Object</code> to display
276 * @param title
277 * the <code>String</code> to display in the dialog title bar
278 * @param messageType
279 * the type of message that is to be displayed:
280 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
281 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
282 * or <code>PLAIN_MESSAGE</code>
283 * @exception HeadlessException
284 * if <code>GraphicsEnvironment.isHeadless</code> returns
285 * <code>true</code>
286 * @see java.awt.GraphicsEnvironment#isHeadless
287 */
288 public static String showInputDialog(Component parentComponent, Object message, String title, int messageType) throws HeadlessException {
289 return (String) showInputDialog(parentComponent, message, title, messageType, null, null, null);
290 }
291
292 /**
293 * Prompts the user for input in a blocking dialog where the initial
294 * selection, possible selections, and all other options can be specified.
295 * The user will able to choose from <code>selectionValues</code>, where
296 * <code>null</code> implies the user can input whatever they wish, usually
297 * by means of a <code>JTextField</code>. <code>initialSelectionValue</code>
298 * is the initial value to prompt the user with. It is up to the UI to
299 * decide how best to represent the <code>selectionValues</code>, but
300 * usually a <code>JComboBox</code>, <code>JList</code>, or
301 * <code>JTextField</code> will be used.
302 *
303 * @param parentComponent
304 * the parent <code>Component</code> for the dialog
305 * @param message
306 * the <code>Object</code> to display
307 * @param title
308 * the <code>String</code> to display in the dialog title bar
309 * @param messageType
310 * the type of message to be displayed:
311 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
312 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
313 * or <code>PLAIN_MESSAGE</code>
314 * @param icon
315 * the <code>Icon</code> image to display
316 * @param selectionValues
317 * an array of <code>Object</code>s that gives the possible
318 * selections
319 * @param initialSelectionValue
320 * the value used to initialize the input field
321 * @return user's input, or <code>null</code> meaning the user canceled the
322 * input
323 * @exception HeadlessException
324 * if <code>GraphicsEnvironment.isHeadless</code> returns
325 * <code>true</code>
326 * @see java.awt.GraphicsEnvironment#isHeadless
327 */
328 public static Object showInputDialog(Component parentComponent, Object message, String title, int messageType, Icon icon, Object[] selectionValues,
329 Object initialSelectionValue) throws HeadlessException
330 {
331 CWOptionPane pane = new CWOptionPane(message, messageType, OK_CANCEL_OPTION, icon, null, null);
332
333 pane.setWantsInput(true);
334 pane.setSelectionValues(selectionValues);
335 pane.setInitialSelectionValue(initialSelectionValue);
336 GuiUtil.applyDefaultOrientation(pane);
337
338 int style = styleFromMessageType(messageType);
339 JDialog dialog = pane.createDialog(parentComponent, title, style);
340
341 pane.selectInitialValue();
342 dialog.setVisible(true);
343 dialog.dispose();
344
345 Object value = pane.getInputValue();
346
347 if (value == UNINITIALIZED_VALUE) {
348 return null;
349 }
350
351 return value;
352 }
353
354 /**
355 * Brings up an information-message dialog titled "Message".
356 *
357 * @param parentComponent
358 * determines the <code>Frame</code> in which the dialog is
359 * displayed; if <code>null</code>, or if the
360 * <code>parentComponent</code> has no <code>Frame</code>, a
361 * default <code>Frame</code> is used
362 * @param message
363 * the <code>Object</code> to display
364 * @exception HeadlessException
365 * if <code>GraphicsEnvironment.isHeadless</code> returns
366 * <code>true</code>
367 * @see java.awt.GraphicsEnvironment#isHeadless
368 */
369 public static void showMessageDialog(Component parentComponent, Object message) throws HeadlessException {
370 showOptionDialog(parentComponent, message, "?", DEFAULT_OPTION, INFORMATION_MESSAGE, null, null, null);
371 }
372
373 /**
374 * Brings up a dialog that displays a message using a default icon
375 * determined by the <code>messageType</code> parameter.
376 *
377 * @param parentComponent
378 * determines the <code>Frame</code> in which the dialog is
379 * displayed; if <code>null</code>, or if the
380 * <code>parentComponent</code> has no <code>Frame</code>, a
381 * default <code>Frame</code> is used
382 * @param message
383 * the <code>Object</code> to display
384 * @param title
385 * the title string for the dialog
386 * @param messageType
387 * the type of message to be displayed:
388 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
389 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
390 * or <code>PLAIN_MESSAGE</code>
391 * @exception HeadlessException
392 * if <code>GraphicsEnvironment.isHeadless</code> returns
393 * <code>true</code>
394 * @see java.awt.GraphicsEnvironment#isHeadless
395 */
396 public static void showMessageDialog(Component parentComponent, Object message, String title, int messageType) throws HeadlessException {
397 showOptionDialog(parentComponent, message, title, DEFAULT_OPTION, messageType, null, null, null);
398 }
399
400 /**
401 * Brings up a dialog displaying a message, specifying all parameters.
402 *
403 * @param parentComponent
404 * determines the <code>Frame</code> in which the dialog is
405 * displayed; if <code>null</code>, or if the
406 * <code>parentComponent</code> has no <code>Frame</code>, a
407 * default <code>Frame</code> is used
408 * @param message
409 * the <code>Object</code> to display
410 * @param title
411 * the title string for the dialog
412 * @param messageType
413 * the type of message to be displayed:
414 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
415 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
416 * or <code>PLAIN_MESSAGE</code>
417 * @param icon
418 * an icon to display in the dialog that helps the user identify
419 * the kind of message that is being displayed
420 * @exception HeadlessException
421 * if <code>GraphicsEnvironment.isHeadless</code> returns
422 * <code>true</code>
423 * @see java.awt.GraphicsEnvironment#isHeadless
424 */
425 public static void showMessageDialog(Component parentComponent, Object message, String title, int messageType, Icon icon) throws HeadlessException {
426 showOptionDialog(parentComponent, message, title, DEFAULT_OPTION, messageType, icon, null, null);
427 }
428
429 /**
430 * Brings up a dialog with the options <i>Yes</i>, <i>No</i> and
431 * <i>Cancel</i>; with the title, <b>Select an Option</b>.
432 *
433 * @param parentComponent
434 * determines the <code>Frame</code> in which the dialog is
435 * displayed; if <code>null</code>, or if the
436 * <code>parentComponent</code> has no <code>Frame</code>, a
437 * default <code>Frame</code> is used
438 * @param message
439 * the <code>Object</code> to display
440 * @return an integer indicating the option selected by the user
441 * @exception HeadlessException
442 * if <code>GraphicsEnvironment.isHeadless</code> returns
443 * <code>true</code>
444 * @see java.awt.GraphicsEnvironment#isHeadless
445 */
446 public static int showConfirmDialog(Component parentComponent, Object message) throws HeadlessException {
447 return showOptionDialog(parentComponent, message, "?", YES_NO_CANCEL_OPTION, QUESTION_MESSAGE, null, null, null);
448 }
449
450 /**
451 * Brings up a dialog where the number of choices is determined by the
452 * <code>optionType</code> parameter.
453 *
454 * @param parentComponent
455 * determines the <code>Frame</code> in which the dialog is
456 * displayed; if <code>null</code>, or if the
457 * <code>parentComponent</code> has no <code>Frame</code>, a
458 * default <code>Frame</code> is used
459 * @param message
460 * the <code>Object</code> to display
461 * @param title
462 * the title string for the dialog
463 * @param optionType
464 * an int designating the options available on the dialog:
465 * <code>YES_NO_OPTION</code>, or
466 * <code>YES_NO_CANCEL_OPTION</code>
467 * @return an int indicating the option selected by the user
468 * @exception HeadlessException
469 * if <code>GraphicsEnvironment.isHeadless</code> returns
470 * <code>true</code>
471 * @see java.awt.GraphicsEnvironment#isHeadless
472 */
473 public static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType) throws HeadlessException {
474 return showOptionDialog(parentComponent, message, title, optionType, QUESTION_MESSAGE, null, null, null);
475 }
476
477 /**
478 * Brings up a dialog where the number of choices is determined by the
479 * <code>optionType</code> parameter, where the <code>messageType</code>
480 * parameter determines the icon to display. The <code>messageType</code>
481 * parameter is primarily used to supply a default icon from the Look and
482 * Feel.
483 *
484 * @param parentComponent
485 * determines the <code>Frame</code> in which the dialog is
486 * displayed; if <code>null</code>, or if the
487 * <code>parentComponent</code> has no <code>Frame</code>, a
488 * default <code>Frame</code> is used.
489 * @param message
490 * the <code>Object</code> to display
491 * @param title
492 * the title string for the dialog
493 * @param optionType
494 * an integer designating the options available on the dialog:
495 * <code>YES_NO_OPTION</code>, or
496 * <code>YES_NO_CANCEL_OPTION</code>
497 * @param messageType
498 * an integer designating the kind of message this is; primarily
499 * used to determine the icon from the pluggable Look and Feel:
500 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
501 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
502 * or <code>PLAIN_MESSAGE</code>
503 * @return an integer indicating the option selected by the user
504 * @exception HeadlessException
505 * if <code>GraphicsEnvironment.isHeadless</code> returns
506 * <code>true</code>
507 * @see java.awt.GraphicsEnvironment#isHeadless
508 */
509 public static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType) throws HeadlessException {
510 return showOptionDialog(parentComponent, message, title, optionType, messageType, null, null, null);
511 }
512
513 /**
514 * Brings up a dialog with a specified icon, where the number of choices is
515 * determined by the <code>optionType</code> parameter. The
516 * <code>messageType</code> parameter is primarily used to supply a default
517 * icon from the look and feel.
518 *
519 * @param parentComponent
520 * determines the <code>Frame</code> in which the dialog is
521 * displayed; if <code>null</code>, or if the
522 * <code>parentComponent</code> has no <code>Frame</code>, a
523 * default <code>Frame</code> is used
524 * @param message
525 * the Object to display
526 * @param title
527 * the title string for the dialog
528 * @param optionType
529 * an int designating the options available on the dialog:
530 * <code>YES_NO_OPTION</code>, or
531 * <code>YES_NO_CANCEL_OPTION</code>
532 * @param messageType
533 * an int designating the kind of message this is, primarily used
534 * to determine the icon from the pluggable Look and Feel:
535 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
536 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
537 * or <code>PLAIN_MESSAGE</code>
538 * @param icon
539 * the icon to display in the dialog
540 * @return an int indicating the option selected by the user
541 * @exception HeadlessException
542 * if <code>GraphicsEnvironment.isHeadless</code> returns
543 * <code>true</code>
544 * @see java.awt.GraphicsEnvironment#isHeadless
545 */
546 public static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon)
547 throws HeadlessException
548 {
549 return showOptionDialog(parentComponent, message, title, optionType, messageType, icon, null, null);
550 }
551
552 /**
553 * Brings up a dialog with a specified icon, where the initial choice is
554 * determined by the <code>initialValue</code> parameter and the number of
555 * choices is determined by the <code>optionType</code> parameter.
556 * <p>
557 * If <code>optionType</code> is <code>YES_NO_OPTION</code>, or
558 * <code>YES_NO_CANCEL_OPTION</code> and the <code>options</code> parameter
559 * is <code>null</code>, then the options are supplied by the look and feel.
560 * <p>
561 * The <code>messageType</code> parameter is primarily used to supply a
562 * default icon from the look and feel.
563 *
564 * @param parentComponent
565 * determines the <code>Frame</code> in which the dialog is
566 * displayed; if <code>null</code>, or if the
567 * <code>parentComponent</code> has no <code>Frame</code>, a
568 * default <code>Frame</code> is used
569 * @param message
570 * the <code>Object</code> to display
571 * @param title
572 * the title string for the dialog
573 * @param optionType
574 * an integer designating the options available on the dialog:
575 * <code>YES_NO_OPTION</code>, or
576 * <code>YES_NO_CANCEL_OPTION</code>
577 * @param messageType
578 * an integer designating the kind of message this is, primarily
579 * used to determine the icon from the pluggable Look and Feel:
580 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
581 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
582 * or <code>PLAIN_MESSAGE</code>
583 * @param icon
584 * the icon to display in the dialog
585 * @param options
586 * an array of objects indicating the possible choices the user
587 * can make; if the objects are components, they are rendered
588 * properly; non-<code>String</code> objects are rendered using
589 * their <code>toString</code> methods; if this parameter is
590 * <code>null</code>, the options are determined by the Look and
591 * Feel
592 * @param initialValue
593 * the object that represents the default selection for the
594 * dialog; only meaningful if <code>options</code> is used; can
595 * be <code>null</code>
596 * @return an integer indicating the option chosen by the user, or
597 * <code>CLOSED_OPTION</code> if the user closed the dialog
598 * @exception HeadlessException
599 * if <code>GraphicsEnvironment.isHeadless</code> returns
600 * <code>true</code>
601 * @see java.awt.GraphicsEnvironment#isHeadless
602 */
603 public static int showOptionDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[] options,
604 Object initialValue) throws HeadlessException
605 {
606 CWOptionPane pane = new CWOptionPane(message, messageType, optionType, icon, options, initialValue);
607
608 pane.setInitialValue(initialValue);
609 GuiUtil.applyDefaultOrientation(pane);
610
611 int style = styleFromMessageType(messageType);
612 JDialog dialog = pane.createDialog(parentComponent, title, style);
613
614 pane.selectInitialValue();
615 dialog.setVisible(true);
616 dialog.dispose();
617
618 Object selectedValue = pane.getValue();
619
620 if (selectedValue == null) {
621 return CLOSED_OPTION;
622 }
623
624 Object[] opts = pane.getOptions();
625 if (opts == null) {
626 if (selectedValue instanceof Integer) {
627 return ((Integer) selectedValue).intValue();
628 }
629 return CLOSED_OPTION;
630 }
631
632 if (getActionName("Yes").equals(selectedValue)) {
633
634 return YES_OPTION;
635 }
636
637 if (getActionName("No").equals(selectedValue)) {
638
639 return NO_OPTION;
640 }
641
642 if (getActionName("OK").equals(selectedValue)) {
643 return OK_OPTION;
644 }
645
646 if (getActionName("Cancel").equals(selectedValue)) {
647 return CANCEL_OPTION;
648 }
649
650 int maxCounter = opts.length;
651 for (int counter = 0; counter < maxCounter; counter++) {
652 if (opts[counter].equals(selectedValue)) {
653 return counter;
654 }
655 }
656
657 return CLOSED_OPTION;
658 }
659
660 private JDialog createDialog(Component parentComponent, String title, int style) throws HeadlessException {
661
662 final JDialog dialog;
663
664 Window window = GuiUtil.getWindow(parentComponent);
665 if (window instanceof Frame) {
666 dialog = new JDialog((Frame) window, title, true);
667 } else {
668 dialog = new JDialog((Dialog) window, title, true);
669 }
670
671 Container contentPane = dialog.getContentPane();
672
673 contentPane.setLayout(new BorderLayout());
674 contentPane.add(this, BorderLayout.CENTER);
675 dialog.setResizable(false);
676
677 if (JDialog.isDefaultLookAndFeelDecorated()) {
678 boolean supportsWindowDecorations = UIManager.getLookAndFeel().getSupportsWindowDecorations();
679 if (supportsWindowDecorations) {
680 dialog.setUndecorated(true);
681 getRootPane().setWindowDecorationStyle(style);
682 }
683 }
684
685 dialog.pack();
686 dialog.setLocationRelativeTo(parentComponent);
687 dialog.addWindowListener(new WindowAdapter() {
688 private boolean gotFocus;
689
690 @Override
691 public void windowClosing(WindowEvent we) {
692 setValue(null);
693 }
694
695 @Override
696 public void windowGainedFocus(WindowEvent we) {
697 // Once window gets focus, set initial focus
698 if (!gotFocus) {
699 selectInitialValue();
700 gotFocus = true;
701 }
702 }
703 });
704
705 dialog.addComponentListener(new ComponentAdapter() {
706 @Override
707 public void componentShown(ComponentEvent ce) {
708 // reset value to ensure closing works properly
709 setValue(JOptionPane.UNINITIALIZED_VALUE);
710 }
711 });
712
713 addPropertyChangeListener(new PropertyChangeListener() {
714 public void propertyChange(PropertyChangeEvent event) {
715 // Let the defaultCloseOperation handle the closing
716 // if the user closed the window without selecting a button
717 // (newValue = null in that case). Otherwise, close the dialog.
718 if (dialog.isVisible() && event.getSource() == CWOptionPane.this && event.getPropertyName().equals(VALUE_PROPERTY)
719 && event.getNewValue() != null && event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE)
720 {
721 dialog.setVisible(false);
722 }
723 }
724 });
725
726 GuiUtil.applyDefaultOrientation(dialog);
727 return dialog;
728 }
729
730 private static int styleFromMessageType(int messageType) {
731 switch (messageType) {
732 case ERROR_MESSAGE:
733 return JRootPane.ERROR_DIALOG;
734 case QUESTION_MESSAGE:
735 return JRootPane.QUESTION_DIALOG;
736 case WARNING_MESSAGE:
737 return JRootPane.WARNING_DIALOG;
738 case INFORMATION_MESSAGE:
739 return JRootPane.INFORMATION_DIALOG;
740 case PLAIN_MESSAGE:
741 default:
742 return JRootPane.PLAIN_DIALOG;
743 }
744 }
745
746 private static String getActionName(String key) {
747 return actions.findAction(key).getValue(Action.NAME).toString();
748 }
749
750 private static Object[] fixOptions(Object[] options, int optionType, int messageType) {
751 Object[] opts = options;
752 if (options == null) {
753 if (optionType == YES_NO_OPTION) {
754 opts = new Object[] {
755 getActionName("Yes"),
756 getActionName("No")
757 };
758 } else if (optionType == OK_CANCEL_OPTION) {
759 opts = new Object[] {
760 getActionName("OK"),
761 getActionName("Cancel")
762 };
763 } else if (optionType == YES_NO_CANCEL_OPTION && messageType != INFORMATION_MESSAGE) {
764 opts = new Object[] {
765 getActionName("Yes"),
766 getActionName("No"),
767 getActionName("Cancel")
768 };
769 } else {
770 opts = new Object[] {
771 getActionName("OK"),
772 };
773 }
774 }
775 return opts;
776 }
777
778 /**
779 * The actions for this dialog.
780 */
781 private static ActionFactory actions = new ActionFactory(null);
782 static {
783 // TRANSLATOR: This is the text on a "Yes" button.
784 actions.addAction("Yes", CWMsg.gettext("Yes"));
785 // TRANSLATOR: This is the text on a "No" button.
786 actions.addAction("No", CWMsg.gettext("No"));
787 // TRANSLATOR: This is the text on an "OK" button.
788 actions.addAction("OK", CWMsg.gettext("OK"));
789 // TRANSLATOR: This is the text on a "Cancel" button.
790 actions.addAction("Cancel", CWMsg.gettext("Cancel"));
791 }
792
793 /**
794 * Serialization ID
795 */
796 private static final long serialVersionUID = -1870422750863765033L;
797 }
798