PageRenderTime 33ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/java-1.7.0-openjdk/openjdk/jdk/src/share/classes/javax/swing/JOptionPane.java

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