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