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