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