/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.KeyboardFocusManager;
import java.awt.Frame;
import java.awt.Point;
import java.awt.HeadlessException;
import java.awt.Window;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.awt.event.WindowListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Vector;
import javax.swing.plaf.OptionPaneUI;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameAdapter;
import javax.accessibility.*;
import static javax.swing.ClientPropertyKey.PopupFactory_FORCE_HEAVYWEIGHT_POPUP;
/**
* JOptionPane
makes it easy to pop up a standard dialog box that
* prompts users for a value or informs them of something.
* For information about using JOptionPane
, see
* How to Make Dialogs,
* a section in The Java Tutorial.
*
*
*
* While the JOptionPane
* class may appear complex because of the large number of methods, almost
* all uses of this class are one-line calls to one of the static
* showXxxDialog
methods shown below:
*
* * ** Each of these methods also comes in a*
* ** *Method Name *Description ** *showConfirmDialog *Asks a confirming question, like yes/no/cancel. ** *showInputDialog *Prompt for some input. ** *showMessageDialog *Tell the user about something that has happened. ** *showOptionDialog *The Grand Unification of the above three. *
showInternalXXX
* flavor, which uses an internal frame to hold the dialog box (see
* {@link JInternalFrame}).
* Multiple convenience methods have also been defined -- overloaded
* versions of the basic methods that use different parameter lists.
*
* All dialogs are modal. Each showXxxDialog
method blocks
* the caller until the user's interaction is complete.
*
* *
icon | *message | *
input value | *|
option buttons | *
ComponentOrientation
property.
*
* Parameters:
* The parameters to these methods follow consistent patterns:
*
***
*- parentComponent
- * Defines the
Component
that is to be the parent of this * dialog box. * It is used in two ways: theFrame
that contains * it is used as theFrame
* parent for the dialog box, and its screen coordinates are used in * the placement of the dialog box. In general, the dialog box is placed * just below the component. This parameter may benull
, * in which case a defaultFrame
is used as the parent, * and the dialog will be * centered on the screen (depending on the L&F). *- message
- * A descriptive message to be placed in the dialog box. * In the most common usage, message is just a
String
or *String
constant. * However, the type of this parameter is actuallyObject
. Its * interpretation depends on its type: **
*- Object[]
- An array of objects is interpreted as a series of * messages (one per object) arranged in a vertical stack. * The interpretation is recursive -- each object in the * array is interpreted according to its type. *
- Component
- The
Component
is displayed in the dialog. *- Icon
- The
Icon
is wrapped in aJLabel
* and displayed in the dialog. *- others
- The object is converted to a
String
by calling * itstoString
method. The result is wrapped in a *JLabel
and displayed. *- messageType
- Defines the style of the message. The Look and Feel * manager may lay out the dialog differently depending on this value, and * will often provide a default icon. The possible values are: *
*
*ERROR_MESSAGE
*INFORMATION_MESSAGE
*WARNING_MESSAGE
*QUESTION_MESSAGE
*PLAIN_MESSAGE
*- optionType
- Defines the set of option buttons that appear at * the bottom of the dialog box: *
*
* You aren't limited to this set of option buttons. You can provide any * buttons you want using the options parameter. *DEFAULT_OPTION
*YES_NO_OPTION
*YES_NO_CANCEL_OPTION
*OK_CANCEL_OPTION
*- options
- A more detailed description of the set of option buttons * that will appear at the bottom of the dialog box. * The usual value for the options parameter is an array of *
String
s. But * the parameter type is an array ofObjects
. * A button is created for each object depending on its type: **
*- Component
- The component is added to the button row directly. *
- Icon
- A
JButton
is created with this as its label. *- other
- The
Object
is converted to a string using its *toString
method and the result is used to * label aJButton
. *- icon
- A decorative icon to be placed in the dialog box. A default * value for this is determined by the
messageType
parameter. *- title
- The title for the dialog box. *
- initialValue
- The default selection (input value). *
* When the selection is changed, setValue
is invoked,
* which generates a PropertyChangeEvent
.
*
* If a JOptionPane
has configured to all input
* setWantsInput
* the bound property JOptionPane.INPUT_VALUE_PROPERTY
* can also be listened
* to, to determine when the user has input or selected a value.
*
* When one of the showXxxDialog
methods returns an integer,
* the possible values are:
*
YES_OPTION
* NO_OPTION
* CANCEL_OPTION
* OK_OPTION
* CLOSED_OPTION
*
* JOptionPane.showMessageDialog(null, "alert", "alert", JOptionPane.ERROR_MESSAGE);
*
*
* JOptionPane.showInternalMessageDialog(frame, "information",
* "information", JOptionPane.INFORMATION_MESSAGE);
*
*
JOptionPane.showConfirmDialog(null,
* "choose one", "choose one", JOptionPane.YES_NO_OPTION);
*
*
JOptionPane.showInternalConfirmDialog(frame,
* "please choose one", "information",
* JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
*
*
* Object[] options = { "OK", "CANCEL" };
* JOptionPane.showOptionDialog(null, "Click OK to continue", "Warning",
* JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
* null, options, options[0]);
*
*
* String inputValue = JOptionPane.showInputDialog("Please input a value");
*
*
* Object[] possibleValues = { "First", "Second", "Third" };
* Object selectedValue = JOptionPane.showInputDialog(null,
* "Choose one", "Input",
* JOptionPane.INFORMATION_MESSAGE, null,
* possibleValues, possibleValues[0]);
*
*
JOptionPane
directly, the
* standard pattern is roughly as follows:
* * JOptionPane pane = new JOptionPane(arguments); * pane.set.Xxxx(...); // Configure * JDialog dialog = pane.createDialog(parentComponent, title); * dialog.show(); * Object selectedValue = pane.getValue(); * if(selectedValue == null) * return CLOSED_OPTION; * //If there is not an array of option buttons: * if(options == null) { * if(selectedValue instanceof Integer) * return ((Integer)selectedValue).intValue(); * return CLOSED_OPTION; * } * //If there is an array of option buttons: * for(int counter = 0, maxCounter = options.length; * counter < maxCounter; counter++) { * if(options[counter].equals(selectedValue)) * return counter; * } * return CLOSED_OPTION; **
* Warning: Swing is not thread safe. For more * information see Swing's Threading * Policy. *
* Warning:
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeansTM
* has been added to the java.beans
package.
* Please see {@link java.beans.XMLEncoder}.
*
* @see JInternalFrame
*
* @beaninfo
* attribute: isContainer true
* description: A component which implements standard dialog box controls.
*
* @author James Gosling
* @author Scott Violet
*/
public class JOptionPane extends JComponent implements Accessible
{
/**
* @see #getUIClassID
* @see #readObject
*/
private static final String uiClassID = "OptionPaneUI";
/**
* Indicates that the user has not yet selected a value.
*/
public static final Object UNINITIALIZED_VALUE = "uninitializedValue";
//
// Option types
//
/**
* Type meaning Look and Feel should not supply any options -- only
* use the options from the JOptionPane
.
*/
public static final int DEFAULT_OPTION = -1;
/** Type used for showConfirmDialog
. */
public static final int YES_NO_OPTION = 0;
/** Type used for showConfirmDialog
. */
public static final int YES_NO_CANCEL_OPTION = 1;
/** Type used for showConfirmDialog
. */
public static final int OK_CANCEL_OPTION = 2;
//
// Return values.
//
/** Return value from class method if YES is chosen. */
public static final int YES_OPTION = 0;
/** Return value from class method if NO is chosen. */
public static final int NO_OPTION = 1;
/** Return value from class method if CANCEL is chosen. */
public static final int CANCEL_OPTION = 2;
/** Return value form class method if OK is chosen. */
public static final int OK_OPTION = 0;
/** Return value from class method if user closes window without selecting
* anything, more than likely this should be treated as either a
* CANCEL_OPTION
or NO_OPTION
. */
public static final int CLOSED_OPTION = -1;
//
// Message types. Used by the UI to determine what icon to display,
// and possibly what behavior to give based on the type.
//
/** Used for error messages. */
public static final int ERROR_MESSAGE = 0;
/** Used for information messages. */
public static final int INFORMATION_MESSAGE = 1;
/** Used for warning messages. */
public static final int WARNING_MESSAGE = 2;
/** Used for questions. */
public static final int QUESTION_MESSAGE = 3;
/** No icon is used. */
public static final int PLAIN_MESSAGE = -1;
/** Bound property name for icon
. */
public static final String ICON_PROPERTY = "icon";
/** Bound property name for message
. */
public static final String MESSAGE_PROPERTY = "message";
/** Bound property name for value
. */
public static final String VALUE_PROPERTY = "value";
/** Bound property name for option
. */
public static final String OPTIONS_PROPERTY = "options";
/** Bound property name for initialValue
. */
public static final String INITIAL_VALUE_PROPERTY = "initialValue";
/** Bound property name for type
. */
public static final String MESSAGE_TYPE_PROPERTY = "messageType";
/** Bound property name for optionType
. */
public static final String OPTION_TYPE_PROPERTY = "optionType";
/** Bound property name for selectionValues
. */
public static final String SELECTION_VALUES_PROPERTY = "selectionValues";
/** Bound property name for initialSelectionValue
. */
public static final String INITIAL_SELECTION_VALUE_PROPERTY = "initialSelectionValue";
/** Bound property name for inputValue
. */
public static final String INPUT_VALUE_PROPERTY = "inputValue";
/** Bound property name for wantsInput
. */
public static final String WANTS_INPUT_PROPERTY = "wantsInput";
/** Icon used in pane. */
transient protected Icon icon;
/** Message to display. */
transient protected Object message;
/** Options to display to the user. */
transient protected Object[] options;
/** Value that should be initially selected in options
. */
transient protected Object initialValue;
/** Message type. */
protected int messageType;
/**
* Option type, one of DEFAULT_OPTION
,
* YES_NO_OPTION
,
* YES_NO_CANCEL_OPTION
or
* OK_CANCEL_OPTION
.
*/
protected int optionType;
/** Currently selected value, will be a valid option, or
* UNINITIALIZED_VALUE
or null
. */
transient protected Object value;
/** Array of values the user can choose from. Look and feel will
* provide the UI component to choose this from. */
protected transient Object[] selectionValues;
/** Value the user has input. */
protected transient Object inputValue;
/** Initial value to select in selectionValues
. */
protected transient Object initialSelectionValue;
/** If true, a UI widget will be provided to the user to get input. */
protected boolean wantsInput;
/**
* Shows a question-message dialog requesting input from the user. The
* dialog uses the default frame, which usually means it is centered on
* the screen.
*
* @param message the Object
to display
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static String showInputDialog(Object message)
throws HeadlessException {
return showInputDialog(null, message);
}
/**
* Shows a question-message dialog requesting input from the user, with
* the input value initialized to initialSelectionValue
. The
* dialog uses the default frame, which usually means it is centered on
* the screen.
*
* @param message the Object
to display
* @param initialSelectionValue the value used to initialize the input
* field
* @since 1.4
*/
public static String showInputDialog(Object message, Object initialSelectionValue) {
return showInputDialog(null, message, initialSelectionValue);
}
/**
* Shows a question-message dialog requesting input from the user
* parented to parentComponent
.
* The dialog is displayed on top of the Component
's
* frame, and is usually positioned below the Component
.
*
* @param parentComponent the parent Component
for the
* dialog
* @param message the Object
to display
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static String showInputDialog(Component parentComponent,
Object message) throws HeadlessException {
return showInputDialog(parentComponent, message, UIManager.getString(
"OptionPane.inputDialogTitle", parentComponent), QUESTION_MESSAGE);
}
/**
* Shows a question-message dialog requesting input from the user and
* parented to parentComponent
. The input value will be
* initialized to initialSelectionValue
.
* The dialog is displayed on top of the Component
's
* frame, and is usually positioned below the Component
.
*
* @param parentComponent the parent Component
for the
* dialog
* @param message the Object
to display
* @param initialSelectionValue the value used to initialize the input
* field
* @since 1.4
*/
public static String showInputDialog(Component parentComponent, Object message,
Object initialSelectionValue) {
return (String)showInputDialog(parentComponent, message,
UIManager.getString("OptionPane.inputDialogTitle",
parentComponent), QUESTION_MESSAGE, null, null,
initialSelectionValue);
}
/**
* Shows a dialog requesting input from the user parented to
* parentComponent
with the dialog having the title
* title
and message type messageType
.
*
* @param parentComponent the parent Component
for the
* dialog
* @param message the Object
to display
* @param title the String
to display in the dialog
* title bar
* @param messageType the type of message that is to be displayed:
* ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static String showInputDialog(Component parentComponent,
Object message, String title, int messageType)
throws HeadlessException {
return (String)showInputDialog(parentComponent, message, title,
messageType, null, null, null);
}
/**
* Prompts the user for input in a blocking dialog where the
* initial selection, possible selections, and all other options can
* be specified. The user will able to choose from
* selectionValues
, where null
implies the
* user can input
* whatever they wish, usually by means of a JTextField
.
* initialSelectionValue
is the initial value to prompt
* the user with. It is up to the UI to decide how best to represent
* the selectionValues
, but usually a
* JComboBox
, JList
, or
* JTextField
will be used.
*
* @param parentComponent the parent Component
for the
* dialog
* @param message the Object
to display
* @param title the String
to display in the
* dialog title bar
* @param messageType the type of message to be displayed:
* ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @param icon the Icon
image to display
* @param selectionValues an array of Object
s that
* gives the possible selections
* @param initialSelectionValue the value used to initialize the input
* field
* @return user's input, or null
meaning the user
* canceled the input
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static Object showInputDialog(Component parentComponent,
Object message, String title, int messageType, Icon icon,
Object[] selectionValues, Object initialSelectionValue)
throws HeadlessException {
JOptionPane pane = new JOptionPane(message, messageType,
OK_CANCEL_OPTION, icon,
null, null);
pane.setWantsInput(true);
pane.setSelectionValues(selectionValues);
pane.setInitialSelectionValue(initialSelectionValue);
pane.setComponentOrientation(((parentComponent == null) ?
getRootFrame() : parentComponent).getComponentOrientation());
int style = styleFromMessageType(messageType);
JDialog dialog = pane.createDialog(parentComponent, title, style);
pane.selectInitialValue();
dialog.show();
dialog.dispose();
Object value = pane.getInputValue();
if (value == UNINITIALIZED_VALUE) {
return null;
}
return value;
}
/**
* Brings up an information-message dialog titled "Message".
*
* @param parentComponent determines the Frame
in
* which the dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a default Frame
is used
* @param message the Object
to display
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static void showMessageDialog(Component parentComponent,
Object message) throws HeadlessException {
showMessageDialog(parentComponent, message, UIManager.getString(
"OptionPane.messageDialogTitle", parentComponent),
INFORMATION_MESSAGE);
}
/**
* Brings up a dialog that displays a message using a default
* icon determined by the messageType
parameter.
*
* @param parentComponent determines the Frame
* in which the dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a default Frame
is used
* @param message the Object
to display
* @param title the title string for the dialog
* @param messageType the type of message to be displayed:
* ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static void showMessageDialog(Component parentComponent,
Object message, String title, int messageType)
throws HeadlessException {
showMessageDialog(parentComponent, message, title, messageType, null);
}
/**
* Brings up a dialog displaying a message, specifying all parameters.
*
* @param parentComponent determines the Frame
in which the
* dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a
* default Frame
is used
* @param message the Object
to display
* @param title the title string for the dialog
* @param messageType the type of message to be displayed:
* ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @param icon an icon to display in the dialog that helps the user
* identify the kind of message that is being displayed
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static void showMessageDialog(Component parentComponent,
Object message, String title, int messageType, Icon icon)
throws HeadlessException {
showOptionDialog(parentComponent, message, title, DEFAULT_OPTION,
messageType, icon, null, null);
}
/**
* Brings up a dialog with the options Yes,
* No and Cancel; with the
* title, Select an Option.
*
* @param parentComponent determines the Frame
in which the
* dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a
* default Frame
is used
* @param message the Object
to display
* @return an integer indicating the option selected by the user
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static int showConfirmDialog(Component parentComponent,
Object message) throws HeadlessException {
return showConfirmDialog(parentComponent, message,
UIManager.getString("OptionPane.titleText"),
YES_NO_CANCEL_OPTION);
}
/**
* Brings up a dialog where the number of choices is determined
* by the optionType
parameter.
*
* @param parentComponent determines the Frame
in which the
* dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a
* default Frame
is used
* @param message the Object
to display
* @param title the title string for the dialog
* @param optionType an int designating the options available on the dialog:
* YES_NO_OPTION
,
* YES_NO_CANCEL_OPTION
,
* or OK_CANCEL_OPTION
* @return an int indicating the option selected by the user
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static int showConfirmDialog(Component parentComponent,
Object message, String title, int optionType)
throws HeadlessException {
return showConfirmDialog(parentComponent, message, title, optionType,
QUESTION_MESSAGE);
}
/**
* Brings up a dialog where the number of choices is determined
* by the optionType
parameter, where the
* messageType
* parameter determines the icon to display.
* The messageType
parameter is primarily used to supply
* a default icon from the Look and Feel.
*
* @param parentComponent determines the Frame
in
* which the dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a
* default Frame
is used.
* @param message the Object
to display
* @param title the title string for the dialog
* @param optionType an integer designating the options available
* on the dialog: YES_NO_OPTION
,
* YES_NO_CANCEL_OPTION
,
* or OK_CANCEL_OPTION
* @param messageType an integer designating the kind of message this is;
* primarily used to determine the icon from the pluggable
* Look and Feel: ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @return an integer indicating the option selected by the user
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static int showConfirmDialog(Component parentComponent,
Object message, String title, int optionType, int messageType)
throws HeadlessException {
return showConfirmDialog(parentComponent, message, title, optionType,
messageType, null);
}
/**
* Brings up a dialog with a specified icon, where the number of
* choices is determined by the optionType
parameter.
* The messageType
parameter is primarily used to supply
* a default icon from the look and feel.
*
* @param parentComponent determines the Frame
in which the
* dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a
* default Frame
is used
* @param message the Object to display
* @param title the title string for the dialog
* @param optionType an int designating the options available on the dialog:
* YES_NO_OPTION
,
* YES_NO_CANCEL_OPTION
,
* or OK_CANCEL_OPTION
* @param messageType an int designating the kind of message this is,
* primarily used to determine the icon from the pluggable
* Look and Feel: ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @param icon the icon to display in the dialog
* @return an int indicating the option selected by the user
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static int showConfirmDialog(Component parentComponent,
Object message, String title, int optionType,
int messageType, Icon icon) throws HeadlessException {
return showOptionDialog(parentComponent, message, title, optionType,
messageType, icon, null, null);
}
/**
* Brings up a dialog with a specified icon, where the initial
* choice is determined by the initialValue
parameter and
* the number of choices is determined by the optionType
* parameter.
*
* If optionType
is YES_NO_OPTION
,
* or YES_NO_CANCEL_OPTION
* and the options
parameter is null
,
* then the options are
* supplied by the look and feel.
*
* The messageType
parameter is primarily used to supply
* a default icon from the look and feel.
*
* @param parentComponent determines the Frame
* in which the dialog is displayed; if
* null
, or if the
* parentComponent
has no
* Frame
, a
* default Frame
is used
* @param message the Object
to display
* @param title the title string for the dialog
* @param optionType an integer designating the options available on the
* dialog: DEFAULT_OPTION
,
* YES_NO_OPTION
,
* YES_NO_CANCEL_OPTION
,
* or OK_CANCEL_OPTION
* @param messageType an integer designating the kind of message this is,
* primarily used to determine the icon from the
* pluggable Look and Feel: ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @param icon the icon to display in the dialog
* @param options an array of objects indicating the possible choices
* the user can make; if the objects are components, they
* are rendered properly; non-String
* objects are
* rendered using their toString
methods;
* if this parameter is null
,
* the options are determined by the Look and Feel
* @param initialValue the object that represents the default selection
* for the dialog; only meaningful if options
* is used; can be null
* @return an integer indicating the option chosen by the user,
* or CLOSED_OPTION
if the user closed
* the dialog
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static int showOptionDialog(Component parentComponent,
Object message, String title, int optionType, int messageType,
Icon icon, Object[] options, Object initialValue)
throws HeadlessException {
JOptionPane pane = new JOptionPane(message, messageType,
optionType, icon,
options, initialValue);
pane.setInitialValue(initialValue);
pane.setComponentOrientation(((parentComponent == null) ?
getRootFrame() : parentComponent).getComponentOrientation());
int style = styleFromMessageType(messageType);
JDialog dialog = pane.createDialog(parentComponent, title, style);
pane.selectInitialValue();
dialog.show();
dialog.dispose();
Object selectedValue = pane.getValue();
if(selectedValue == null)
return CLOSED_OPTION;
if(options == null) {
if(selectedValue instanceof Integer)
return ((Integer)selectedValue).intValue();
return CLOSED_OPTION;
}
for(int counter = 0, maxCounter = options.length;
counter < maxCounter; counter++) {
if(options[counter].equals(selectedValue))
return counter;
}
return CLOSED_OPTION;
}
/**
* Creates and returns a new JDialog
wrapping
* this
centered on the parentComponent
* in the parentComponent
's frame.
* title
is the title of the returned dialog.
* The returned JDialog
will not be resizable by the
* user, however programs can invoke setResizable
on
* the JDialog
instance to change this property.
* The returned JDialog
will be set up such that
* once it is closed, or the user clicks on one of the buttons,
* the optionpane's value property will be set accordingly and
* the dialog will be closed. Each time the dialog is made visible,
* it will reset the option pane's value property to
* JOptionPane.UNINITIALIZED_VALUE
to ensure the
* user's subsequent action closes the dialog properly.
*
* @param parentComponent determines the frame in which the dialog
* is displayed; if the parentComponent
has
* no Frame
, a default Frame
is used
* @param title the title string for the dialog
* @return a new JDialog
containing this instance
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public JDialog createDialog(Component parentComponent, String title)
throws HeadlessException {
int style = styleFromMessageType(getMessageType());
return createDialog(parentComponent, title, style);
}
/**
* Creates and returns a new parentless JDialog
* with the specified title.
* The returned JDialog
will not be resizable by the
* user, however programs can invoke setResizable
on
* the JDialog
instance to change this property.
* The returned JDialog
will be set up such that
* once it is closed, or the user clicks on one of the buttons,
* the optionpane's value property will be set accordingly and
* the dialog will be closed. Each time the dialog is made visible,
* it will reset the option pane's value property to
* JOptionPane.UNINITIALIZED_VALUE
to ensure the
* user's subsequent action closes the dialog properly.
*
* @param title the title string for the dialog
* @return a new JDialog
containing this instance
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
* @since 1.6
*/
public JDialog createDialog(String title) throws HeadlessException {
int style = styleFromMessageType(getMessageType());
JDialog dialog = new JDialog((Dialog) null, title, true);
initDialog(dialog, style, null);
return dialog;
}
private JDialog createDialog(Component parentComponent, String title,
int style)
throws HeadlessException {
final JDialog dialog;
Window window = JOptionPane.getWindowForComponent(parentComponent);
if (window instanceof Frame) {
dialog = new JDialog((Frame)window, title, true);
} else {
dialog = new JDialog((Dialog)window, title, true);
}
if (window instanceof SwingUtilities.SharedOwnerFrame) {
WindowListener ownerShutdownListener =
SwingUtilities.getSharedOwnerFrameShutdownListener();
dialog.addWindowListener(ownerShutdownListener);
}
initDialog(dialog, style, parentComponent);
return dialog;
}
private void initDialog(final JDialog dialog, int style, Component parentComponent) {
dialog.setComponentOrientation(this.getComponentOrientation());
Container contentPane = dialog.getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(this, BorderLayout.CENTER);
dialog.setResizable(false);
if (JDialog.isDefaultLookAndFeelDecorated()) {
boolean supportsWindowDecorations =
UIManager.getLookAndFeel().getSupportsWindowDecorations();
if (supportsWindowDecorations) {
dialog.setUndecorated(true);
getRootPane().setWindowDecorationStyle(style);
}
}
dialog.pack();
dialog.setLocationRelativeTo(parentComponent);
final PropertyChangeListener listener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
// Let the defaultCloseOperation handle the closing
// if the user closed the window without selecting a button
// (newValue = null in that case). Otherwise, close the dialog.
if (dialog.isVisible() && event.getSource() == JOptionPane.this &&
(event.getPropertyName().equals(VALUE_PROPERTY)) &&
event.getNewValue() != null &&
event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) {
dialog.setVisible(false);
}
}
};
WindowAdapter adapter = new WindowAdapter() {
private boolean gotFocus = false;
public void windowClosing(WindowEvent we) {
setValue(null);
}
public void windowClosed(WindowEvent e) {
removePropertyChangeListener(listener);
dialog.getContentPane().removeAll();
}
public void windowGainedFocus(WindowEvent we) {
// Once window gets focus, set initial focus
if (!gotFocus) {
selectInitialValue();
gotFocus = true;
}
}
};
dialog.addWindowListener(adapter);
dialog.addWindowFocusListener(adapter);
dialog.addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent ce) {
// reset value to ensure closing works properly
setValue(JOptionPane.UNINITIALIZED_VALUE);
}
});
addPropertyChangeListener(listener);
}
/**
* Brings up an internal confirmation dialog panel. The dialog
* is a information-message dialog titled "Message".
*
* @param parentComponent determines the Frame
* in which the dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a default Frame
is used
* @param message the object to display
*/
public static void showInternalMessageDialog(Component parentComponent,
Object message) {
showInternalMessageDialog(parentComponent, message, UIManager.
getString("OptionPane.messageDialogTitle",
parentComponent), INFORMATION_MESSAGE);
}
/**
* Brings up an internal dialog panel that displays a message
* using a default icon determined by the messageType
* parameter.
*
* @param parentComponent determines the Frame
* in which the dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a default Frame
is used
* @param message the Object
to display
* @param title the title string for the dialog
* @param messageType the type of message to be displayed:
* ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
*/
public static void showInternalMessageDialog(Component parentComponent,
Object message, String title,
int messageType) {
showInternalMessageDialog(parentComponent, message, title, messageType,null);
}
/**
* Brings up an internal dialog panel displaying a message,
* specifying all parameters.
*
* @param parentComponent determines the Frame
* in which the dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a default Frame
is used
* @param message the Object
to display
* @param title the title string for the dialog
* @param messageType the type of message to be displayed:
* ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @param icon an icon to display in the dialog that helps the user
* identify the kind of message that is being displayed
*/
public static void showInternalMessageDialog(Component parentComponent,
Object message,
String title, int messageType,
Icon icon){
showInternalOptionDialog(parentComponent, message, title, DEFAULT_OPTION,
messageType, icon, null, null);
}
/**
* Brings up an internal dialog panel with the options Yes, No
* and Cancel; with the title, Select an Option.
*
* @param parentComponent determines the Frame
in
* which the dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a default Frame
is used
* @param message the Object
to display
* @return an integer indicating the option selected by the user
*/
public static int showInternalConfirmDialog(Component parentComponent,
Object message) {
return showInternalConfirmDialog(parentComponent, message,
UIManager.getString("OptionPane.titleText"),
YES_NO_CANCEL_OPTION);
}
/**
* Brings up a internal dialog panel where the number of choices
* is determined by the optionType
parameter.
*
* @param parentComponent determines the Frame
* in which the dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a default Frame
is used
* @param message the object to display in the dialog; a
* Component
object is rendered as a
* Component
; a String
* object is rendered as a string; other objects
* are converted to a String
using the
* toString
method
* @param title the title string for the dialog
* @param optionType an integer designating the options
* available on the dialog: YES_NO_OPTION
,
* or YES_NO_CANCEL_OPTION
* @return an integer indicating the option selected by the user
*/
public static int showInternalConfirmDialog(Component parentComponent,
Object message, String title,
int optionType) {
return showInternalConfirmDialog(parentComponent, message, title, optionType,
QUESTION_MESSAGE);
}
/**
* Brings up an internal dialog panel where the number of choices
* is determined by the optionType
parameter, where
* the messageType
parameter determines the icon to display.
* The messageType
parameter is primarily used to supply
* a default icon from the Look and Feel.
*
* @param parentComponent determines the Frame
in
* which the dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a default Frame
is used
* @param message the object to display in the dialog; a
* Component
object is rendered as a
* Component
; a String
* object is rendered as a string; other objects are
* converted to a String
using the
* toString
method
* @param title the title string for the dialog
* @param optionType an integer designating the options
* available on the dialog:
* YES_NO_OPTION
, or YES_NO_CANCEL_OPTION
* @param messageType an integer designating the kind of message this is,
* primarily used to determine the icon from the
* pluggable Look and Feel: ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
, QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @return an integer indicating the option selected by the user
*/
public static int showInternalConfirmDialog(Component parentComponent,
Object message,
String title, int optionType,
int messageType) {
return showInternalConfirmDialog(parentComponent, message, title, optionType,
messageType, null);
}
/**
* Brings up an internal dialog panel with a specified icon, where
* the number of choices is determined by the optionType
* parameter.
* The messageType
parameter is primarily used to supply
* a default icon from the look and feel.
*
* @param parentComponent determines the Frame
* in which the dialog is displayed; if null
,
* or if the parentComponent has no Frame, a
* default Frame
is used
* @param message the object to display in the dialog; a
* Component
object is rendered as a
* Component
; a String
* object is rendered as a string; other objects are
* converted to a String
using the
* toString
method
* @param title the title string for the dialog
* @param optionType an integer designating the options available
* on the dialog:
* YES_NO_OPTION
, or
* YES_NO_CANCEL_OPTION
.
* @param messageType an integer designating the kind of message this is,
* primarily used to determine the icon from the pluggable
* Look and Feel: ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
, QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @param icon the icon to display in the dialog
* @return an integer indicating the option selected by the user
*/
public static int showInternalConfirmDialog(Component parentComponent,
Object message,
String title, int optionType,
int messageType, Icon icon) {
return showInternalOptionDialog(parentComponent, message, title, optionType,
messageType, icon, null, null);
}
/**
* Brings up an internal dialog panel with a specified icon, where
* the initial choice is determined by the initialValue
* parameter and the number of choices is determined by the
* optionType
parameter.
*
* If optionType
is YES_NO_OPTION
, or
* YES_NO_CANCEL_OPTION
* and the options
parameter is null
,
* then the options are supplied by the Look and Feel.
*
* The messageType
parameter is primarily used to supply
* a default icon from the look and feel.
*
* @param parentComponent determines the Frame
* in which the dialog is displayed; if null
,
* or if the parentComponent
has no
* Frame
, a default Frame
is used
* @param message the object to display in the dialog; a
* Component
object is rendered as a
* Component
; a String
* object is rendered as a string. Other objects are
* converted to a String
using the
* toString
method
* @param title the title string for the dialog
* @param optionType an integer designating the options available
* on the dialog: YES_NO_OPTION
,
* or YES_NO_CANCEL_OPTION
* @param messageType an integer designating the kind of message this is;
* primarily used to determine the icon from the
* pluggable Look and Feel: ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
, QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @param icon the icon to display in the dialog
* @param options an array of objects indicating the possible choices
* the user can make; if the objects are components, they
* are rendered properly; non-String
* objects are rendered using their toString
* methods; if this parameter is null
,
* the options are determined by the Look and Feel
* @param initialValue the object that represents the default selection
* for the dialog; only meaningful if options
* is used; can be null
* @return an integer indicating the option chosen by the user,
* or CLOSED_OPTION
if the user closed the Dialog
*/
public static int showInternalOptionDialog(Component parentComponent,
Object message,
String title, int optionType,
int messageType, Icon icon,
Object[] options, Object initialValue) {
JOptionPane pane = new JOptionPane(message, messageType,
optionType, icon, options, initialValue);
pane.putClientProperty(PopupFactory_FORCE_HEAVYWEIGHT_POPUP,
Boolean.TRUE);
Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager().
getFocusOwner();
pane.setInitialValue(initialValue);
JInternalFrame dialog =
pane.createInternalFrame(parentComponent, title);
pane.selectInitialValue();
dialog.setVisible(true);
/* Since all input will be blocked until this dialog is dismissed,
* make sure its parent containers are visible first (this component
* is tested below). This is necessary for JApplets, because
* because an applet normally isn't made visible until after its
* start() method returns -- if this method is called from start(),
* the applet will appear to hang while an invisible modal frame
* waits for input.
*/
if (dialog.isVisible() && !dialog.isShowing()) {
Container parent = dialog.getParent();
while (parent != null) {
if (parent.isVisible() == false) {
parent.setVisible(true);
}
parent = parent.getParent();
}
}
// Use reflection to get Container.startLWModal.
try {
Method method = AccessController.doPrivileged(new ModalPrivilegedAction(
Container.class, "startLWModal"));
if (method != null) {
method.invoke(dialog, (Object[])null);
}
} catch (IllegalAccessException ex) {
} catch (IllegalArgumentException ex) {
} catch (InvocationTargetException ex) {
}
if (parentComponent instanceof JInternalFrame) {
try {
((JInternalFrame)parentComponent).setSelected(true);
} catch (java.beans.PropertyVetoException e) {
}
}
Object selectedValue = pane.getValue();
if (fo != null && fo.isShowing()) {
fo.requestFocus();
}
if (selectedValue == null) {
return CLOSED_OPTION;
}
if (options == null) {
if (selectedValue instanceof Integer) {
return ((Integer)selectedValue).intValue();
}
return CLOSED_OPTION;
}
for(int counter = 0, maxCounter = options.length;
counter < maxCounter; counter++) {
if (options[counter].equals(selectedValue)) {
return counter;
}
}
return CLOSED_OPTION;
}
/**
* Shows an internal question-message dialog requesting input from
* the user parented to parentComponent
. The dialog
* is displayed in the Component
's frame,
* and is usually positioned below the Component
.
*
* @param parentComponent the parent Component
* for the dialog
* @param message the Object
to display
*/
public static String showInternalInputDialog(Component parentComponent,
Object message) {
return showInternalInputDialog(parentComponent, message, UIManager.
getString("OptionPane.inputDialogTitle", parentComponent),
QUESTION_MESSAGE);
}
/**
* Shows an internal dialog requesting input from the user parented
* to parentComponent
with the dialog having the title
* title
and message type messageType
.
*
* @param parentComponent the parent Component
for the dialog
* @param message the Object
to display
* @param title the String
to display in the
* dialog title bar
* @param messageType the type of message that is to be displayed:
* ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
* QUESTION_MESSAGE, or PLAIN_MESSAGE
*/
public static String showInternalInputDialog(Component parentComponent,
Object message, String title, int messageType) {
return (String)showInternalInputDialog(parentComponent, message, title,
messageType, null, null, null);
}
/**
* Prompts the user for input in a blocking internal dialog where
* the initial selection, possible selections, and all other
* options can be specified. The user will able to choose from
* selectionValues
, where null
* implies the user can input
* whatever they wish, usually by means of a JTextField
.
* initialSelectionValue
is the initial value to prompt
* the user with. It is up to the UI to decide how best to represent
* the selectionValues
, but usually a
* JComboBox
, JList
, or
* JTextField
will be used.
*
* @param parentComponent the parent Component
for the dialog
* @param message the Object
to display
* @param title the String
to display in the dialog
* title bar
* @param messageType the type of message to be displayed:
* ERROR_MESSAGE
, INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
, or PLAIN_MESSAGE
* @param icon the Icon
image to display
* @param selectionValues an array of Objects
that
* gives the possible selections
* @param initialSelectionValue the value used to initialize the input
* field
* @return user's input, or null
meaning the user
* canceled the input
*/
public static Object showInternalInputDialog(Component parentComponent,
Object message, String title, int messageType, Icon icon,
Object[] selectionValues, Object initialSelectionValue) {
JOptionPane pane = new JOptionPane(message, messageType,
OK_CANCEL_OPTION, icon, null, null);
pane.putClientProperty(PopupFactory_FORCE_HEAVYWEIGHT_POPUP,
Boolean.TRUE);
Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager().
getFocusOwner();
pane.setWantsInput(true);
pane.setSelectionValues(selectionValues);
pane.setInitialSelectionValue(initialSelectionValue);
JInternalFrame dialog =
pane.createInternalFrame(parentComponent, title);
pane.selectInitialValue();
dialog.setVisible(true);
/* Since all input will be blocked until this dialog is dismissed,
* make sure its parent containers are visible first (this component
* is tested below). This is necessary for JApplets, because
* because an applet normally isn't made visible until after its
* start() method returns -- if this method is called from start(),
* the applet will appear to hang while an invisible modal frame
* waits for input.
*/
if (dialog.isVisible() && !dialog.isShowing()) {
Container parent = dialog.getParent();
while (parent != null) {
if (parent.isVisible() == false) {
parent.setVisible(true);
}
parent = parent.getParent();
}
}
// Use reflection to get Container.startLWModal.
try {
Method method = AccessController.doPrivileged(new ModalPrivilegedAction(
Container.class, "startLWModal"));
if (method != null) {
method.invoke(dialog, (Object[])null);
}
} catch (IllegalAccessException ex) {
} catch (IllegalArgumentException ex) {
} catch (InvocationTargetException ex) {
}
if (parentComponent instanceof JInternalFrame) {
try {
((JInternalFrame)parentComponent).setSelected(true);
} catch (java.beans.PropertyVetoException e) {
}
}
if (fo != null && fo.isShowing()) {
fo.requestFocus();
}
Object value = pane.getInputValue();
if (value == UNINITIALIZED_VALUE) {
return null;
}
return value;
}
/**
* Creates and returns an instance of JInternalFrame
.
* The internal frame is created with the specified title,
* and wrapping the JOptionPane
.
* The returned JInternalFrame
is
* added to the JDesktopPane
ancestor of
* parentComponent
, or components
* parent if one its ancestors isn't a JDesktopPane
,
* or if parentComponent
* doesn't have a parent then a RuntimeException
is thrown.
*
* @param parentComponent the parent Component
for
* the internal frame
* @param title the String
to display in the
* frame's title bar
* @return a JInternalFrame
containing a
* JOptionPane
* @exception RuntimeException if parentComponent
does
* not have a valid parent
*/
public JInternalFrame createInternalFrame(Component parentComponent,
String title) {
Container parent =
JOptionPane.getDesktopPaneForComponent(parentComponent);
if (parent == null && (parentComponent == null ||
(parent = parentComponent.getParent()) == null)) {
throw new RuntimeException("JOptionPane: parentComponent does " +
"not have a valid parent");
}
// Option dialogs should be closable only
final JInternalFrame iFrame = new JInternalFrame(title, false, true,
false, false);
iFrame.putClientProperty("JInternalFrame.frameType", "optionDialog");
iFrame.putClientProperty("JInternalFrame.messageType",
Integer.valueOf(getMessageType()));
iFrame.addInternalFrameListener(new InternalFrameAdapter() {
public void internalFrameClosing(InternalFrameEvent e) {
if (getValue() == UNINITIALIZED_VALUE) {
setValue(null);
}
}
});
addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
// Let the defaultCloseOperation handle the closing
// if the user closed the iframe without selecting a button
// (newValue = null in that case). Otherwise, close the dialog.
if (iFrame.isVisible() &&
event.getSource() == JOptionPane.this &&
event.getPropertyName().equals(VALUE_PROPERTY)) {
// Use reflection to get Container.stopLWModal().
try {
Method method = AccessController.doPrivileged(
new ModalPrivilegedAction(
Container.class, "stopLWModal"));
if (method != null) {
method.invoke(iFrame, (Object[])null);
}
} catch (IllegalAccessException ex) {
} catch (IllegalArgumentException ex) {
} catch (InvocationTargetException ex) {
}
try {
iFrame.setClosed(true);
}
catch (java.beans.PropertyVetoException e) {
}
iFrame.setVisible(false);
}
}
});
iFrame.getContentPane().add(this, BorderLayout.CENTER);
if (parent instanceof JDesktopPane) {
parent.add(iFrame, JLayeredPane.MODAL_LAYER);
} else {
parent.add(iFrame, BorderLayout.CENTER);
}
Dimension iFrameSize = iFrame.getPreferredSize();
Dimension rootSize = parent.getSize();
Dimension parentSize = parentComponent.getSize();
iFrame.setBounds((rootSize.width - iFrameSize.width) / 2,
(rootSize.height - iFrameSize.height) / 2,
iFrameSize.width, iFrameSize.height);
// We want dialog centered relative to its parent component
Point iFrameCoord =
SwingUtilities.convertPoint(parentComponent, 0, 0, parent);
int x = (parentSize.width - iFrameSize.width) / 2 + iFrameCoord.x;
int y = (parentSize.height - iFrameSize.height) / 2 + iFrameCoord.y;
// If possible, dialog should be fully visible
int ovrx = x + iFrameSize.width - rootSize.width;
int ovry = y + iFrameSize.height - rootSize.height;
x = Math.max((ovrx > 0? x - ovrx: x), 0);
y = Math.max((ovry > 0? y - ovry: y), 0);
iFrame.setBounds(x, y, iFrameSize.width, iFrameSize.height);
parent.validate();
try {
iFrame.setSelected(true);
} catch (java.beans.PropertyVetoException e) {}
return iFrame;
}
/**
* Returns the specified component's Frame
.
*
* @param parentComponent the Component
to check for a
* Frame
* @return the Frame
that contains the component,
* or getRootFrame
* if the component is null
,
* or does not have a valid Frame
parent
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see #getRootFrame
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static Frame getFrameForComponent(Component parentComponent)
throws HeadlessException {
if (parentComponent == null)
return getRootFrame();
if (parentComponent instanceof Frame)
return (Frame)parentComponent;
return JOptionPane.getFrameForComponent(parentComponent.getParent());
}
/**
* Returns the specified component's toplevel Frame
or
* Dialog
.
*
* @param parentComponent the Component
to check for a
* Frame
or Dialog
* @return the Frame
or Dialog
that
* contains the component, or the default
* frame if the component is null
,
* or does not have a valid
* Frame
or Dialog
parent
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
static Window getWindowForComponent(Component parentComponent)
throws HeadlessException {
if (parentComponent == null)
return getRootFrame();
if (parentComponent instanceof Frame || parentComponent instanceof Dialog)
return (Window)parentComponent;
return JOptionPane.getWindowForComponent(parentComponent.getParent());
}
/**
* Returns the specified component's desktop pane.
*
* @param parentComponent the Component
to check for a
* desktop
* @return the JDesktopPane
that contains the component,
* or null
if the component is null
* or does not have an ancestor that is a
* JInternalFrame
*/
public static JDesktopPane getDesktopPaneForComponent(Component parentComponent) {
if(parentComponent == null)
return null;
if(parentComponent instanceof JDesktopPane)
return (JDesktopPane)parentComponent;
return getDesktopPaneForComponent(parentComponent.getParent());
}
private static final Object sharedFrameKey = JOptionPane.class;
/**
* Sets the frame to use for class methods in which a frame is
* not provided.
*
* Note:
* It is recommended that rather than using this method you supply a valid parent.
*
* @param newRootFrame the default Frame
to use
*/
public static void setRootFrame(Frame newRootFrame) {
if (newRootFrame != null) {
SwingUtilities.appContextPut(sharedFrameKey, newRootFrame);
} else {
SwingUtilities.appContextRemove(sharedFrameKey);
}
}
/**
* Returns the Frame
to use for the class methods in
* which a frame is not provided.
*
* @return the default Frame
to use
* @exception HeadlessException if
* GraphicsEnvironment.isHeadless
returns
* true
* @see #setRootFrame
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static Frame getRootFrame() throws HeadlessException {
Frame sharedFrame =
(Frame)SwingUtilities.appContextGet(sharedFrameKey);
if (sharedFrame == null) {
sharedFrame = SwingUtilities.getSharedOwnerFrame();
SwingUtilities.appContextPut(sharedFrameKey, sharedFrame);
}
return sharedFrame;
}
/**
* Creates a JOptionPane
with a test message.
*/
public JOptionPane() {
this("JOptionPane message");
}
/**
* Creates a instance of JOptionPane
to display a
* message using the
* plain-message message type and the default options delivered by
* the UI.
*
* @param message the Object
to display
*/
public JOptionPane(Object message) {
this(message, PLAIN_MESSAGE);
}
/**
* Creates an instance of JOptionPane
to display a message
* with the specified message type and the default options,
*
* @param message the Object
to display
* @param messageType the type of message to be displayed:
* ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
*/
public JOptionPane(Object message, int messageType) {
this(message, messageType, DEFAULT_OPTION);
}
/**
* Creates an instance of JOptionPane
to display a message
* with the specified message type and options.
*
* @param message the Object
to display
* @param messageType the type of message to be displayed:
* ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @param optionType the options to display in the pane:
* DEFAULT_OPTION
, YES_NO_OPTION
,
* YES_NO_CANCEL_OPTION
,
* OK_CANCEL_OPTION
*/
public JOptionPane(Object message, int messageType, int optionType) {
this(message, messageType, optionType, null);
}
/**
* Creates an instance of JOptionPane
to display a message
* with the specified message type, options, and icon.
*
* @param message the Object
to display
* @param messageType the type of message to be displayed:
* ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @param optionType the options to display in the pane:
* DEFAULT_OPTION
, YES_NO_OPTION
,
* YES_NO_CANCEL_OPTION
,
* OK_CANCEL_OPTION
* @param icon the Icon
image to display
*/
public JOptionPane(Object message, int messageType, int optionType,
Icon icon) {
this(message, messageType, optionType, icon, null);
}
/**
* Creates an instance of JOptionPane
to display a message
* with the specified message type, icon, and options.
* None of the options is initially selected.
*
* The options objects should contain either instances of
* Component
s, (which are added directly) or
* Strings
(which are wrapped in a JButton
).
* If you provide Component
s, you must ensure that when the
* Component
is clicked it messages setValue
* in the created JOptionPane
.
*
* @param message the Object
to display
* @param messageType the type of message to be displayed:
* ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @param optionType the options to display in the pane:
* DEFAULT_OPTION
,
* YES_NO_OPTION
,
* YES_NO_CANCEL_OPTION
,
* OK_CANCEL_OPTION
* @param icon the Icon
image to display
* @param options the choices the user can select
*/
public JOptionPane(Object message, int messageType, int optionType,
Icon icon, Object[] options) {
this(message, messageType, optionType, icon, options, null);
}
/**
* Creates an instance of JOptionPane
to display a message
* with the specified message type, icon, and options, with the
* initially-selected option specified.
*
* @param message the Object
to display
* @param messageType the type of message to be displayed:
* ERROR_MESSAGE
,
* INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
,
* or PLAIN_MESSAGE
* @param optionType the options to display in the pane:
* DEFAULT_OPTION
,
* YES_NO_OPTION
,
* YES_NO_CANCEL_OPTION
,
* OK_CANCEL_OPTION
* @param icon the Icon image to display
* @param options the choices the user can select
* @param initialValue the choice that is initially selected; if
* null
, then nothing will be initially selected;
* only meaningful if options
is used
*/
public JOptionPane(Object message, int messageType, int optionType,
Icon icon, Object[] options, Object initialValue) {
this.message = message;
this.options = options;
this.initialValue = initialValue;
this.icon = icon;
setMessageType(messageType);
setOptionType(optionType);
value = UNINITIALIZED_VALUE;
inputValue = UNINITIALIZED_VALUE;
updateUI();
}
/**
* Sets the UI object which implements the L&F for this component.
*
* @param ui the OptionPaneUI
L&F object
* @see UIDefaults#getUI
* @beaninfo
* bound: true
* hidden: true
* description: The UI object that implements the optionpane's LookAndFeel
*/
public void setUI(OptionPaneUI ui) {
if (this.ui != ui) {
super.setUI(ui);
invalidate();
}
}
/**
* Returns the UI object which implements the L&F for this component.
*
* @return the OptionPaneUI
object
*/
public OptionPaneUI getUI() {
return (OptionPaneUI)ui;
}
/**
* Notification from the UIManager
that the L&F has changed.
* Replaces the current UI object with the latest version from the
* UIManager
.
*
* @see JComponent#updateUI
*/
public void updateUI() {
setUI((OptionPaneUI)UIManager.getUI(this));
}
/**
* Returns the name of the UI class that implements the
* L&F for this component.
*
* @return the string "OptionPaneUI"
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
*/
public String getUIClassID() {
return uiClassID;
}
/**
* Sets the option pane's message-object.
* @param newMessage the Object
to display
* @see #getMessage
*
* @beaninfo
* preferred: true
* bound: true
* description: The optionpane's message object.
*/
public void setMessage(Object newMessage) {
Object oldMessage = message;
message = newMessage;
firePropertyChange(MESSAGE_PROPERTY, oldMessage, message);
}
/**
* Returns the message-object this pane displays.
* @see #setMessage
*
* @return the Object
that is displayed
*/
public Object getMessage() {
return message;
}
/**
* Sets the icon to display. If non-null
, the look and feel
* does not provide an icon.
* @param newIcon the Icon
to display
*
* @see #getIcon
* @beaninfo
* preferred: true
* bound: true
* description: The option pane's type icon.
*/
public void setIcon(Icon newIcon) {
Object oldIcon = icon;
icon = newIcon;
firePropertyChange(ICON_PROPERTY, oldIcon, icon);
}
/**
* Returns the icon this pane displays.
* @return the Icon
that is displayed
*
* @see #setIcon
*/
public Icon getIcon() {
return icon;
}
/**
* Sets the value the user has chosen.
* @param newValue the chosen value
*
* @see #getValue
* @beaninfo
* preferred: true
* bound: true
* description: The option pane's value object.
*/
public void setValue(Object newValue) {
Object oldValue = value;
value = newValue;
firePropertyChange(VALUE_PROPERTY, oldValue, value);
}
/**
* Returns the value the user has selected. UNINITIALIZED_VALUE
* implies the user has not yet made a choice, null
means the
* user closed the window with out choosing anything. Otherwise
* the returned value will be one of the options defined in this
* object.
*
* @return the Object
chosen by the user,
* UNINITIALIZED_VALUE
* if the user has not yet made a choice, or null
if
* the user closed the window without making a choice
*
* @see #setValue
*/
public Object getValue() {
return value;
}
/**
* Sets the options this pane displays. If an element in
* newOptions
is a Component
* it is added directly to the pane,
* otherwise a button is created for the element.
*
* @param newOptions an array of Objects
that create the
* buttons the user can click on, or arbitrary
* Components
to add to the pane
*
* @see #getOptions
* @beaninfo
* bound: true
* description: The option pane's options objects.
*/
public void setOptions(Object[] newOptions) {
Object[] oldOptions = options;
options = newOptions;
firePropertyChange(OPTIONS_PROPERTY, oldOptions, options);
}
/**
* Returns the choices the user can make.
* @return the array of Objects
that give the user's choices
*
* @see #setOptions
*/
public Object[] getOptions() {
if(options != null) {
int optionCount = options.length;
Object[] retOptions = new Object[optionCount];
System.arraycopy(options, 0, retOptions, 0, optionCount);
return retOptions;
}
return options;
}
/**
* Sets the initial value that is to be enabled -- the
* Component
* that has the focus when the pane is initially displayed.
*
* @param newInitialValue the Object
that gets the initial
* keyboard focus
*
* @see #getInitialValue
* @beaninfo
* preferred: true
* bound: true
* description: The option pane's initial value object.
*/
public void setInitialValue(Object newInitialValue) {
Object oldIV = initialValue;
initialValue = newInitialValue;
firePropertyChange(INITIAL_VALUE_PROPERTY, oldIV, initialValue);
}
/**
* Returns the initial value.
*
* @return the Object
that gets the initial keyboard focus
*
* @see #setInitialValue
*/
public Object getInitialValue() {
return initialValue;
}
/**
* Sets the option pane's message type.
* The message type is used by the Look and Feel to determine the
* icon to display (if not supplied) as well as potentially how to
* lay out the parentComponent
.
* @param newType an integer specifying the kind of message to display:
* ERROR_MESSAGE
, INFORMATION_MESSAGE
,
* WARNING_MESSAGE
,
* QUESTION_MESSAGE
, or PLAIN_MESSAGE
* @exception RuntimeException if newType
is not one of the
* legal values listed above
* @see #getMessageType
* @beaninfo
* preferred: true
* bound: true
* description: The option pane's message type.
*/
public void setMessageType(int newType) {
if(newType != ERROR_MESSAGE && newType != INFORMATION_MESSAGE &&
newType != WARNING_MESSAGE && newType != QUESTION_MESSAGE &&
newType != PLAIN_MESSAGE)
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");
int oldType = messageType;
messageType = newType;
firePropertyChange(MESSAGE_TYPE_PROPERTY, oldType, messageType);
}
/**
* Returns the message type.
*
* @return an integer specifying the message type
*
* @see #setMessageType
*/
public int getMessageType() {
return messageType;
}
/**
* Sets the options to display.
* The option type is used by the Look and Feel to
* determine what buttons to show (unless options are supplied).
* @param newType an integer specifying the options the L&F is to display:
* DEFAULT_OPTION
,
* YES_NO_OPTION
,
* YES_NO_CANCEL_OPTION
,
* or OK_CANCEL_OPTION
* @exception RuntimeException if newType
is not one of
* the legal values listed above
*
* @see #getOptionType
* @see #setOptions
* @beaninfo
* preferred: true
* bound: true
* description: The option pane's option type.
*/
public void setOptionType(int newType) {
if(newType != DEFAULT_OPTION && newType != YES_NO_OPTION &&
newType != YES_NO_CANCEL_OPTION && newType != OK_CANCEL_OPTION)
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");
int oldType = optionType;
optionType = newType;
firePropertyChange(OPTION_TYPE_PROPERTY, oldType, optionType);
}
/**
* Returns the type of options that are displayed.
*
* @return an integer specifying the user-selectable options
*
* @see #setOptionType
*/
public int getOptionType() {
return optionType;
}
/**
* Sets the input selection values for a pane that provides the user
* with a list of items to choose from. (The UI provides a widget
* for choosing one of the values.) A null
value
* implies the user can input whatever they wish, usually by means
* of a JTextField
.
*
* Sets wantsInput
to true. Use
* setInitialSelectionValue
to specify the initially-chosen
* value. After the pane as been enabled, inputValue
is
* set to the value the user has selected.
* @param newValues an array of Objects
the user to be
* displayed
* (usually in a list or combo-box) from which
* the user can make a selection
* @see #setWantsInput
* @see #setInitialSelectionValue
* @see #getSelectionValues
* @beaninfo
* bound: true
* description: The option pane's selection values.
*/
public void setSelectionValues(Object[] newValues) {
Object[] oldValues = selectionValues;
selectionValues = newValues;
firePropertyChange(SELECTION_VALUES_PROPERTY, oldValues, newValues);
if(selectionValues != null)
setWantsInput(true);
}
/**
* Returns the input selection values.
*
* @return the array of Objects
the user can select
* @see #setSelectionValues
*/
public Object[] getSelectionValues() {
return selectionValues;
}
/**
* Sets the input value that is initially displayed as selected to the user.
* Only used if wantsInput
is true.
* @param newValue the initially selected value
* @see #setSelectionValues
* @see #getInitialSelectionValue
* @beaninfo
* bound: true
* description: The option pane's initial selection value object.
*/
public void setInitialSelectionValue(Object newValue) {
Object oldValue = initialSelectionValue;
initialSelectionValue = newValue;
firePropertyChange(INITIAL_SELECTION_VALUE_PROPERTY, oldValue,
newValue);
}
/**
* Returns the input value that is displayed as initially selected to the user.
*
* @return the initially selected value
* @see #setInitialSelectionValue
* @see #setSelectionValues
*/
public Object getInitialSelectionValue() {
return initialSelectionValue;
}
/**
* Sets the input value that was selected or input by the user.
* Only used if wantsInput
is true. Note that this method
* is invoked internally by the option pane (in response to user action)
* and should generally not be called by client programs. To set the
* input value initially displayed as selected to the user, use
* setInitialSelectionValue
.
*
* @param newValue the Object
used to set the
* value that the user specified (usually in a text field)
* @see #setSelectionValues
* @see #setInitialSelectionValue
* @see #setWantsInput
* @see #getInputValue
* @beaninfo
* preferred: true
* bound: true
* description: The option pane's input value object.
*/
public void setInputValue(Object newValue) {
Object oldValue = inputValue;
inputValue = newValue;
firePropertyChange(INPUT_VALUE_PROPERTY, oldValue, newValue);
}
/**
* Returns the value the user has input, if wantsInput
* is true.
*
* @return the Object
the user specified,
* if it was one of the objects, or a
* String
if it was a value typed into a
* field
* @see #setSelectionValues
* @see #setWantsInput
* @see #setInputValue
*/
public Object getInputValue() {
return inputValue;
}
/**
* Returns the maximum number of characters to place on a line in a
* message. Default is to return Integer.MAX_VALUE
.
* The value can be
* changed by overriding this method in a subclass.
*
* @return an integer giving the maximum number of characters on a line
*/
public int getMaxCharactersPerLineCount() {
return Integer.MAX_VALUE;
}
/**
* Sets the wantsInput
property.
* If newValue
is true, an input component
* (such as a text field or combo box) whose parent is
* parentComponent
is provided to
* allow the user to input a value. If getSelectionValues
* returns a non-null
array, the input value is one of the
* objects in that array. Otherwise the input value is whatever
* the user inputs.
*
* This is a bound property.
*
* @see #setSelectionValues
* @see #setInputValue
* @beaninfo
* preferred: true
* bound: true
* description: Flag which allows the user to input a value.
*/
public void setWantsInput(boolean newValue) {
boolean oldValue = wantsInput;
wantsInput = newValue;
firePropertyChange(WANTS_INPUT_PROPERTY, oldValue, newValue);
}
/**
* Returns the value of the wantsInput
property.
*
* @return true if an input component will be provided
* @see #setWantsInput
*/
public boolean getWantsInput() {
return wantsInput;
}
/**
* Requests that the initial value be selected, which will set
* focus to the initial value. This method
* should be invoked after the window containing the option pane
* is made visible.
*/
public void selectInitialValue() {
OptionPaneUI ui = getUI();
if (ui != null) {
ui.selectInitialValue(this);
}
}
private static int styleFromMessageType(int messageType) {
switch (messageType) {
case ERROR_MESSAGE:
return JRootPane.ERROR_DIALOG;
case QUESTION_MESSAGE:
return JRootPane.QUESTION_DIALOG;
case WARNING_MESSAGE:
return JRootPane.WARNING_DIALOG;
case INFORMATION_MESSAGE:
return JRootPane.INFORMATION_DIALOG;
case PLAIN_MESSAGE:
default:
return JRootPane.PLAIN_DIALOG;
}
}
// Serialization support.
private void writeObject(ObjectOutputStream s) throws IOException {
Vector