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