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