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 private static boolean checkFrameForComponent(Component parentComponent) { 1237 if (parentComponent == null) { 1238 return false; 1239 } 1240 if (parentComponent instanceof Frame) { 1241 return true; 1242 } 1243 return checkFrameForComponent(parentComponent.getParent()); 1244 } 1245 1246 /** 1247 * Brings up an internal dialog panel with a specified icon, where 1248 * the initial choice is determined by the <code>initialValue</code> 1249 * parameter and the number of choices is determined by the 1250 * <code>optionType</code> parameter. 1251 * <p> 1252 * If <code>optionType</code> is <code>YES_NO_OPTION</code>, or 1253 * <code>YES_NO_CANCEL_OPTION</code> 1254 * and the <code>options</code> parameter is <code>null</code>, 1255 * then the options are supplied by the Look and Feel. 1256 * <p> 1257 * The <code>messageType</code> parameter is primarily used to supply 1258 * a default icon from the look and feel. 1259 * 1260 * @param parentComponent determines the <code>Frame</code> 1261 * in which the dialog is displayed; if <code>null</code>, 1262 * or if the <code>parentComponent</code> has no 1263 * <code>Frame</code>, a default <code>Frame</code> is used 1264 * @param message the object to display in the dialog; a 1265 * <code>Component</code> object is rendered as a 1266 * <code>Component</code>; a <code>String</code> 1267 * object is rendered as a string. Other objects are 1268 * converted to a <code>String</code> using the 1269 * <code>toString</code> method 1270 * @param title the title string for the dialog 1271 * @param optionType an integer designating the options available 1272 * on the dialog: <code>YES_NO_OPTION</code>, 1273 * or <code>YES_NO_CANCEL_OPTION</code> 1274 * @param messageType an integer designating the kind of message this is; 1275 * primarily used to determine the icon from the 1276 * pluggable Look and Feel: <code>ERROR_MESSAGE</code>, 1277 * <code>INFORMATION_MESSAGE</code>, 1278 * <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>, 1279 * or <code>PLAIN_MESSAGE</code> 1280 * @param icon the icon to display in the dialog 1281 * @param options an array of objects indicating the possible choices 1282 * the user can make; if the objects are components, they 1283 * are rendered properly; non-<code>String</code> 1284 * objects are rendered using their <code>toString</code> 1285 * methods; if this parameter is <code>null</code>, 1286 * the options are determined by the Look and Feel 1287 * @param initialValue the object that represents the default selection 1288 * for the dialog; only meaningful if <code>options</code> 1289 * is used; can be <code>null</code> 1290 * @return an integer indicating the option chosen by the user, 1291 * or <code>CLOSED_OPTION</code> if the user closed the Dialog 1292 */ 1293 public static int showInternalOptionDialog(Component parentComponent, 1294 Object message, 1295 String title, int optionType, 1296 int messageType, Icon icon, 1297 Object[] options, Object initialValue) { 1298 JOptionPane pane = new JOptionPane(message, messageType, 1299 optionType, icon, options, initialValue); 1300 pane.putClientProperty(PopupFactory_FORCE_HEAVYWEIGHT_POPUP, 1301 Boolean.TRUE); 1302 Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager(). 1303 getFocusOwner(); 1304 1305 pane.setInitialValue(initialValue); 1306 if (checkFrameForComponent(parentComponent)) { 1307 JInternalFrame dialog = 1308 pane.createInternalFrame(parentComponent, title); 1309 pane.selectInitialValue(); 1310 dialog.setVisible(true); 1311 1312 /* Since all input will be blocked until this dialog is dismissed, 1313 * make sure its parent containers are visible first (this component 1314 * is tested below). This is necessary for JApplets, because 1315 * because an applet normally isn't made visible until after its 1316 * start() method returns -- if this method is called from start(), 1317 * the applet will appear to hang while an invisible modal frame 1318 * waits for input. 1319 */ 1320 if (dialog.isVisible() && !dialog.isShowing()) { 1321 Container parent = dialog.getParent(); 1322 while (parent != null) { 1323 if (parent.isVisible() == false) { 1324 parent.setVisible(true); 1325 } 1326 parent = parent.getParent(); 1327 } 1328 } 1329 1330 AWTAccessor.getContainerAccessor().startLWModal(dialog); 1331 } else { 1332 pane.setComponentOrientation(getRootFrame().getComponentOrientation()); 1333 int style = styleFromMessageType(messageType); 1334 JDialog dialog = pane.createDialog(parentComponent, title, style); 1335 pane.selectInitialValue(); 1336 dialog.setVisible(true); 1337 } 1338 1339 if (parentComponent instanceof JInternalFrame) { 1340 try { 1341 ((JInternalFrame)parentComponent).setSelected(true); 1342 } catch (java.beans.PropertyVetoException e) { 1343 } 1344 } 1345 1346 Object selectedValue = pane.getValue(); 1347 1348 if (fo != null && fo.isShowing()) { 1349 fo.requestFocus(); 1350 } 1351 if (selectedValue == null) { 1352 return CLOSED_OPTION; 1353 } 1354 if (options == null) { 1355 if (selectedValue instanceof Integer) { 1356 return ((Integer)selectedValue).intValue(); 1357 } 1358 return CLOSED_OPTION; 1359 } 1360 for(int counter = 0, maxCounter = options.length; 1361 counter < maxCounter; counter++) { 1362 if (options[counter].equals(selectedValue)) { 1363 return counter; 1364 } 1365 } 1366 return CLOSED_OPTION; 1367 } 1368 1369 /** 1370 * Shows an internal question-message dialog requesting input from 1371 * the user parented to <code>parentComponent</code>. The dialog 1372 * is displayed in the <code>Component</code>'s frame, 1373 * and is usually positioned below the <code>Component</code>. 1374 * 1375 * @param parentComponent the parent <code>Component</code> 1376 * for the dialog 1377 * @param message the <code>Object</code> to display 1378 * @return user's input 1379 */ 1380 public static String showInternalInputDialog(Component parentComponent, 1381 Object message) { 1382 return showInternalInputDialog(parentComponent, message, UIManager. 1383 getString("OptionPane.inputDialogTitle", parentComponent), 1384 QUESTION_MESSAGE); 1385 } 1386 1387 /** 1388 * Shows an internal dialog requesting input from the user parented 1389 * to <code>parentComponent</code> with the dialog having the title 1390 * <code>title</code> and message type <code>messageType</code>. 1391 * 1392 * @param parentComponent the parent <code>Component</code> for the dialog 1393 * @param message the <code>Object</code> to display 1394 * @param title the <code>String</code> to display in the 1395 * dialog title bar 1396 * @param messageType the type of message that is to be displayed: 1397 * ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, 1398 * QUESTION_MESSAGE, or PLAIN_MESSAGE 1399 * @return user's input 1400 */ 1401 public static String showInternalInputDialog(Component parentComponent, 1402 Object message, String title, int messageType) { 1403 return (String)showInternalInputDialog(parentComponent, message, title, 1404 messageType, null, null, null); 1405 } 1406 1407 /** 1408 * Prompts the user for input in a blocking internal dialog where 1409 * the initial selection, possible selections, and all other 1410 * options can be specified. The user will able to choose from 1411 * <code>selectionValues</code>, where <code>null</code> 1412 * implies the user can input 1413 * whatever they wish, usually by means of a <code>JTextField</code>. 1414 * <code>initialSelectionValue</code> is the initial value to prompt 1415 * the user with. It is up to the UI to decide how best to represent 1416 * the <code>selectionValues</code>, but usually a 1417 * <code>JComboBox</code>, <code>JList</code>, or 1418 * <code>JTextField</code> will be used. 1419 * 1420 * @param parentComponent the parent <code>Component</code> for the dialog 1421 * @param message the <code>Object</code> to display 1422 * @param title the <code>String</code> to display in the dialog 1423 * title bar 1424 * @param messageType the type of message to be displayed: 1425 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>, 1426 * <code>WARNING_MESSAGE</code>, 1427 * <code>QUESTION_MESSAGE</code>, or <code>PLAIN_MESSAGE</code> 1428 * @param icon the <code>Icon</code> image to display 1429 * @param selectionValues an array of <code>Objects</code> that 1430 * gives the possible selections 1431 * @param initialSelectionValue the value used to initialize the input 1432 * field 1433 * @return user's input, or <code>null</code> meaning the user 1434 * canceled the input 1435 */ 1436 public static Object showInternalInputDialog(Component parentComponent, 1437 Object message, String title, int messageType, Icon icon, 1438 Object[] selectionValues, Object initialSelectionValue) { 1439 JOptionPane pane = new JOptionPane(message, messageType, 1440 OK_CANCEL_OPTION, icon, null, null); 1441 pane.putClientProperty(PopupFactory_FORCE_HEAVYWEIGHT_POPUP, 1442 Boolean.TRUE); 1443 Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager(). 1444 getFocusOwner(); 1445 1446 pane.setWantsInput(true); 1447 pane.setSelectionValues(selectionValues); 1448 pane.setInitialSelectionValue(initialSelectionValue); 1449 1450 JInternalFrame dialog = 1451 pane.createInternalFrame(parentComponent, title); 1452 1453 pane.selectInitialValue(); 1454 dialog.setVisible(true); 1455 1456 /* Since all input will be blocked until this dialog is dismissed, 1457 * make sure its parent containers are visible first (this component 1458 * is tested below). This is necessary for JApplets, because 1459 * because an applet normally isn't made visible until after its 1460 * start() method returns -- if this method is called from start(), 1461 * the applet will appear to hang while an invisible modal frame 1462 * waits for input. 1463 */ 1464 if (dialog.isVisible() && !dialog.isShowing()) { 1465 Container parent = dialog.getParent(); 1466 while (parent != null) { 1467 if (parent.isVisible() == false) { 1468 parent.setVisible(true); 1469 } 1470 parent = parent.getParent(); 1471 } 1472 } 1473 1474 AWTAccessor.getContainerAccessor().startLWModal(dialog); 1475 1476 if (parentComponent instanceof JInternalFrame) { 1477 try { 1478 ((JInternalFrame)parentComponent).setSelected(true); 1479 } catch (java.beans.PropertyVetoException e) { 1480 } 1481 } 1482 1483 if (fo != null && fo.isShowing()) { 1484 fo.requestFocus(); 1485 } 1486 Object value = pane.getInputValue(); 1487 1488 if (value == UNINITIALIZED_VALUE) { 1489 return null; 1490 } 1491 return value; 1492 } 1493 1494 /** 1495 * Creates and returns an instance of <code>JInternalFrame</code>. 1496 * The internal frame is created with the specified title, 1497 * and wrapping the <code>JOptionPane</code>. 1498 * The returned <code>JInternalFrame</code> is 1499 * added to the <code>JDesktopPane</code> ancestor of 1500 * <code>parentComponent</code>, or components 1501 * parent if one its ancestors isn't a <code>JDesktopPane</code>, 1502 * or if <code>parentComponent</code> 1503 * doesn't have a parent then a <code>RuntimeException</code> is thrown. 1504 * 1505 * @param parentComponent the parent <code>Component</code> for 1506 * the internal frame 1507 * @param title the <code>String</code> to display in the 1508 * frame's title bar 1509 * @return a <code>JInternalFrame</code> containing a 1510 * <code>JOptionPane</code> 1511 * @exception RuntimeException if <code>parentComponent</code> does 1512 * not have a valid parent 1513 */ 1514 public JInternalFrame createInternalFrame(Component parentComponent, 1515 String title) { 1516 Container parent = 1517 JOptionPane.getDesktopPaneForComponent(parentComponent); 1518 1519 if (parent == null && (parentComponent == null || 1520 (parent = parentComponent.getParent()) == null)) { 1521 throw new RuntimeException("JOptionPane: parentComponent does " + 1522 "not have a valid parent"); 1523 } 1524 1525 // Option dialogs should be closable only 1526 final JInternalFrame iFrame = new JInternalFrame(title, false, true, 1527 false, false); 1528 1529 iFrame.putClientProperty("JInternalFrame.frameType", "optionDialog"); 1530 iFrame.putClientProperty("JInternalFrame.messageType", 1531 Integer.valueOf(getMessageType())); 1532 1533 iFrame.addInternalFrameListener(new InternalFrameAdapter() { 1534 public void internalFrameClosing(InternalFrameEvent e) { 1535 if (getValue() == UNINITIALIZED_VALUE) { 1536 setValue(null); 1537 } 1538 } 1539 }); 1540 addPropertyChangeListener(new PropertyChangeListener() { 1541 public void propertyChange(PropertyChangeEvent event) { 1542 // Let the defaultCloseOperation handle the closing 1543 // if the user closed the iframe without selecting a button 1544 // (newValue = null in that case). Otherwise, close the dialog. 1545 if (iFrame.isVisible() && 1546 event.getSource() == JOptionPane.this && 1547 event.getPropertyName().equals(VALUE_PROPERTY)) { 1548 AWTAccessor.getContainerAccessor().stopLWModal(iFrame); 1549 1550 try { 1551 iFrame.setClosed(true); 1552 } 1553 catch (java.beans.PropertyVetoException e) { 1554 } 1555 1556 iFrame.setVisible(false); 1557 } 1558 } 1559 }); 1560 iFrame.getContentPane().add(this, BorderLayout.CENTER); 1561 if (parent instanceof JDesktopPane) { 1562 parent.add(iFrame, JLayeredPane.MODAL_LAYER); 1563 } else { 1564 parent.add(iFrame, BorderLayout.CENTER); 1565 } 1566 Dimension iFrameSize = iFrame.getPreferredSize(); 1567 Dimension rootSize = parent.getSize(); 1568 Dimension parentSize = parentComponent.getSize(); 1569 1570 iFrame.setBounds((rootSize.width - iFrameSize.width) / 2, 1571 (rootSize.height - iFrameSize.height) / 2, 1572 iFrameSize.width, iFrameSize.height); 1573 // We want dialog centered relative to its parent component 1574 Point iFrameCoord = 1575 SwingUtilities.convertPoint(parentComponent, 0, 0, parent); 1576 int x = (parentSize.width - iFrameSize.width) / 2 + iFrameCoord.x; 1577 int y = (parentSize.height - iFrameSize.height) / 2 + iFrameCoord.y; 1578 1579 // If possible, dialog should be fully visible 1580 int ovrx = x + iFrameSize.width - rootSize.width; 1581 int ovry = y + iFrameSize.height - rootSize.height; 1582 x = Math.max((ovrx > 0? x - ovrx: x), 0); 1583 y = Math.max((ovry > 0? y - ovry: y), 0); 1584 iFrame.setBounds(x, y, iFrameSize.width, iFrameSize.height); 1585 1586 parent.validate(); 1587 try { 1588 iFrame.setSelected(true); 1589 } catch (java.beans.PropertyVetoException e) {} 1590 1591 return iFrame; 1592 } 1593 1594 /** 1595 * Returns the specified component's <code>Frame</code>. 1596 * 1597 * @param parentComponent the <code>Component</code> to check for a 1598 * <code>Frame</code> 1599 * @return the <code>Frame</code> that contains the component, 1600 * or <code>getRootFrame</code> 1601 * if the component is <code>null</code>, 1602 * or does not have a valid <code>Frame</code> parent 1603 * @exception HeadlessException if 1604 * <code>GraphicsEnvironment.isHeadless</code> returns 1605 * <code>true</code> 1606 * @see #getRootFrame 1607 * @see java.awt.GraphicsEnvironment#isHeadless 1608 */ 1609 public static Frame getFrameForComponent(Component parentComponent) 1610 throws HeadlessException { 1611 if (parentComponent == null) 1612 return getRootFrame(); 1613 if (parentComponent instanceof Frame) 1614 return (Frame)parentComponent; 1615 return JOptionPane.getFrameForComponent(parentComponent.getParent()); 1616 } 1617 1618 /** 1619 * Returns the specified component's toplevel <code>Frame</code> or 1620 * <code>Dialog</code>. 1621 * 1622 * @param parentComponent the <code>Component</code> to check for a 1623 * <code>Frame</code> or <code>Dialog</code> 1624 * @return the <code>Frame</code> or <code>Dialog</code> that 1625 * contains the component, or the default 1626 * frame if the component is <code>null</code>, 1627 * or does not have a valid 1628 * <code>Frame</code> or <code>Dialog</code> parent 1629 * @exception HeadlessException if 1630 * <code>GraphicsEnvironment.isHeadless</code> returns 1631 * <code>true</code> 1632 * @see java.awt.GraphicsEnvironment#isHeadless 1633 */ 1634 static Window getWindowForComponent(Component parentComponent) 1635 throws HeadlessException { 1636 if (parentComponent == null) 1637 return getRootFrame(); 1638 if (parentComponent instanceof Frame || parentComponent instanceof Dialog) 1639 return (Window)parentComponent; 1640 return JOptionPane.getWindowForComponent(parentComponent.getParent()); 1641 } 1642 1643 1644 /** 1645 * Returns the specified component's desktop pane. 1646 * 1647 * @param parentComponent the <code>Component</code> to check for a 1648 * desktop 1649 * @return the <code>JDesktopPane</code> that contains the component, 1650 * or <code>null</code> if the component is <code>null</code> 1651 * or does not have an ancestor that is a 1652 * <code>JInternalFrame</code> 1653 */ 1654 public static JDesktopPane getDesktopPaneForComponent(Component parentComponent) { 1655 if(parentComponent == null) 1656 return null; 1657 if(parentComponent instanceof JDesktopPane) 1658 return (JDesktopPane)parentComponent; 1659 return getDesktopPaneForComponent(parentComponent.getParent()); 1660 } 1661 1662 private static final Object sharedFrameKey = JOptionPane.class; 1663 1664 /** 1665 * Sets the frame to use for class methods in which a frame is 1666 * not provided. 1667 * <p> 1668 * <strong>Note:</strong> 1669 * It is recommended that rather than using this method you supply a valid parent. 1670 * 1671 * @param newRootFrame the default <code>Frame</code> to use 1672 */ 1673 public static void setRootFrame(Frame newRootFrame) { 1674 if (newRootFrame != null) { 1675 SwingUtilities.appContextPut(sharedFrameKey, newRootFrame); 1676 } else { 1677 SwingUtilities.appContextRemove(sharedFrameKey); 1678 } 1679 } 1680 1681 /** 1682 * Returns the <code>Frame</code> to use for the class methods in 1683 * which a frame is not provided. 1684 * 1685 * @return the default <code>Frame</code> to use 1686 * @exception HeadlessException if 1687 * <code>GraphicsEnvironment.isHeadless</code> returns 1688 * <code>true</code> 1689 * @see #setRootFrame 1690 * @see java.awt.GraphicsEnvironment#isHeadless 1691 */ 1692 public static Frame getRootFrame() throws HeadlessException { 1693 Frame sharedFrame = 1694 (Frame)SwingUtilities.appContextGet(sharedFrameKey); 1695 if (sharedFrame == null) { 1696 sharedFrame = SwingUtilities.getSharedOwnerFrame(); 1697 SwingUtilities.appContextPut(sharedFrameKey, sharedFrame); 1698 } 1699 return sharedFrame; 1700 } 1701 1702 /** 1703 * Creates a <code>JOptionPane</code> with a test message. 1704 */ 1705 public JOptionPane() { 1706 this("JOptionPane message"); 1707 } 1708 1709 /** 1710 * Creates a instance of <code>JOptionPane</code> to display a 1711 * message using the 1712 * plain-message message type and the default options delivered by 1713 * the UI. 1714 * 1715 * @param message the <code>Object</code> to display 1716 */ 1717 public JOptionPane(Object message) { 1718 this(message, PLAIN_MESSAGE); 1719 } 1720 1721 /** 1722 * Creates an instance of <code>JOptionPane</code> to display a message 1723 * with the specified message type and the default options, 1724 * 1725 * @param message the <code>Object</code> to display 1726 * @param messageType the type of message to be displayed: 1727 * <code>ERROR_MESSAGE</code>, 1728 * <code>INFORMATION_MESSAGE</code>, 1729 * <code>WARNING_MESSAGE</code>, 1730 * <code>QUESTION_MESSAGE</code>, 1731 * or <code>PLAIN_MESSAGE</code> 1732 */ 1733 public JOptionPane(Object message, int messageType) { 1734 this(message, messageType, DEFAULT_OPTION); 1735 } 1736 1737 /** 1738 * Creates an instance of <code>JOptionPane</code> to display a message 1739 * with the specified message type and options. 1740 * 1741 * @param message the <code>Object</code> to display 1742 * @param messageType the type of message to be displayed: 1743 * <code>ERROR_MESSAGE</code>, 1744 * <code>INFORMATION_MESSAGE</code>, 1745 * <code>WARNING_MESSAGE</code>, 1746 * <code>QUESTION_MESSAGE</code>, 1747 * or <code>PLAIN_MESSAGE</code> 1748 * @param optionType the options to display in the pane: 1749 * <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>, 1750 * <code>YES_NO_CANCEL_OPTION</code>, 1751 * <code>OK_CANCEL_OPTION</code> 1752 */ 1753 public JOptionPane(Object message, int messageType, int optionType) { 1754 this(message, messageType, optionType, null); 1755 } 1756 1757 /** 1758 * Creates an instance of <code>JOptionPane</code> to display a message 1759 * with the specified message type, options, and icon. 1760 * 1761 * @param message the <code>Object</code> to display 1762 * @param messageType the type of message to be displayed: 1763 * <code>ERROR_MESSAGE</code>, 1764 * <code>INFORMATION_MESSAGE</code>, 1765 * <code>WARNING_MESSAGE</code>, 1766 * <code>QUESTION_MESSAGE</code>, 1767 * or <code>PLAIN_MESSAGE</code> 1768 * @param optionType the options to display in the pane: 1769 * <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>, 1770 * <code>YES_NO_CANCEL_OPTION</code>, 1771 * <code>OK_CANCEL_OPTION</code> 1772 * @param icon the <code>Icon</code> image to display 1773 */ 1774 public JOptionPane(Object message, int messageType, int optionType, 1775 Icon icon) { 1776 this(message, messageType, optionType, icon, null); 1777 } 1778 1779 /** 1780 * Creates an instance of <code>JOptionPane</code> to display a message 1781 * with the specified message type, icon, and options. 1782 * None of the options is initially selected. 1783 * <p> 1784 * The options objects should contain either instances of 1785 * <code>Component</code>s, (which are added directly) or 1786 * <code>Strings</code> (which are wrapped in a <code>JButton</code>). 1787 * If you provide <code>Component</code>s, you must ensure that when the 1788 * <code>Component</code> is clicked it messages <code>setValue</code> 1789 * in the created <code>JOptionPane</code>. 1790 * 1791 * @param message the <code>Object</code> to display 1792 * @param messageType the type of message to be displayed: 1793 * <code>ERROR_MESSAGE</code>, 1794 * <code>INFORMATION_MESSAGE</code>, 1795 * <code>WARNING_MESSAGE</code>, 1796 * <code>QUESTION_MESSAGE</code>, 1797 * or <code>PLAIN_MESSAGE</code> 1798 * @param optionType the options to display in the pane: 1799 * <code>DEFAULT_OPTION</code>, 1800 * <code>YES_NO_OPTION</code>, 1801 * <code>YES_NO_CANCEL_OPTION</code>, 1802 * <code>OK_CANCEL_OPTION</code> 1803 * @param icon the <code>Icon</code> image to display 1804 * @param options the choices the user can select 1805 */ 1806 public JOptionPane(Object message, int messageType, int optionType, 1807 Icon icon, Object[] options) { 1808 this(message, messageType, optionType, icon, options, null); 1809 } 1810 1811 /** 1812 * Creates an instance of <code>JOptionPane</code> to display a message 1813 * with the specified message type, icon, and options, with the 1814 * initially-selected option specified. 1815 * 1816 * @param message the <code>Object</code> to display 1817 * @param messageType the type of message to be displayed: 1818 * <code>ERROR_MESSAGE</code>, 1819 * <code>INFORMATION_MESSAGE</code>, 1820 * <code>WARNING_MESSAGE</code>, 1821 * <code>QUESTION_MESSAGE</code>, 1822 * or <code>PLAIN_MESSAGE</code> 1823 * @param optionType the options to display in the pane: 1824 * <code>DEFAULT_OPTION</code>, 1825 * <code>YES_NO_OPTION</code>, 1826 * <code>YES_NO_CANCEL_OPTION</code>, 1827 * <code>OK_CANCEL_OPTION</code> 1828 * @param icon the Icon image to display 1829 * @param options the choices the user can select 1830 * @param initialValue the choice that is initially selected; if 1831 * <code>null</code>, then nothing will be initially selected; 1832 * only meaningful if <code>options</code> is used 1833 */ 1834 public JOptionPane(Object message, int messageType, int optionType, 1835 Icon icon, Object[] options, Object initialValue) { 1836 1837 this.message = message; 1838 this.options = options == null ? null : Arrays.copyOf(options, options.length); 1839 this.initialValue = initialValue; 1840 this.icon = icon; 1841 setMessageType(messageType); 1842 setOptionType(optionType); 1843 value = UNINITIALIZED_VALUE; 1844 inputValue = UNINITIALIZED_VALUE; 1845 updateUI(); 1846 } 1847 1848 /** 1849 * Sets the UI object which implements the {@literal L&F} for this component. 1850 * 1851 * @param ui the <code>OptionPaneUI</code> {@literal L&F} object 1852 * @see UIDefaults#getUI 1853 */ 1854 @BeanProperty(hidden = true, description 1855 = "The UI object that implements the optionpane's LookAndFeel") 1856 public void setUI(OptionPaneUI ui) { 1857 if (this.ui != ui) { 1858 super.setUI(ui); 1859 invalidate(); 1860 } 1861 } 1862 1863 /** 1864 * Returns the UI object which implements the {@literal L&F} for this component. 1865 * 1866 * @return the <code>OptionPaneUI</code> object 1867 */ 1868 public OptionPaneUI getUI() { 1869 return (OptionPaneUI)ui; 1870 } 1871 1872 /** 1873 * Notification from the <code>UIManager</code> that the {@literal L&F} has changed. 1874 * Replaces the current UI object with the latest version from the 1875 * <code>UIManager</code>. 1876 * 1877 * @see JComponent#updateUI 1878 */ 1879 public void updateUI() { 1880 setUI((OptionPaneUI)UIManager.getUI(this)); 1881 } 1882 1883 1884 /** 1885 * Returns the name of the UI class that implements the 1886 * {@literal L&F} for this component. 1887 * 1888 * @return the string "OptionPaneUI" 1889 * @see JComponent#getUIClassID 1890 * @see UIDefaults#getUI 1891 */ 1892 @BeanProperty(bound = false) 1893 public String getUIClassID() { 1894 return uiClassID; 1895 } 1896 1897 1898 /** 1899 * Sets the option pane's message-object. 1900 * @param newMessage the <code>Object</code> to display 1901 * @see #getMessage 1902 */ 1903 @BeanProperty(preferred = true, description 1904 = "The optionpane's message object.") 1905 public void setMessage(Object newMessage) { 1906 Object oldMessage = message; 1907 1908 message = newMessage; 1909 firePropertyChange(MESSAGE_PROPERTY, oldMessage, message); 1910 } 1911 1912 /** 1913 * Returns the message-object this pane displays. 1914 * @see #setMessage 1915 * 1916 * @return the <code>Object</code> that is displayed 1917 */ 1918 public Object getMessage() { 1919 return message; 1920 } 1921 1922 /** 1923 * Sets the icon to display. If non-<code>null</code>, the look and feel 1924 * does not provide an icon. 1925 * @param newIcon the <code>Icon</code> to display 1926 * 1927 * @see #getIcon 1928 */ 1929 @BeanProperty(preferred = true, description 1930 = "The option pane's type icon.") 1931 public void setIcon(Icon newIcon) { 1932 Object oldIcon = icon; 1933 1934 icon = newIcon; 1935 firePropertyChange(ICON_PROPERTY, oldIcon, icon); 1936 } 1937 1938 /** 1939 * Returns the icon this pane displays. 1940 * @return the <code>Icon</code> that is displayed 1941 * 1942 * @see #setIcon 1943 */ 1944 public Icon getIcon() { 1945 return icon; 1946 } 1947 1948 /** 1949 * Sets the value the user has chosen. 1950 * @param newValue the chosen value 1951 * 1952 * @see #getValue 1953 */ 1954 @BeanProperty(preferred = true, description 1955 = "The option pane's value object.") 1956 public void setValue(Object newValue) { 1957 Object oldValue = value; 1958 1959 value = newValue; 1960 firePropertyChange(VALUE_PROPERTY, oldValue, value); 1961 } 1962 1963 /** 1964 * Returns the value the user has selected. <code>UNINITIALIZED_VALUE</code> 1965 * implies the user has not yet made a choice, <code>null</code> means the 1966 * user closed the window with out choosing anything. Otherwise 1967 * the returned value will be one of the options defined in this 1968 * object. 1969 * 1970 * @return the <code>Object</code> chosen by the user, 1971 * <code>UNINITIALIZED_VALUE</code> 1972 * if the user has not yet made a choice, or <code>null</code> if 1973 * the user closed the window without making a choice 1974 * 1975 * @see #setValue 1976 */ 1977 public Object getValue() { 1978 return value; 1979 } 1980 1981 /** 1982 * Sets the options this pane displays. If an element in 1983 * <code>newOptions</code> is a <code>Component</code> 1984 * it is added directly to the pane, 1985 * otherwise a button is created for the element. 1986 * 1987 * @param newOptions an array of <code>Objects</code> that create the 1988 * buttons the user can click on, or arbitrary 1989 * <code>Components</code> to add to the pane 1990 * 1991 * @see #getOptions 1992 */ 1993 @BeanProperty(description 1994 = "The option pane's options objects.") 1995 public void setOptions(Object[] newOptions) { 1996 Object[] oldOptions = options; 1997 1998 options = newOptions == null 1999 ? null 2000 : Arrays.copyOf(newOptions, newOptions.length); 2001 firePropertyChange(OPTIONS_PROPERTY, oldOptions, options); 2002 } 2003 2004 /** 2005 * Returns the choices the user can make. 2006 * @return the array of <code>Objects</code> that give the user's choices 2007 * 2008 * @see #setOptions 2009 */ 2010 public Object[] getOptions() { 2011 return options == null ? null : Arrays.copyOf(options, options.length); 2012 } 2013 2014 /** 2015 * Sets the initial value that is to be enabled -- the 2016 * <code>Component</code> 2017 * that has the focus when the pane is initially displayed. 2018 * 2019 * @param newInitialValue the <code>Object</code> that gets the initial 2020 * keyboard focus 2021 * 2022 * @see #getInitialValue 2023 */ 2024 @BeanProperty(preferred = true, description 2025 = "The option pane's initial value object.") 2026 public void setInitialValue(Object newInitialValue) { 2027 Object oldIV = initialValue; 2028 2029 initialValue = newInitialValue; 2030 firePropertyChange(INITIAL_VALUE_PROPERTY, oldIV, initialValue); 2031 } 2032 2033 /** 2034 * Returns the initial value. 2035 * 2036 * @return the <code>Object</code> that gets the initial keyboard focus 2037 * 2038 * @see #setInitialValue 2039 */ 2040 public Object getInitialValue() { 2041 return initialValue; 2042 } 2043 2044 /** 2045 * Sets the option pane's message type. 2046 * The message type is used by the Look and Feel to determine the 2047 * icon to display (if not supplied) as well as potentially how to 2048 * lay out the <code>parentComponent</code>. 2049 * @param newType an integer specifying the kind of message to display: 2050 * <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>, 2051 * <code>WARNING_MESSAGE</code>, 2052 * <code>QUESTION_MESSAGE</code>, or <code>PLAIN_MESSAGE</code> 2053 * @exception RuntimeException if <code>newType</code> is not one of the 2054 * legal values listed above 2055 2056 * @see #getMessageType 2057 */ 2058 @BeanProperty(preferred = true, description 2059 = "The option pane's message type.") 2060 public void setMessageType(int newType) { 2061 checkMessageType(newType); 2062 int oldType = messageType; 2063 messageType = newType; 2064 firePropertyChange(MESSAGE_TYPE_PROPERTY, oldType, messageType); 2065 } 2066 2067 private static void checkMessageType(int newType){ 2068 if(newType != ERROR_MESSAGE && newType != INFORMATION_MESSAGE && 2069 newType != WARNING_MESSAGE && newType != QUESTION_MESSAGE && 2070 newType != PLAIN_MESSAGE) 2071 throw new RuntimeException("JOptionPane: type must be one of" 2072 + " JOptionPane.ERROR_MESSAGE," 2073 + " JOptionPane.INFORMATION_MESSAGE," 2074 + " JOptionPane.WARNING_MESSAGE," 2075 + " JOptionPane.QUESTION_MESSAGE" 2076 + " or JOptionPane.PLAIN_MESSAGE"); 2077 } 2078 2079 /** 2080 * Returns the message type. 2081 * 2082 * @return an integer specifying the message type 2083 * 2084 * @see #setMessageType 2085 */ 2086 public int getMessageType() { 2087 return messageType; 2088 } 2089 2090 /** 2091 * Sets the options to display. 2092 * The option type is used by the Look and Feel to 2093 * determine what buttons to show (unless options are supplied). 2094 * @param newType an integer specifying the options the {@literal L&F} is to display: 2095 * <code>DEFAULT_OPTION</code>, 2096 * <code>YES_NO_OPTION</code>, 2097 * <code>YES_NO_CANCEL_OPTION</code>, 2098 * or <code>OK_CANCEL_OPTION</code> 2099 * @exception RuntimeException if <code>newType</code> is not one of 2100 * the legal values listed above 2101 * 2102 * @see #getOptionType 2103 * @see #setOptions 2104 */ 2105 @BeanProperty(preferred = true, description 2106 = "The option pane's option type.") 2107 public void setOptionType(int newType) { 2108 checkOptionType(newType); 2109 int oldType = optionType; 2110 optionType = newType; 2111 firePropertyChange(OPTION_TYPE_PROPERTY, oldType, optionType); 2112 } 2113 2114 private static void checkOptionType(int newType) { 2115 if (newType != DEFAULT_OPTION && newType != YES_NO_OPTION 2116 && newType != YES_NO_CANCEL_OPTION 2117 && newType != OK_CANCEL_OPTION) { 2118 throw new RuntimeException("JOptionPane: option type must be one of" 2119 + " JOptionPane.DEFAULT_OPTION, JOptionPane.YES_NO_OPTION," 2120 + " JOptionPane.YES_NO_CANCEL_OPTION" 2121 + " or JOptionPane.OK_CANCEL_OPTION"); 2122 } 2123 } 2124 2125 /** 2126 * Returns the type of options that are displayed. 2127 * 2128 * @return an integer specifying the user-selectable options 2129 * 2130 * @see #setOptionType 2131 */ 2132 public int getOptionType() { 2133 return optionType; 2134 } 2135 2136 /** 2137 * Sets the input selection values for a pane that provides the user 2138 * with a list of items to choose from. (The UI provides a widget 2139 * for choosing one of the values.) A <code>null</code> value 2140 * implies the user can input whatever they wish, usually by means 2141 * of a <code>JTextField</code>. 2142 * <p> 2143 * Sets <code>wantsInput</code> to true. Use 2144 * <code>setInitialSelectionValue</code> to specify the initially-chosen 2145 * value. After the pane as been enabled, <code>inputValue</code> is 2146 * set to the value the user has selected. 2147 * @param newValues an array of <code>Objects</code> the user to be 2148 * displayed 2149 * (usually in a list or combo-box) from which 2150 * the user can make a selection 2151 * @see #setWantsInput 2152 * @see #setInitialSelectionValue 2153 * @see #getSelectionValues 2154 */ 2155 @BeanProperty(description 2156 = "The option pane's selection values.") 2157 public void setSelectionValues(Object[] newValues) { 2158 Object[] oldValues = selectionValues; 2159 2160 selectionValues = newValues == null 2161 ? null 2162 : Arrays.copyOf(newValues, newValues.length); 2163 firePropertyChange(SELECTION_VALUES_PROPERTY, oldValues, newValues); 2164 if(selectionValues != null) 2165 setWantsInput(true); 2166 } 2167 2168 /** 2169 * Returns the input selection values. 2170 * 2171 * @return the array of <code>Objects</code> the user can select 2172 * @see #setSelectionValues 2173 */ 2174 public Object[] getSelectionValues() { 2175 return selectionValues == null 2176 ? null 2177 : Arrays.copyOf(selectionValues, selectionValues.length); 2178 } 2179 2180 /** 2181 * Sets the input value that is initially displayed as selected to the user. 2182 * Only used if <code>wantsInput</code> is true. 2183 * @param newValue the initially selected value 2184 * @see #setSelectionValues 2185 * @see #getInitialSelectionValue 2186 */ 2187 @BeanProperty(description 2188 = "The option pane's initial selection value object.") 2189 public void setInitialSelectionValue(Object newValue) { 2190 Object oldValue = initialSelectionValue; 2191 2192 initialSelectionValue = newValue; 2193 firePropertyChange(INITIAL_SELECTION_VALUE_PROPERTY, oldValue, 2194 newValue); 2195 } 2196 2197 /** 2198 * Returns the input value that is displayed as initially selected to the user. 2199 * 2200 * @return the initially selected value 2201 * @see #setInitialSelectionValue 2202 * @see #setSelectionValues 2203 */ 2204 public Object getInitialSelectionValue() { 2205 return initialSelectionValue; 2206 } 2207 2208 /** 2209 * Sets the input value that was selected or input by the user. 2210 * Only used if <code>wantsInput</code> is true. Note that this method 2211 * is invoked internally by the option pane (in response to user action) 2212 * and should generally not be called by client programs. To set the 2213 * input value initially displayed as selected to the user, use 2214 * <code>setInitialSelectionValue</code>. 2215 * 2216 * @param newValue the <code>Object</code> used to set the 2217 * value that the user specified (usually in a text field) 2218 * @see #setSelectionValues 2219 * @see #setInitialSelectionValue 2220 * @see #setWantsInput 2221 * @see #getInputValue 2222 */ 2223 @BeanProperty(preferred = true, description 2224 = "The option pane's input value object.") 2225 public void setInputValue(Object newValue) { 2226 Object oldValue = inputValue; 2227 2228 inputValue = newValue; 2229 firePropertyChange(INPUT_VALUE_PROPERTY, oldValue, newValue); 2230 } 2231 2232 /** 2233 * Returns the value the user has input, if <code>wantsInput</code> 2234 * is true. 2235 * 2236 * @return the <code>Object</code> the user specified, 2237 * if it was one of the objects, or a 2238 * <code>String</code> if it was a value typed into a 2239 * field 2240 * @see #setSelectionValues 2241 * @see #setWantsInput 2242 * @see #setInputValue 2243 */ 2244 public Object getInputValue() { 2245 return inputValue; 2246 } 2247 2248 /** 2249 * Returns the maximum number of characters to place on a line in a 2250 * message. Default is to return <code>Integer.MAX_VALUE</code>. 2251 * The value can be 2252 * changed by overriding this method in a subclass. 2253 * 2254 * @return an integer giving the maximum number of characters on a line 2255 */ 2256 @BeanProperty(bound = false) 2257 public int getMaxCharactersPerLineCount() { 2258 return Integer.MAX_VALUE; 2259 } 2260 2261 /** 2262 * Sets the <code>wantsInput</code> property. 2263 * If <code>newValue</code> is true, an input component 2264 * (such as a text field or combo box) whose parent is 2265 * <code>parentComponent</code> is provided to 2266 * allow the user to input a value. If <code>getSelectionValues</code> 2267 * returns a non-<code>null</code> array, the input value is one of the 2268 * objects in that array. Otherwise the input value is whatever 2269 * the user inputs. 2270 * <p> 2271 * This is a bound property. 2272 * 2273 * @param newValue if true, an input component whose parent is {@code parentComponent} 2274 * is provided to allow the user to input a value. 2275 * @see #setSelectionValues 2276 * @see #setInputValue 2277 */ 2278 @BeanProperty(preferred = true, description 2279 = "Flag which allows the user to input a value.") 2280 public void setWantsInput(boolean newValue) { 2281 boolean oldValue = wantsInput; 2282 2283 wantsInput = newValue; 2284 firePropertyChange(WANTS_INPUT_PROPERTY, oldValue, newValue); 2285 } 2286 2287 /** 2288 * Returns the value of the <code>wantsInput</code> property. 2289 * 2290 * @return true if an input component will be provided 2291 * @see #setWantsInput 2292 */ 2293 public boolean getWantsInput() { 2294 return wantsInput; 2295 } 2296 2297 /** 2298 * Requests that the initial value be selected, which will set 2299 * focus to the initial value. This method 2300 * should be invoked after the window containing the option pane 2301 * is made visible. 2302 */ 2303 public void selectInitialValue() { 2304 OptionPaneUI ui = getUI(); 2305 if (ui != null) { 2306 ui.selectInitialValue(this); 2307 } 2308 } 2309 2310 2311 private static int styleFromMessageType(int messageType) { 2312 switch (messageType) { 2313 case ERROR_MESSAGE: 2314 return JRootPane.ERROR_DIALOG; 2315 case QUESTION_MESSAGE: 2316 return JRootPane.QUESTION_DIALOG; 2317 case WARNING_MESSAGE: 2318 return JRootPane.WARNING_DIALOG; 2319 case INFORMATION_MESSAGE: 2320 return JRootPane.INFORMATION_DIALOG; 2321 case PLAIN_MESSAGE: 2322 default: 2323 return JRootPane.PLAIN_DIALOG; 2324 } 2325 } 2326 2327 // Serialization support. 2328 private void writeObject(ObjectOutputStream s) throws IOException { 2329 Vector<Object> values = new Vector<Object>(); 2330 2331 s.defaultWriteObject(); 2332 // Save the icon, if its Serializable. 2333 if(icon != null && icon instanceof Serializable) { 2334 values.addElement("icon"); 2335 values.addElement(icon); 2336 } 2337 // Save the message, if its Serializable. 2338 if(message != null && message instanceof Serializable) { 2339 values.addElement("message"); 2340 values.addElement(message); 2341 } 2342 // Save the treeModel, if its Serializable. 2343 if(options != null) { 2344 Vector<Object> serOptions = new Vector<Object>(); 2345 2346 for(int counter = 0, maxCounter = options.length; 2347 counter < maxCounter; counter++) 2348 if(options[counter] instanceof Serializable) 2349 serOptions.addElement(options[counter]); 2350 if(serOptions.size() > 0) { 2351 int optionCount = serOptions.size(); 2352 Object[] arrayOptions = new Object[optionCount]; 2353 2354 serOptions.copyInto(arrayOptions); 2355 values.addElement("options"); 2356 values.addElement(arrayOptions); 2357 } 2358 } 2359 // Save the initialValue, if its Serializable. 2360 if(initialValue != null && initialValue instanceof Serializable) { 2361 values.addElement("initialValue"); 2362 values.addElement(initialValue); 2363 } 2364 // Save the value, if its Serializable. 2365 if(value != null && value instanceof Serializable) { 2366 values.addElement("value"); 2367 values.addElement(value); 2368 } 2369 // Save the selectionValues, if its Serializable. 2370 if(selectionValues != null) { 2371 boolean serialize = true; 2372 2373 for(int counter = 0, maxCounter = selectionValues.length; 2374 counter < maxCounter; counter++) { 2375 if(selectionValues[counter] != null && 2376 !(selectionValues[counter] instanceof Serializable)) { 2377 serialize = false; 2378 break; 2379 } 2380 } 2381 if(serialize) { 2382 values.addElement("selectionValues"); 2383 values.addElement(selectionValues); 2384 } 2385 } 2386 // Save the inputValue, if its Serializable. 2387 if(inputValue != null && inputValue instanceof Serializable) { 2388 values.addElement("inputValue"); 2389 values.addElement(inputValue); 2390 } 2391 // Save the initialSelectionValue, if its Serializable. 2392 if(initialSelectionValue != null && 2393 initialSelectionValue instanceof Serializable) { 2394 values.addElement("initialSelectionValue"); 2395 values.addElement(initialSelectionValue); 2396 } 2397 s.writeObject(values); 2398 } 2399 2400 private void readObject(ObjectInputStream s) 2401 throws IOException, ClassNotFoundException { 2402 ObjectInputStream.GetField f = s.readFields(); 2403 2404 int newMessageType = f.get("messageType", 0); 2405 checkMessageType(newMessageType); 2406 messageType = newMessageType; 2407 int newOptionType = f.get("optionType", 0); 2408 checkOptionType(newOptionType); 2409 optionType = newOptionType; 2410 wantsInput = f.get("wantsInput", false); 2411 2412 Vector<?> values = (Vector)s.readObject(); 2413 int indexCounter = 0; 2414 int maxCounter = values.size(); 2415 2416 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2417 equals("icon")) { 2418 icon = (Icon)values.elementAt(++indexCounter); 2419 indexCounter++; 2420 } 2421 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2422 equals("message")) { 2423 message = values.elementAt(++indexCounter); 2424 indexCounter++; 2425 } 2426 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2427 equals("options")) { 2428 options = (Object[])values.elementAt(++indexCounter); 2429 indexCounter++; 2430 } 2431 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2432 equals("initialValue")) { 2433 initialValue = values.elementAt(++indexCounter); 2434 indexCounter++; 2435 } 2436 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2437 equals("value")) { 2438 value = values.elementAt(++indexCounter); 2439 indexCounter++; 2440 } 2441 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2442 equals("selectionValues")) { 2443 selectionValues = (Object[])values.elementAt(++indexCounter); 2444 indexCounter++; 2445 } 2446 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2447 equals("inputValue")) { 2448 inputValue = values.elementAt(++indexCounter); 2449 indexCounter++; 2450 } 2451 if(indexCounter < maxCounter && values.elementAt(indexCounter). 2452 equals("initialSelectionValue")) { 2453 initialSelectionValue = values.elementAt(++indexCounter); 2454 indexCounter++; 2455 } 2456 if (getUIClassID().equals(uiClassID)) { 2457 byte count = JComponent.getWriteObjCounter(this); 2458 JComponent.setWriteObjCounter(this, --count); 2459 if (count == 0 && ui != null) { 2460 ui.installUI(this); 2461 } 2462 } 2463 } 2464 2465 2466 /** 2467 * Returns a string representation of this <code>JOptionPane</code>. 2468 * This method 2469 * is intended to be used only for debugging purposes, and the 2470 * content and format of the returned string may vary between 2471 * implementations. The returned string may be empty but may not 2472 * be <code>null</code>. 2473 * 2474 * @return a string representation of this <code>JOptionPane</code> 2475 */ 2476 protected String paramString() { 2477 String iconString = (icon != null ? 2478 icon.toString() : ""); 2479 String initialValueString = (initialValue != null ? 2480 initialValue.toString() : ""); 2481 String messageString = (message != null ? 2482 message.toString() : ""); 2483 String messageTypeString; 2484 if (messageType == ERROR_MESSAGE) { 2485 messageTypeString = "ERROR_MESSAGE"; 2486 } else if (messageType == INFORMATION_MESSAGE) { 2487 messageTypeString = "INFORMATION_MESSAGE"; 2488 } else if (messageType == WARNING_MESSAGE) { 2489 messageTypeString = "WARNING_MESSAGE"; 2490 } else if (messageType == QUESTION_MESSAGE) { 2491 messageTypeString = "QUESTION_MESSAGE"; 2492 } else if (messageType == PLAIN_MESSAGE) { 2493 messageTypeString = "PLAIN_MESSAGE"; 2494 } else messageTypeString = ""; 2495 String optionTypeString; 2496 if (optionType == DEFAULT_OPTION) { 2497 optionTypeString = "DEFAULT_OPTION"; 2498 } else if (optionType == YES_NO_OPTION) { 2499 optionTypeString = "YES_NO_OPTION"; 2500 } else if (optionType == YES_NO_CANCEL_OPTION) { 2501 optionTypeString = "YES_NO_CANCEL_OPTION"; 2502 } else if (optionType == OK_CANCEL_OPTION) { 2503 optionTypeString = "OK_CANCEL_OPTION"; 2504 } else optionTypeString = ""; 2505 String wantsInputString = (wantsInput ? 2506 "true" : "false"); 2507 2508 return super.paramString() + 2509 ",icon=" + iconString + 2510 ",initialValue=" + initialValueString + 2511 ",message=" + messageString + 2512 ",messageType=" + messageTypeString + 2513 ",optionType=" + optionTypeString + 2514 ",wantsInput=" + wantsInputString; 2515 } 2516 2517 /////////////////// 2518 // Accessibility support 2519 /////////////////// 2520 2521 /** 2522 * Returns the <code>AccessibleContext</code> associated with this JOptionPane. 2523 * For option panes, the <code>AccessibleContext</code> takes the form of an 2524 * <code>AccessibleJOptionPane</code>. 2525 * A new <code>AccessibleJOptionPane</code> instance is created if necessary. 2526 * 2527 * @return an AccessibleJOptionPane that serves as the 2528 * AccessibleContext of this AccessibleJOptionPane 2529 */ 2530 @BeanProperty(bound = false, expert = true, description 2531 = "The AccessibleContext associated with this option pane") 2532 public AccessibleContext getAccessibleContext() { 2533 if (accessibleContext == null) { 2534 accessibleContext = new AccessibleJOptionPane(); 2535 } 2536 return accessibleContext; 2537 } 2538 2539 /** 2540 * This class implements accessibility support for the 2541 * <code>JOptionPane</code> class. It provides an implementation of the 2542 * Java Accessibility API appropriate to option pane user-interface 2543 * elements. 2544 * <p> 2545 * <strong>Warning:</strong> 2546 * Serialized objects of this class will not be compatible with 2547 * future Swing releases. The current serialization support is 2548 * appropriate for short term storage or RMI between applications running 2549 * the same version of Swing. As of 1.4, support for long term storage 2550 * of all JavaBeans™ 2551 * has been added to the <code>java.beans</code> package. 2552 * Please see {@link java.beans.XMLEncoder}. 2553 */ 2554 @SuppressWarnings("serial") // Same-version serialization only 2555 protected class AccessibleJOptionPane extends AccessibleJComponent { 2556 2557 /** 2558 * Get the role of this object. 2559 * 2560 * @return an instance of AccessibleRole describing the role of the object 2561 * @see AccessibleRole 2562 */ 2563 public AccessibleRole getAccessibleRole() { 2564 switch (messageType) { 2565 case ERROR_MESSAGE: 2566 case INFORMATION_MESSAGE: 2567 case WARNING_MESSAGE: 2568 return AccessibleRole.ALERT; 2569 2570 default: 2571 return AccessibleRole.OPTION_PANE; 2572 } 2573 } 2574 2575 } // inner class AccessibleJOptionPane 2576 }