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