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