| /* JOptionPane.java |
| Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath 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 for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| |
| package javax.swing; |
| |
| import java.awt.AWTEvent; |
| import java.awt.ActiveEvent; |
| import java.awt.Component; |
| import java.awt.Container; |
| import java.awt.EventQueue; |
| import java.awt.Frame; |
| import java.awt.MenuComponent; |
| import java.awt.Toolkit; |
| import java.awt.event.MouseAdapter; |
| import java.awt.event.MouseMotionAdapter; |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| |
| import javax.accessibility.Accessible; |
| import javax.accessibility.AccessibleContext; |
| import javax.accessibility.AccessibleRole; |
| import javax.swing.plaf.OptionPaneUI; |
| |
| /** |
| * This class creates different types of JDialogs and JInternalFrames that can |
| * ask users for input or pass on information. JOptionPane can be used by |
| * calling one of the show static methods or by creating an instance of |
| * JOptionPane and calling createDialog or createInternalFrame. |
| */ |
| public class JOptionPane extends JComponent implements Accessible |
| { |
| /** |
| * Provides the accessibility features for the <code>JOptionPane</code> |
| * component. |
| */ |
| protected class AccessibleJOptionPane extends JComponent.AccessibleJComponent |
| { |
| private static final long serialVersionUID = 686071432213084821L; |
| |
| /** |
| * Creates a new <code>AccessibleJOptionPane</code> instance. |
| */ |
| protected AccessibleJOptionPane() |
| { |
| // Nothing to do here. |
| } |
| |
| /** |
| * Returns the accessible role of this object, which is always |
| * {@link AccessibleRole#OPTION_PANE}. |
| * |
| * @return the accessible role of this object |
| */ |
| public AccessibleRole getAccessibleRole() |
| { |
| return AccessibleRole.OPTION_PANE; |
| } |
| } |
| |
| private static final long serialVersionUID = 5231143276678566796L; |
| |
| /** The value returned when cancel option is selected. */ |
| public static final int CANCEL_OPTION = 2; |
| |
| /** The value returned when the dialog is closed without a selection. */ |
| public static final int CLOSED_OPTION = -1; |
| |
| /** An option used in confirmation dialog methods. */ |
| public static final int DEFAULT_OPTION = -1; |
| |
| /** The value returned when the no option is selected. */ |
| public static final int NO_OPTION = 1; |
| |
| /** An option used in confirmation dialog methods. */ |
| public static final int OK_CANCEL_OPTION = 2; |
| |
| /** The value returned when the ok option is selected. */ |
| public static final int OK_OPTION = 0; |
| |
| /** An option used in confirmation dialog methods. */ |
| public static final int YES_NO_CANCEL_OPTION = 1; |
| |
| /** An option used in confirmation dialog methods. */ |
| public static final int YES_NO_OPTION = 0; |
| |
| /** The value returned when the yes option is selected. */ |
| public static final int YES_OPTION = 0; |
| |
| /** Identifier for the error message type. */ |
| public static final int ERROR_MESSAGE = 0; |
| |
| /** Identifier for the information message type. */ |
| public static final int INFORMATION_MESSAGE = 1; |
| |
| /** Identifier for the plain message type. */ |
| public static final int PLAIN_MESSAGE = -1; |
| |
| /** Identifier for the question message type. */ |
| public static final int QUESTION_MESSAGE = 3; |
| |
| /** Identifier for the warning message type. */ |
| public static final int WARNING_MESSAGE = 2; |
| |
| /** |
| * The identifier for the propertyChangeEvent when the icon property |
| * changes. |
| */ |
| public static final String ICON_PROPERTY = "icon"; |
| |
| /** |
| * The identifier for the propertyChangeEvent when the initialSelectionValue |
| * property changes. |
| */ |
| public static final String INITIAL_SELECTION_VALUE_PROPERTY = "initialSelectionValue"; |
| |
| /** |
| * The identifier for the propertyChangeEvent when the initialValue property |
| * changes. |
| */ |
| public static final String INITIAL_VALUE_PROPERTY = "initialValue"; |
| |
| /** |
| * The identifier for the propertyChangeEvent when the inputValue property |
| * changes. |
| */ |
| public static final String INPUT_VALUE_PROPERTY = "inputValue"; |
| |
| /** |
| * The identifier for the propertyChangeEvent when the message property |
| * changes. |
| */ |
| public static final String MESSAGE_PROPERTY = "message"; |
| |
| /** |
| * The identifier for the propertyChangeEvent when the messageType property |
| * changes. |
| */ |
| public static final String MESSAGE_TYPE_PROPERTY = "messageType"; |
| |
| /** |
| * The identifier for the propertyChangeEvent when the optionType property |
| * changes. |
| */ |
| public static final String OPTION_TYPE_PROPERTY = "optionType"; |
| |
| /** |
| * The identifier for the propertyChangeEvent when the options property |
| * changes. |
| */ |
| public static final String OPTIONS_PROPERTY = "options"; |
| |
| /** |
| * The identifier for the propertyChangeEvent when the selectionValues |
| * property changes. |
| */ |
| public static final String SELECTION_VALUES_PROPERTY = "selectionValues"; |
| |
| /** |
| * The identifier for the propertyChangeEvent when the value property |
| * changes. |
| */ |
| public static final String VALUE_PROPERTY = "value"; |
| |
| /** |
| * The identifier for the propertyChangeEvent when the wantsInput property |
| * changes. |
| */ |
| public static final String WANTS_INPUT_PROPERTY = "wantsInput"; |
| |
| /** The value returned when the inputValue is uninitialized. */ |
| public static final Object UNINITIALIZED_VALUE = "uninitializedValue"; |
| |
| /** The icon displayed in the dialog/internal frame. */ |
| protected Icon icon; |
| |
| /** The initial selected value in the input component. */ |
| protected Object initialSelectionValue; |
| |
| /** The object that is initially selected for options. */ |
| protected Object initialValue; |
| |
| /** The value the user inputs. */ |
| protected Object inputValue = UNINITIALIZED_VALUE; |
| |
| /** The message displayed in the dialog/internal frame. */ |
| protected Object message; |
| |
| /** The type of message displayed. */ |
| protected int messageType = PLAIN_MESSAGE; |
| |
| /** |
| * The options (usually buttons) aligned at the bottom for the user to |
| * select. |
| */ |
| protected Object[] options; |
| |
| /** The type of options to display. */ |
| protected int optionType = DEFAULT_OPTION; |
| |
| /** The input values the user can select. */ |
| protected Object[] selectionValues; |
| |
| /** The value returned by selecting an option. */ |
| protected Object value = UNINITIALIZED_VALUE; |
| |
| /** Whether the Dialog/InternalFrame needs input. */ |
| protected boolean wantsInput; |
| |
| /** The common frame used when no parent is provided. */ |
| private static Frame privFrame = (Frame) SwingUtilities.getOwnerFrame(null); |
| |
| /** |
| * Creates a new JOptionPane object using a message of "JOptionPane |
| * message", using the PLAIN_MESSAGE type and DEFAULT_OPTION. |
| */ |
| public JOptionPane() |
| { |
| this("JOptionPane message", PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null); |
| } |
| |
| /** |
| * Creates a new JOptionPane object using the given message using the |
| * PLAIN_MESSAGE type and DEFAULT_OPTION. |
| * |
| * @param message The message to display. |
| */ |
| public JOptionPane(Object message) |
| { |
| this(message, PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null); |
| } |
| |
| /** |
| * Creates a new JOptionPane object using the given message and messageType |
| * and DEFAULT_OPTION. |
| * |
| * @param message The message to display. |
| * @param messageType The type of message. |
| */ |
| public JOptionPane(Object message, int messageType) |
| { |
| this(message, messageType, DEFAULT_OPTION, null, null, null); |
| } |
| |
| /** |
| * Creates a new JOptionPane object using the given message, messageType and |
| * optionType. |
| * |
| * @param message The message to display. |
| * @param messageType The type of message. |
| * @param optionType The type of options. |
| */ |
| public JOptionPane(Object message, int messageType, int optionType) |
| { |
| this(message, messageType, optionType, null, null, null); |
| } |
| |
| /** |
| * Creates a new JOptionPane object using the given message, messageType, |
| * optionType and icon. |
| * |
| * @param message The message to display. |
| * @param messageType The type of message. |
| * @param optionType The type of options. |
| * @param icon The icon to display. |
| */ |
| public JOptionPane(Object message, int messageType, int optionType, Icon icon) |
| { |
| this(message, messageType, optionType, icon, null, null); |
| } |
| |
| /** |
| * Creates a new JOptionPane object using the given message, messageType, |
| * optionType, icon and options. |
| * |
| * @param message The message to display. |
| * @param messageType The type of message. |
| * @param optionType The type of options. |
| * @param icon The icon to display. |
| * @param options The options given. |
| */ |
| public JOptionPane(Object message, int messageType, int optionType, |
| Icon icon, Object[] options) |
| { |
| this(message, messageType, optionType, icon, options, null); |
| } |
| |
| /** |
| * Creates a new JOptionPane object using the given message, messageType, |
| * optionType, icon, options and initialValue. The initialValue will be |
| * focused initially. |
| * |
| * @param message The message to display. |
| * @param messageType The type of message. |
| * @param optionType The type of options. |
| * @param icon The icon to display. |
| * @param options The options given. |
| * @param initialValue The component to focus on initially. |
| * |
| * @throws IllegalArgumentException If the messageType or optionType are not |
| * legal values. |
| */ |
| public JOptionPane(Object message, int messageType, int optionType, |
| Icon icon, Object[] options, Object initialValue) |
| { |
| this.message = message; |
| if (! validMessageType(messageType)) |
| throw new IllegalArgumentException("Message Type not legal value."); |
| this.messageType = messageType; |
| if (! validOptionType(optionType)) |
| throw new IllegalArgumentException("Option Type not legal value."); |
| this.optionType = optionType; |
| this.icon = icon; |
| this.options = options; |
| this.initialValue = initialValue; |
| |
| setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); |
| |
| updateUI(); |
| } |
| |
| /** |
| * This method creates a new JDialog that is either centered around the |
| * parent's frame or centered on the screen (if the parent is null). The |
| * JDialog will not be resizable and will be modal. Once the JDialog is |
| * disposed, the inputValue and value properties will be set by the |
| * optionPane. |
| * |
| * @param parentComponent The parent of the Dialog. |
| * @param title The title in the bar of the JDialog. |
| * |
| * @return A new JDialog based on the JOptionPane configuration. |
| */ |
| public JDialog createDialog(Component parentComponent, String title) |
| { |
| Frame toUse = getFrameForComponent(parentComponent); |
| if (toUse == null) |
| toUse = getRootFrame(); |
| |
| JDialog dialog = new JDialog(toUse, title); |
| inputValue = UNINITIALIZED_VALUE; |
| value = UNINITIALIZED_VALUE; |
| |
| dialog.getContentPane().add(this); |
| dialog.setModal(true); |
| dialog.setResizable(false); |
| dialog.pack(); |
| dialog.setLocationRelativeTo(parentComponent); |
| |
| addPropertyChangeListener(new ValuePropertyHandler(dialog)); |
| return dialog; |
| } |
| |
| /** |
| * Handles changes of the value property. Whenever this property changes, |
| * the JOptionPane dialog should be closed. |
| */ |
| private static class ValuePropertyHandler |
| implements PropertyChangeListener |
| { |
| /** |
| * The dialog to close. |
| */ |
| JDialog dialog; |
| |
| /** |
| * Creates a new instance. |
| * |
| * @param d the dialog to be closed |
| */ |
| ValuePropertyHandler(JDialog d) |
| { |
| dialog = d; |
| } |
| |
| /** |
| * Receives notification when any of the properties change. |
| */ |
| public void propertyChange(PropertyChangeEvent p) |
| { |
| String prop = p.getPropertyName(); |
| Object val = p.getNewValue(); |
| if (prop.equals(VALUE_PROPERTY) && val != null |
| && val != UNINITIALIZED_VALUE) |
| { |
| dialog.setVisible(false); |
| } |
| } |
| } |
| |
| /** |
| * This method creates a new JInternalFrame that is in the JLayeredPane |
| * which contains the parentComponent given. If no suitable JLayeredPane |
| * can be found from the parentComponent given, a RuntimeException will be |
| * thrown. |
| * |
| * @param parentComponent The parent to find a JDesktopPane from. |
| * @param title The title of the JInternalFrame. |
| * |
| * @return A new JInternalFrame based on the JOptionPane configuration. |
| * |
| * @throws RuntimeException If no suitable JDesktopPane is found. |
| * |
| * @specnote The specification says that the internal frame is placed |
| * in the nearest <code>JDesktopPane</code> that is found in |
| * <code>parent</code>'s ancestors. The behaviour of the JDK |
| * is that it actually looks up the nearest |
| * <code>JLayeredPane</code> in <code>parent</code>'s ancestors. |
| * So do we. |
| */ |
| public JInternalFrame createInternalFrame(Component parentComponent, |
| String title) |
| throws RuntimeException |
| { |
| // Try to find a JDesktopPane. |
| JLayeredPane toUse = getDesktopPaneForComponent(parentComponent); |
| // If we don't have a JDesktopPane, we try to find a JLayeredPane. |
| if (toUse == null) |
| toUse = JLayeredPane.getLayeredPaneAbove(parentComponent); |
| // If this still fails, we throw a RuntimeException. |
| if (toUse == null) |
| throw new RuntimeException |
| ("parentComponent does not have a valid parent"); |
| |
| JInternalFrame frame = new JInternalFrame(title); |
| |
| inputValue = UNINITIALIZED_VALUE; |
| value = UNINITIALIZED_VALUE; |
| |
| frame.setContentPane(this); |
| frame.setClosable(true); |
| |
| toUse.add(frame); |
| frame.setLayer(JLayeredPane.MODAL_LAYER); |
| |
| frame.pack(); |
| frame.setVisible(true); |
| |
| return frame; |
| } |
| |
| /** |
| * Returns the object that provides accessibility features for this |
| * <code>JOptionPane</code> component. |
| * |
| * @return The accessible context (an instance of |
| * {@link AccessibleJOptionPane}). |
| */ |
| public AccessibleContext getAccessibleContext() |
| { |
| if (accessibleContext == null) |
| accessibleContext = new AccessibleJOptionPane(); |
| return accessibleContext; |
| } |
| |
| /** |
| * This method returns the JDesktopPane for the given parentComponent or |
| * null if none can be found. |
| * |
| * @param parentComponent The component to look in. |
| * |
| * @return The JDesktopPane for the given component or null if none can be |
| * found. |
| */ |
| public static JDesktopPane getDesktopPaneForComponent(Component parentComponent) |
| { |
| return (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class, |
| parentComponent); |
| } |
| |
| /** |
| * This method returns the Frame for the given parentComponent or null if |
| * none can be found. |
| * |
| * @param parentComponent The component to look in. |
| * |
| * @return The Frame for the given component or null if none can be found. |
| */ |
| public static Frame getFrameForComponent(Component parentComponent) |
| { |
| return (Frame) SwingUtilities.getAncestorOfClass(Frame.class, |
| parentComponent); |
| } |
| |
| /** |
| * This method returns the icon displayed. |
| * |
| * @return The icon displayed. |
| */ |
| public Icon getIcon() |
| { |
| return icon; |
| } |
| |
| /** |
| * This method returns the value initially selected from the list of values |
| * the user can input. |
| * |
| * @return The initial selection value. |
| */ |
| public Object getInitialSelectionValue() |
| { |
| return initialSelectionValue; |
| } |
| |
| /** |
| * This method returns the value that is focused from the list of options. |
| * |
| * @return The initial value from options. |
| */ |
| public Object getInitialValue() |
| { |
| return initialValue; |
| } |
| |
| /** |
| * This method returns the value that the user input. |
| * |
| * @return The user's input value. |
| */ |
| public Object getInputValue() |
| { |
| if (getValue().equals(new Integer(CANCEL_OPTION))) |
| setInputValue(null); |
| return inputValue; |
| } |
| |
| /** |
| * This method returns the maximum characters per line. By default, this is |
| * Integer.MAX_VALUE. |
| * |
| * @return The maximum characters per line. |
| */ |
| public int getMaxCharactersPerLineCount() |
| { |
| return Integer.MAX_VALUE; |
| } |
| |
| /** |
| * This method returns the message displayed. |
| * |
| * @return The message displayed. |
| */ |
| public Object getMessage() |
| { |
| return message; |
| } |
| |
| /** |
| * This method returns the message type. |
| * |
| * @return The message type. |
| */ |
| public int getMessageType() |
| { |
| return messageType; |
| } |
| |
| /** |
| * This method returns the options. |
| * |
| * @return The options. |
| */ |
| public Object[] getOptions() |
| { |
| return options; |
| } |
| |
| /** |
| * This method returns the option type. |
| * |
| * @return The option type. |
| */ |
| public int getOptionType() |
| { |
| return optionType; |
| } |
| |
| /** |
| * This method returns the Frame used by JOptionPane dialog's that have no |
| * parent. |
| * |
| * @return The Frame used by dialogs that have no parent. |
| */ |
| public static Frame getRootFrame() |
| { |
| return privFrame; |
| } |
| |
| /** |
| * This method returns the selection values. |
| * |
| * @return The selection values. |
| */ |
| public Object[] getSelectionValues() |
| { |
| return selectionValues; |
| } |
| |
| /** |
| * This method returns the UI used by the JOptionPane. |
| * |
| * @return The UI used by the JOptionPane. |
| */ |
| public OptionPaneUI getUI() |
| { |
| return (OptionPaneUI) ui; |
| } |
| |
| /** |
| * This method returns an identifier to determine which UI class will act as |
| * the UI. |
| * |
| * @return The UI identifier. |
| */ |
| public String getUIClassID() |
| { |
| return "OptionPaneUI"; |
| } |
| |
| /** |
| * This method returns the value that the user selected out of options. |
| * |
| * @return The value that the user selected out of options. |
| */ |
| public Object getValue() |
| { |
| return value; |
| } |
| |
| /** |
| * This method returns whether this JOptionPane wants input. |
| * |
| * @return Whether this JOptionPane wants input. |
| */ |
| public boolean getWantsInput() |
| { |
| return wantsInput; |
| } |
| |
| /** |
| * This method returns a String that describes this JOptionPane. |
| * |
| * @return A String that describes this JOptionPane. |
| */ |
| protected String paramString() |
| { |
| return "JOptionPane"; |
| } |
| |
| /** |
| * This method requests focus for the initial value. |
| */ |
| public void selectInitialValue() |
| { |
| if (ui != null) |
| ((OptionPaneUI) ui).selectInitialValue(this); |
| } |
| |
| /** |
| * This method changes the icon property. |
| * |
| * @param newIcon The new icon to use. |
| */ |
| public void setIcon(Icon newIcon) |
| { |
| if (icon != newIcon) |
| { |
| Icon old = icon; |
| icon = newIcon; |
| firePropertyChange(ICON_PROPERTY, old, icon); |
| } |
| } |
| |
| /** |
| * This method changes the initial selection property. |
| * |
| * @param newValue The new initial selection. |
| */ |
| public void setInitialSelectionValue(Object newValue) |
| { |
| if (initialSelectionValue != newValue) |
| { |
| Object old = initialSelectionValue; |
| initialSelectionValue = newValue; |
| firePropertyChange(INITIAL_SELECTION_VALUE_PROPERTY, old, |
| initialSelectionValue); |
| } |
| } |
| |
| /** |
| * This method changes the initial value property. |
| * |
| * @param newValue The new initial value. |
| */ |
| public void setInitialValue(Object newValue) |
| { |
| if (initialValue != newValue) |
| { |
| Object old = initialValue; |
| initialValue = newValue; |
| firePropertyChange(INITIAL_VALUE_PROPERTY, old, initialValue); |
| } |
| } |
| |
| /** |
| * This method changes the inputValue property. |
| * |
| * @param newValue The new inputValue. |
| */ |
| public void setInputValue(Object newValue) |
| { |
| if (inputValue != newValue) |
| { |
| Object old = inputValue; |
| inputValue = newValue; |
| firePropertyChange(INPUT_VALUE_PROPERTY, old, inputValue); |
| } |
| } |
| |
| /** |
| * This method changes the message property. |
| * |
| * @param newMessage The new message. |
| */ |
| public void setMessage(Object newMessage) |
| { |
| if (message != newMessage) |
| { |
| Object old = message; |
| message = newMessage; |
| firePropertyChange(MESSAGE_PROPERTY, old, message); |
| } |
| } |
| |
| /** |
| * This method changes the messageType property. |
| * |
| * @param newType The new messageType. |
| * |
| * @throws IllegalArgumentException If the messageType is not valid. |
| */ |
| public void setMessageType(int newType) |
| { |
| if (! validMessageType(newType)) |
| throw new IllegalArgumentException("Message Type not legal value."); |
| if (newType != messageType) |
| { |
| int old = messageType; |
| messageType = newType; |
| firePropertyChange(MESSAGE_TYPE_PROPERTY, old, messageType); |
| } |
| } |
| |
| /** |
| * This method changes the options property. |
| * |
| * @param newOptions The new options. |
| */ |
| public void setOptions(Object[] newOptions) |
| { |
| if (options != newOptions) |
| { |
| Object[] old = options; |
| options = newOptions; |
| firePropertyChange(OPTIONS_PROPERTY, old, options); |
| } |
| } |
| |
| /** |
| * This method changes the optionType property. |
| * |
| * @param newType The new optionType. |
| * |
| * @throws IllegalArgumentException If the optionType is not valid. |
| */ |
| public void setOptionType(int newType) |
| { |
| if (! validOptionType(newType)) |
| throw new IllegalArgumentException("Option Type not legal value."); |
| if (newType != optionType) |
| { |
| int old = optionType; |
| optionType = newType; |
| firePropertyChange(OPTION_TYPE_PROPERTY, old, optionType); |
| } |
| } |
| |
| /** |
| * This method changes the Frame used for JOptionPane dialogs that have no |
| * parent. |
| * |
| * @param newRootFrame The Frame to use for dialogs that have no parent. |
| */ |
| public static void setRootFrame(Frame newRootFrame) |
| { |
| privFrame = newRootFrame; |
| } |
| |
| /** |
| * This method changes the selectionValues property. |
| * |
| * @param newValues The new selectionValues. |
| */ |
| public void setSelectionValues(Object[] newValues) |
| { |
| if (newValues != selectionValues) |
| { |
| if (newValues != null) |
| wantsInput = true; |
| Object[] old = selectionValues; |
| selectionValues = newValues; |
| firePropertyChange(SELECTION_VALUES_PROPERTY, old, selectionValues); |
| } |
| } |
| |
| /** |
| * This method sets the UI used with the JOptionPane. |
| * |
| * @param ui The UI used with the JOptionPane. |
| */ |
| public void setUI(OptionPaneUI ui) |
| { |
| super.setUI(ui); |
| } |
| |
| /** |
| * This method sets the value has been selected out of options. |
| * |
| * @param newValue The value that has been selected out of options. |
| */ |
| public void setValue(Object newValue) |
| { |
| if (value != newValue) |
| { |
| Object old = value; |
| value = newValue; |
| firePropertyChange(VALUE_PROPERTY, old, value); |
| } |
| } |
| |
| /** |
| * This method changes the wantsInput property. |
| * |
| * @param newValue Whether this JOptionPane requires input. |
| */ |
| public void setWantsInput(boolean newValue) |
| { |
| if (wantsInput != newValue) |
| { |
| boolean old = wantsInput; |
| wantsInput = newValue; |
| firePropertyChange(WANTS_INPUT_PROPERTY, old, wantsInput); |
| } |
| } |
| |
| /** |
| * This method shows a confirmation dialog with the title "Select an Option" |
| * and displays the given message. The parent frame will be the same as the |
| * parent frame of the given parentComponent. This method returns the |
| * option chosen by the user. |
| * |
| * @param parentComponent The parentComponent to find a frame in. |
| * @param message The message to display. |
| * |
| * @return The option that was selected. |
| */ |
| public static int showConfirmDialog(Component parentComponent, Object message) |
| { |
| JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE); |
| JDialog dialog = pane.createDialog(parentComponent, "Select an Option"); |
| dialog.show(); |
| |
| if (pane.getValue() instanceof Integer) |
| return ((Integer) pane.getValue()).intValue(); |
| return -1; |
| } |
| |
| /** |
| * This method shows a confirmation dialog with the given message, |
| * optionType and title. The frame that owns the dialog will be the same |
| * frame that holds the given parentComponent. This method returns the |
| * option that was chosen. |
| * |
| * @param parentComponent The component to find a frame in. |
| * @param message The message displayed. |
| * @param title The title of the dialog. |
| * @param optionType The optionType. |
| * |
| * @return The option that was chosen. |
| */ |
| public static int showConfirmDialog(Component parentComponent, |
| Object message, String title, |
| int optionType) |
| { |
| JOptionPane pane = new JOptionPane(message, PLAIN_MESSAGE, optionType); |
| JDialog dialog = pane.createDialog(parentComponent, title); |
| dialog.show(); |
| |
| if (pane.getValue() instanceof Integer) |
| return ((Integer) pane.getValue()).intValue(); |
| return -1; |
| } |
| |
| /** |
| * This method shows a confirmation dialog with the given message, title, |
| * messageType and optionType. The frame owner will be the same frame as |
| * the one that holds the given parentComponent. This method returns the |
| * option selected by the user. |
| * |
| * @param parentComponent The component to find a frame in. |
| * @param message The message displayed. |
| * @param title The title of the dialog. |
| * @param optionType The optionType. |
| * @param messageType The messageType. |
| * |
| * @return The selected option. |
| */ |
| public static int showConfirmDialog(Component parentComponent, |
| Object message, String title, |
| int optionType, int messageType) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType, optionType); |
| JDialog dialog = pane.createDialog(parentComponent, title); |
| dialog.show(); |
| |
| if (pane.getValue() instanceof Integer) |
| return ((Integer) pane.getValue()).intValue(); |
| return -1; |
| } |
| |
| /** |
| * This method shows a confirmation dialog with the given message, title, |
| * optionType, messageType and icon. The frame owner will be the same as |
| * the one that holds the given parentComponent. This method returns the |
| * option selected by the user. |
| * |
| * @param parentComponent The component to find a frame in. |
| * @param message The message displayed. |
| * @param title The title of the dialog. |
| * @param optionType The optionType. |
| * @param messageType The messsageType. |
| * @param icon The icon displayed. |
| * |
| * @return The selected option. |
| */ |
| public static int showConfirmDialog(Component parentComponent, |
| Object message, String title, |
| int optionType, int messageType, |
| Icon icon) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType, optionType, icon); |
| JDialog dialog = pane.createDialog(parentComponent, title); |
| dialog.show(); |
| |
| if (pane.getValue() instanceof Integer) |
| return ((Integer) pane.getValue()).intValue(); |
| return -1; |
| } |
| |
| /** |
| * This method will show a QUESTION_MESSAGE input dialog with the given |
| * message. No selectionValues is set so the Look and Feel will usually |
| * give the user a TextField to fill out. The frame owner will be the same |
| * frame that holds the given parentComponent. This method will return the |
| * value entered by the user. |
| * |
| * @param parentComponent The component to find a frame in. |
| * @param message The message displayed. |
| * |
| * @return The value entered by the user. |
| */ |
| public static String showInputDialog(Component parentComponent, |
| Object message) |
| { |
| JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE); |
| pane.setWantsInput(true); |
| JDialog dialog = pane.createDialog(parentComponent, null); |
| dialog.show(); |
| |
| return (String) pane.getInputValue(); |
| } |
| |
| /** |
| * This method will show a QUESTION_MESSAGE type input dialog with the given |
| * message and initialSelectionValue. Since there is no selectionValues |
| * set, the Look and Feel will usually give a TextField to fill out. The |
| * frame owner will be the same as the one that holds the given |
| * parentComponent. This method will return the value entered by the user. |
| * |
| * @param parentComponent The component to find a frame in. |
| * @param message The message to display. |
| * @param initialSelectionValue The initially selected value. |
| * |
| * @return The value the user input. |
| */ |
| public static String showInputDialog(Component parentComponent, |
| Object message, |
| Object initialSelectionValue) |
| { |
| JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE); |
| pane.setInitialSelectionValue(initialSelectionValue); |
| pane.setWantsInput(true); |
| JDialog dialog = pane.createDialog(parentComponent, null); |
| dialog.show(); |
| |
| return (String) pane.getInputValue(); |
| } |
| |
| /** |
| * This method displays a new input dialog with the given message, title and |
| * messageType. Since no selectionValues value is given, the Look and Feel |
| * will usually give the user a TextField to input data to. This method |
| * returns the value the user inputs. |
| * |
| * @param parentComponent The component to find a frame in. |
| * @param message The message to display. |
| * @param title The title of the dialog. |
| * @param messageType The messageType. |
| * |
| * @return The value the user input. |
| */ |
| public static String showInputDialog(Component parentComponent, |
| Object message, String title, |
| int messageType) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType); |
| pane.setWantsInput(true); |
| JDialog dialog = pane.createDialog(parentComponent, title); |
| dialog.show(); |
| |
| return (String) pane.getInputValue(); |
| } |
| |
| /** |
| * This method shows an input dialog with the given message, title, |
| * messageType, icon, selectionValues, and initialSelectionValue. This |
| * method returns the value that the user selects. |
| * |
| * @param parentComponent The component to find a frame in. |
| * @param message The message displayed. |
| * @param title The title of the dialog. |
| * @param messageType The messageType. |
| * @param icon The icon displayed. |
| * @param selectionValues The list of values to select from. |
| * @param initialSelectionValue The initially selected value. |
| * |
| * @return The user selected value. |
| */ |
| public static Object showInputDialog(Component parentComponent, |
| Object message, String title, |
| int messageType, Icon icon, |
| Object[] selectionValues, |
| Object initialSelectionValue) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType); |
| pane.setWantsInput(true); |
| pane.setIcon(icon); |
| pane.setSelectionValues(selectionValues); |
| pane.setInitialSelectionValue(initialSelectionValue); |
| JDialog dialog = pane.createDialog(parentComponent, title); |
| dialog.show(); |
| |
| return pane.getInputValue(); |
| } |
| |
| /** |
| * This method shows a QUESTION_MESSAGE type input dialog. Since no |
| * selectionValues is set, the Look and Feel will usually give the user a |
| * TextField to input data to. This method returns the value the user |
| * inputs. |
| * |
| * @param message The message to display. |
| * |
| * @return The user selected value. |
| */ |
| public static String showInputDialog(Object message) |
| { |
| JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE); |
| pane.setWantsInput(true); |
| JDialog dialog = pane.createDialog(null, null); |
| dialog.show(); |
| |
| return (String) pane.getInputValue(); |
| } |
| |
| /** |
| * This method shows a QUESTION_MESSAGE type input dialog. Since no |
| * selectionValues is set, the Look and Feel will usually give the user a |
| * TextField to input data to. The input component will be initialized with |
| * the initialSelectionValue. This method returns the value the user |
| * inputs. |
| * |
| * @param message The message to display. |
| * @param initialSelectionValue The initialSelectionValue. |
| * |
| * @return The user selected value. |
| */ |
| public static String showInputDialog(Object message, |
| Object initialSelectionValue) |
| { |
| JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE); |
| pane.setWantsInput(true); |
| pane.setInitialSelectionValue(initialSelectionValue); |
| JDialog dialog = pane.createDialog(null, null); |
| dialog.show(); |
| |
| return (String) pane.getInputValue(); |
| } |
| |
| /** |
| * This method shows an internal confirmation dialog with the given message. |
| * The internal frame dialog will be placed in the first JDesktopPane |
| * ancestor of the given parentComponent. This method will return the value |
| * selected. |
| * |
| * @param parentComponent The parent to find a JDesktopPane in. |
| * @param message The message to display. |
| * |
| * @return The value selected. |
| */ |
| public static int showInternalConfirmDialog(Component parentComponent, |
| Object message) |
| { |
| JOptionPane pane = new JOptionPane(message); |
| JInternalFrame frame = pane.createInternalFrame(parentComponent, null); |
| |
| startModal(frame); |
| |
| if (pane.getValue() instanceof Integer) |
| return ((Integer) pane.getValue()).intValue(); |
| return -1; |
| } |
| |
| /** |
| * This method shows an internal confirmation dialog with the given message, |
| * optionType and title. The internal frame dialog will be placed in the |
| * first JDesktopPane ancestor of the given parentComponent. This method |
| * will return the selected value. |
| * |
| * @param parentComponent The parent to find a JDesktopPane in. |
| * @param message The message to display. |
| * @param title The title to display. |
| * @param optionType The option type. |
| * |
| * @return The selected value. |
| */ |
| public static int showInternalConfirmDialog(Component parentComponent, |
| Object message, String title, |
| int optionType) |
| { |
| JOptionPane pane = new JOptionPane(message, PLAIN_MESSAGE, optionType); |
| JInternalFrame frame = pane.createInternalFrame(parentComponent, title); |
| |
| startModal(frame); |
| |
| if (pane.getValue() instanceof Integer) |
| return ((Integer) pane.getValue()).intValue(); |
| return -1; |
| } |
| |
| /** |
| * This method shows an internal confirmation dialog with the given message, |
| * title, optionTypes and icon for the given message type. The internal |
| * confirmation dialog will be placed in the first instance of |
| * JDesktopPane ancestor of the given parentComponent. |
| * |
| * @param parentComponent The component to find a JDesktopPane in. |
| * @param message The message to display. |
| * @param title The title of the dialog. |
| * @param optionType The option type. |
| * @param messageType The message type. |
| * |
| * @return The selected value. |
| */ |
| public static int showInternalConfirmDialog(Component parentComponent, |
| Object message, String title, |
| int optionType, int messageType) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType, optionType); |
| JInternalFrame frame = pane.createInternalFrame(parentComponent, title); |
| |
| startModal(frame); |
| |
| if (pane.getValue() instanceof Integer) |
| return ((Integer) pane.getValue()).intValue(); |
| return -1; |
| } |
| |
| /** |
| * This method shows an internal confirmation dialog with the given message, |
| * title, option type, message type, and icon. The internal frame dialog |
| * will be placed in the first JDesktopPane ancestor that is found in the |
| * given parentComponent. This method returns the selected value. |
| * |
| * @param parentComponent The parent to find a JDesktopPane in. |
| * @param message The message to display. |
| * @param title The title to display. |
| * @param optionType The option type. |
| * @param messageType The message type. |
| * @param icon The icon to display. |
| * |
| * @return The selected value. |
| */ |
| public static int showInternalConfirmDialog(Component parentComponent, |
| Object message, String title, |
| int optionType, int messageType, |
| Icon icon) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType, optionType, icon); |
| JInternalFrame frame = pane.createInternalFrame(parentComponent, title); |
| |
| startModal(frame); |
| |
| if (pane.getValue() instanceof Integer) |
| return ((Integer) pane.getValue()).intValue(); |
| return -1; |
| } |
| |
| /** |
| * This method shows an internal input dialog with the given message. The |
| * internal frame dialog will be placed in the first JDesktopPane ancestor |
| * of the given parent component. This method returns the value input by |
| * the user. |
| * |
| * @param parentComponent The parent to find a JDesktopPane in. |
| * @param message The message to display. |
| * |
| * @return The user selected value. |
| */ |
| public static String showInternalInputDialog(Component parentComponent, |
| Object message) |
| { |
| JOptionPane pane = new JOptionPane(message); |
| pane.setWantsInput(true); |
| JInternalFrame frame = pane.createInternalFrame(parentComponent, null); |
| |
| startModal(frame); |
| |
| return (String) pane.getInputValue(); |
| } |
| |
| /** |
| * This method shows an internal input dialog with the given message, title |
| * and message type. The internal input dialog will be placed in the first |
| * JDesktopPane ancestor found in the given parent component. This method |
| * will return the input value given by the user. |
| * |
| * @param parentComponent The component to find a JDesktopPane in. |
| * @param message The message to display. |
| * @param title The title to display. |
| * @param messageType The message type. |
| * |
| * @return The user input value. |
| */ |
| public static String showInternalInputDialog(Component parentComponent, |
| Object message, String title, |
| int messageType) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType); |
| pane.setWantsInput(true); |
| JInternalFrame frame = pane.createInternalFrame(parentComponent, title); |
| |
| startModal(frame); |
| |
| return (String) pane.getInputValue(); |
| } |
| |
| /** |
| * This method shows an internal input dialog with the given message, title |
| * message type, icon, selection value list and initial selection value. |
| * The internal frame dialog will be placed in the first JDesktopPane |
| * ancestor found in the given parent component. This method returns the |
| * input value from the user. |
| * |
| * @param parentComponent The parent to find a JDesktopPane in. |
| * @param message The message to display. |
| * @param title The title to display. |
| * @param messageType The message type. |
| * @param icon The icon to display. |
| * @param selectionValues The selection value list. |
| * @param initialSelectionValue The initial selection value. |
| * |
| * @return The user input value. |
| */ |
| public static Object showInternalInputDialog(Component parentComponent, |
| Object message, String title, |
| int messageType, Icon icon, |
| Object[] selectionValues, |
| Object initialSelectionValue) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType); |
| pane.setWantsInput(true); |
| pane.setIcon(icon); |
| pane.setSelectionValues(selectionValues); |
| pane.setInitialSelectionValue(initialSelectionValue); |
| JInternalFrame frame = pane.createInternalFrame(parentComponent, title); |
| |
| startModal(frame); |
| |
| return pane.getInputValue(); |
| } |
| |
| /** |
| * This method shows an internal message dialog with the given message. The |
| * internal frame dialog will be placed in the first JDesktopPane ancestor |
| * found in the given parent component. |
| * |
| * @param parentComponent The component to find a JDesktopPane in. |
| * @param message The message to display. |
| */ |
| public static void showInternalMessageDialog(Component parentComponent, |
| Object message) |
| { |
| JOptionPane pane = new JOptionPane(message); |
| JInternalFrame frame = pane.createInternalFrame(parentComponent, null); |
| |
| startModal(frame); |
| } |
| |
| /** |
| * This method shows an internal message dialog with the given message, |
| * title and message type. The internal message dialog is placed in the |
| * first JDesktopPane ancestor found in the given parent component. |
| * |
| * @param parentComponent The parent component to find a JDesktopPane in. |
| * @param message The message to display. |
| * @param title The title to display. |
| * @param messageType The message type. |
| */ |
| public static void showInternalMessageDialog(Component parentComponent, |
| Object message, String title, |
| int messageType) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType); |
| JInternalFrame frame = pane.createInternalFrame(parentComponent, title); |
| |
| startModal(frame); |
| } |
| |
| /** |
| * This method shows an internal message dialog with the given message, |
| * title, message type and icon. The internal message dialog is placed in |
| * the first JDesktopPane ancestor found in the given parent component. |
| * |
| * @param parentComponent The component to find a JDesktopPane in. |
| * @param message The message to display. |
| * @param title The title to display. |
| * @param messageType The message type. |
| * @param icon The icon to display. |
| */ |
| public static void showInternalMessageDialog(Component parentComponent, |
| Object message, String title, |
| int messageType, Icon icon) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType); |
| pane.setIcon(icon); |
| JInternalFrame frame = pane.createInternalFrame(parentComponent, title); |
| |
| startModal(frame); |
| } |
| |
| /** |
| * This method displays an internal option dialog with the given message, |
| * title, option type, message type, icon, option list, and initial option |
| * value. The internal option dialog is placed in the first JDesktopPane |
| * ancestor found in the parent component. This method returns the option |
| * selected. |
| * |
| * @param parentComponent The parent to find a JDesktopPane in. |
| * @param message The message displayed. |
| * @param title The title displayed. |
| * @param optionType The option type. |
| * @param messageType The message type. |
| * @param icon The icon to display. |
| * @param options The array of options. |
| * @param initialValue The initial value selected. |
| * |
| * @return The option that was selected. |
| */ |
| 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); |
| |
| JInternalFrame frame = pane.createInternalFrame(parentComponent, title); |
| |
| startModal(frame); |
| |
| if (pane.getValue() instanceof Integer) |
| return ((Integer) pane.getValue()).intValue(); |
| return -1; |
| } |
| |
| /** |
| * This method shows an INFORMATION_MESSAGE type message dialog. |
| * |
| * @param parentComponent The component to find a frame in. |
| * @param message The message displayed. |
| */ |
| public static void showMessageDialog(Component parentComponent, |
| Object message) |
| { |
| JOptionPane pane = new JOptionPane(message, INFORMATION_MESSAGE); |
| JDialog dialog = pane.createDialog(parentComponent, null); |
| dialog.show(); |
| } |
| |
| /** |
| * This method shows a message dialog with the given message, title and |
| * messageType. |
| * |
| * @param parentComponent The component to find a frame in. |
| * @param message The message displayed. |
| * @param title The title of the dialog. |
| * @param messageType The messageType. |
| */ |
| public static void showMessageDialog(Component parentComponent, |
| Object message, String title, |
| int messageType) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType); |
| JDialog dialog = pane.createDialog(parentComponent, title); |
| dialog.show(); |
| } |
| |
| /** |
| * This method shows a message dialog with the given message, title, |
| * messageType and icon. |
| * |
| * @param parentComponent The component to find a frame in. |
| * @param message The message displayed. |
| * @param title The title of the dialog. |
| * @param messageType The messageType. |
| * @param icon The icon displayed. |
| */ |
| public static void showMessageDialog(Component parentComponent, |
| Object message, String title, |
| int messageType, Icon icon) |
| { |
| JOptionPane pane = new JOptionPane(message, messageType); |
| pane.setIcon(icon); |
| JDialog dialog = pane.createDialog(parentComponent, title); |
| dialog.show(); |
| } |
| |
| /** |
| * This method shows an option dialog with the given message, title, |
| * optionType, messageType, icon, options and initialValue. This method |
| * returns the option that was selected. |
| * |
| * @param parentComponent The component to find a frame in. |
| * @param message The message displayed. |
| * @param title The title of the dialog. |
| * @param optionType The optionType. |
| * @param messageType The messageType. |
| * @param icon The icon displayed. |
| * @param options The options to choose from. |
| * @param initialValue The initial value. |
| * |
| * @return The selected option. |
| */ |
| public static int showOptionDialog(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); |
| |
| JDialog dialog = pane.createDialog(parentComponent, title); |
| dialog.show(); |
| |
| if (pane.getValue() instanceof Integer) |
| return ((Integer) pane.getValue()).intValue(); |
| return -1; |
| } |
| |
| /** |
| * This method resets the UI to the Look and Feel default. |
| */ |
| public void updateUI() |
| { |
| setUI((OptionPaneUI) UIManager.getUI(this)); |
| } |
| |
| /** |
| * This method returns true if the key is a valid messageType. |
| * |
| * @param key The key to check. |
| * |
| * @return True if key is valid. |
| */ |
| private boolean validMessageType(int key) |
| { |
| switch (key) |
| { |
| case ERROR_MESSAGE: |
| case INFORMATION_MESSAGE: |
| case PLAIN_MESSAGE: |
| case QUESTION_MESSAGE: |
| case WARNING_MESSAGE: |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * This method returns true if the key is a valid optionType. |
| * |
| * @param key The key to check. |
| * |
| * @return True if key is valid. |
| */ |
| private boolean validOptionType(int key) |
| { |
| switch (key) |
| { |
| case DEFAULT_OPTION: |
| case OK_CANCEL_OPTION: |
| case YES_NO_CANCEL_OPTION: |
| case YES_NO_OPTION: |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * This helper method makes the JInternalFrame wait until it is notified by |
| * an InternalFrameClosing event. This method also adds the given |
| * JOptionPane to the JInternalFrame and sizes it according to the |
| * JInternalFrame's preferred size. |
| * |
| * @param f The JInternalFrame to make modal. |
| */ |
| private static void startModal(JInternalFrame f) |
| { |
| // We need to add an additional glasspane-like component directly |
| // below the frame, which intercepts all mouse events that are not |
| // directed at the frame itself. |
| JPanel modalInterceptor = new JPanel(); |
| modalInterceptor.setOpaque(false); |
| JLayeredPane lp = JLayeredPane.getLayeredPaneAbove(f); |
| lp.setLayer(modalInterceptor, JLayeredPane.MODAL_LAYER.intValue()); |
| modalInterceptor.setBounds(0, 0, lp.getWidth(), lp.getHeight()); |
| modalInterceptor.addMouseListener(new MouseAdapter(){}); |
| modalInterceptor.addMouseMotionListener(new MouseMotionAdapter(){}); |
| lp.add(modalInterceptor); |
| f.toFront(); |
| |
| // We need to explicitly dispatch events when we are blocking the event |
| // dispatch thread. |
| EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); |
| try |
| { |
| while (! f.isClosed()) |
| { |
| if (EventQueue.isDispatchThread()) |
| { |
| // The getNextEventMethod() issues wait() when no |
| // event is available, so we don't need do explicitly wait(). |
| AWTEvent ev = queue.getNextEvent(); |
| // This mimics EventQueue.dispatchEvent(). We can't use |
| // EventQueue.dispatchEvent() directly, because it is |
| // protected, unfortunately. |
| if (ev instanceof ActiveEvent) |
| ((ActiveEvent) ev).dispatch(); |
| else if (ev.getSource() instanceof Component) |
| ((Component) ev.getSource()).dispatchEvent(ev); |
| else if (ev.getSource() instanceof MenuComponent) |
| ((MenuComponent) ev.getSource()).dispatchEvent(ev); |
| // Other events are ignored as per spec in |
| // EventQueue.dispatchEvent |
| } |
| else |
| { |
| // Give other threads a chance to become active. |
| Thread.yield(); |
| } |
| } |
| } |
| catch (InterruptedException ex) |
| { |
| // If we get interrupted, then leave the modal state. |
| } |
| finally |
| { |
| // Clean up the modal interceptor. |
| lp.remove(modalInterceptor); |
| |
| // Remove the internal frame from its parent, so it is no longer |
| // lurking around and clogging memory. |
| Container parent = f.getParent(); |
| if (parent != null) |
| parent.remove(f); |
| } |
| } |
| } |