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