001 /* JOptionPane.java
002 Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038
039 package javax.swing;
040
041 import java.awt.AWTEvent;
042 import java.awt.ActiveEvent;
043 import java.awt.Component;
044 import java.awt.Container;
045 import java.awt.EventQueue;
046 import java.awt.Frame;
047 import java.awt.MenuComponent;
048 import java.awt.Toolkit;
049 import java.awt.event.MouseAdapter;
050 import java.awt.event.MouseMotionAdapter;
051 import java.beans.PropertyChangeEvent;
052 import java.beans.PropertyChangeListener;
053
054 import javax.accessibility.Accessible;
055 import javax.accessibility.AccessibleContext;
056 import javax.accessibility.AccessibleRole;
057 import javax.swing.plaf.OptionPaneUI;
058
059 /**
060 * This class creates different types of JDialogs and JInternalFrames that can
061 * ask users for input or pass on information. JOptionPane can be used by
062 * calling one of the show static methods or by creating an instance of
063 * JOptionPane and calling createDialog or createInternalFrame.
064 */
065 public class JOptionPane extends JComponent implements Accessible
066 {
067 /**
068 * Provides the accessibility features for the <code>JOptionPane</code>
069 * component.
070 */
071 protected class AccessibleJOptionPane extends JComponent.AccessibleJComponent
072 {
073 private static final long serialVersionUID = 686071432213084821L;
074
075 /**
076 * Creates a new <code>AccessibleJOptionPane</code> instance.
077 */
078 protected AccessibleJOptionPane()
079 {
080 // Nothing to do here.
081 }
082
083 /**
084 * Returns the accessible role of this object, which is always
085 * {@link AccessibleRole#OPTION_PANE}.
086 *
087 * @return the accessible role of this object
088 */
089 public AccessibleRole getAccessibleRole()
090 {
091 return AccessibleRole.OPTION_PANE;
092 }
093 }
094
095 private static final long serialVersionUID = 5231143276678566796L;
096
097 /** The value returned when cancel option is selected. */
098 public static final int CANCEL_OPTION = 2;
099
100 /** The value returned when the dialog is closed without a selection. */
101 public static final int CLOSED_OPTION = -1;
102
103 /** An option used in confirmation dialog methods. */
104 public static final int DEFAULT_OPTION = -1;
105
106 /** The value returned when the no option is selected. */
107 public static final int NO_OPTION = 1;
108
109 /** An option used in confirmation dialog methods. */
110 public static final int OK_CANCEL_OPTION = 2;
111
112 /** The value returned when the ok option is selected. */
113 public static final int OK_OPTION = 0;
114
115 /** An option used in confirmation dialog methods. */
116 public static final int YES_NO_CANCEL_OPTION = 1;
117
118 /** An option used in confirmation dialog methods. */
119 public static final int YES_NO_OPTION = 0;
120
121 /** The value returned when the yes option is selected. */
122 public static final int YES_OPTION = 0;
123
124 /** Identifier for the error message type. */
125 public static final int ERROR_MESSAGE = 0;
126
127 /** Identifier for the information message type. */
128 public static final int INFORMATION_MESSAGE = 1;
129
130 /** Identifier for the plain message type. */
131 public static final int PLAIN_MESSAGE = -1;
132
133 /** Identifier for the question message type. */
134 public static final int QUESTION_MESSAGE = 3;
135
136 /** Identifier for the warning message type. */
137 public static final int WARNING_MESSAGE = 2;
138
139 /**
140 * The identifier for the propertyChangeEvent when the icon property
141 * changes.
142 */
143 public static final String ICON_PROPERTY = "icon";
144
145 /**
146 * The identifier for the propertyChangeEvent when the initialSelectionValue
147 * property changes.
148 */
149 public static final String INITIAL_SELECTION_VALUE_PROPERTY = "initialSelectionValue";
150
151 /**
152 * The identifier for the propertyChangeEvent when the initialValue property
153 * changes.
154 */
155 public static final String INITIAL_VALUE_PROPERTY = "initialValue";
156
157 /**
158 * The identifier for the propertyChangeEvent when the inputValue property
159 * changes.
160 */
161 public static final String INPUT_VALUE_PROPERTY = "inputValue";
162
163 /**
164 * The identifier for the propertyChangeEvent when the message property
165 * changes.
166 */
167 public static final String MESSAGE_PROPERTY = "message";
168
169 /**
170 * The identifier for the propertyChangeEvent when the messageType property
171 * changes.
172 */
173 public static final String MESSAGE_TYPE_PROPERTY = "messageType";
174
175 /**
176 * The identifier for the propertyChangeEvent when the optionType property
177 * changes.
178 */
179 public static final String OPTION_TYPE_PROPERTY = "optionType";
180
181 /**
182 * The identifier for the propertyChangeEvent when the options property
183 * changes.
184 */
185 public static final String OPTIONS_PROPERTY = "options";
186
187 /**
188 * The identifier for the propertyChangeEvent when the selectionValues
189 * property changes.
190 */
191 public static final String SELECTION_VALUES_PROPERTY = "selectionValues";
192
193 /**
194 * The identifier for the propertyChangeEvent when the value property
195 * changes.
196 */
197 public static final String VALUE_PROPERTY = "value";
198
199 /**
200 * The identifier for the propertyChangeEvent when the wantsInput property
201 * changes.
202 */
203 public static final String WANTS_INPUT_PROPERTY = "wantsInput";
204
205 /** The value returned when the inputValue is uninitialized. */
206 public static final Object UNINITIALIZED_VALUE = "uninitializedValue";
207
208 /** The icon displayed in the dialog/internal frame. */
209 protected Icon icon;
210
211 /** The initial selected value in the input component. */
212 protected Object initialSelectionValue;
213
214 /** The object that is initially selected for options. */
215 protected Object initialValue;
216
217 /** The value the user inputs. */
218 protected Object inputValue = UNINITIALIZED_VALUE;
219
220 /** The message displayed in the dialog/internal frame. */
221 protected Object message;
222
223 /** The type of message displayed. */
224 protected int messageType = PLAIN_MESSAGE;
225
226 /**
227 * The options (usually buttons) aligned at the bottom for the user to
228 * select.
229 */
230 protected Object[] options;
231
232 /** The type of options to display. */
233 protected int optionType = DEFAULT_OPTION;
234
235 /** The input values the user can select. */
236 protected Object[] selectionValues;
237
238 /** The value returned by selecting an option. */
239 protected Object value = UNINITIALIZED_VALUE;
240
241 /** Whether the Dialog/InternalFrame needs input. */
242 protected boolean wantsInput;
243
244 /** The common frame used when no parent is provided. */
245 private static Frame privFrame = (Frame) SwingUtilities.getOwnerFrame(null);
246
247 /**
248 * Creates a new JOptionPane object using a message of "JOptionPane
249 * message", using the PLAIN_MESSAGE type and DEFAULT_OPTION.
250 */
251 public JOptionPane()
252 {
253 this("JOptionPane message", PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null);
254 }
255
256 /**
257 * Creates a new JOptionPane object using the given message using the
258 * PLAIN_MESSAGE type and DEFAULT_OPTION.
259 *
260 * @param message The message to display.
261 */
262 public JOptionPane(Object message)
263 {
264 this(message, PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null);
265 }
266
267 /**
268 * Creates a new JOptionPane object using the given message and messageType
269 * and DEFAULT_OPTION.
270 *
271 * @param message The message to display.
272 * @param messageType The type of message.
273 */
274 public JOptionPane(Object message, int messageType)
275 {
276 this(message, messageType, DEFAULT_OPTION, null, null, null);
277 }
278
279 /**
280 * Creates a new JOptionPane object using the given message, messageType and
281 * optionType.
282 *
283 * @param message The message to display.
284 * @param messageType The type of message.
285 * @param optionType The type of options.
286 */
287 public JOptionPane(Object message, int messageType, int optionType)
288 {
289 this(message, messageType, optionType, null, null, null);
290 }
291
292 /**
293 * Creates a new JOptionPane object using the given message, messageType,
294 * optionType and icon.
295 *
296 * @param message The message to display.
297 * @param messageType The type of message.
298 * @param optionType The type of options.
299 * @param icon The icon to display.
300 */
301 public JOptionPane(Object message, int messageType, int optionType, Icon icon)
302 {
303 this(message, messageType, optionType, icon, null, null);
304 }
305
306 /**
307 * Creates a new JOptionPane object using the given message, messageType,
308 * optionType, icon and options.
309 *
310 * @param message The message to display.
311 * @param messageType The type of message.
312 * @param optionType The type of options.
313 * @param icon The icon to display.
314 * @param options The options given.
315 */
316 public JOptionPane(Object message, int messageType, int optionType,
317 Icon icon, Object[] options)
318 {
319 this(message, messageType, optionType, icon, options, null);
320 }
321
322 /**
323 * Creates a new JOptionPane object using the given message, messageType,
324 * optionType, icon, options and initialValue. The initialValue will be
325 * focused initially.
326 *
327 * @param message The message to display.
328 * @param messageType The type of message.
329 * @param optionType The type of options.
330 * @param icon The icon to display.
331 * @param options The options given.
332 * @param initialValue The component to focus on initially.
333 *
334 * @throws IllegalArgumentException If the messageType or optionType are not
335 * legal values.
336 */
337 public JOptionPane(Object message, int messageType, int optionType,
338 Icon icon, Object[] options, Object initialValue)
339 {
340 this.message = message;
341 if (! validMessageType(messageType))
342 throw new IllegalArgumentException("Message Type not legal value.");
343 this.messageType = messageType;
344 if (! validOptionType(optionType))
345 throw new IllegalArgumentException("Option Type not legal value.");
346 this.optionType = optionType;
347 this.icon = icon;
348 this.options = options;
349 this.initialValue = initialValue;
350
351 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
352
353 updateUI();
354 }
355
356 /**
357 * This method creates a new JDialog that is either centered around the
358 * parent's frame or centered on the screen (if the parent is null). The
359 * JDialog will not be resizable and will be modal. Once the JDialog is
360 * disposed, the inputValue and value properties will be set by the
361 * optionPane.
362 *
363 * @param parentComponent The parent of the Dialog.
364 * @param title The title in the bar of the JDialog.
365 *
366 * @return A new JDialog based on the JOptionPane configuration.
367 */
368 public JDialog createDialog(Component parentComponent, String title)
369 {
370 Frame toUse = getFrameForComponent(parentComponent);
371 if (toUse == null)
372 toUse = getRootFrame();
373
374 JDialog dialog = new JDialog(toUse, title);
375 inputValue = UNINITIALIZED_VALUE;
376 value = UNINITIALIZED_VALUE;
377
378 dialog.getContentPane().add(this);
379 dialog.setModal(true);
380 dialog.setResizable(false);
381 dialog.pack();
382 dialog.setLocationRelativeTo(parentComponent);
383
384 addPropertyChangeListener(new ValuePropertyHandler(dialog));
385 return dialog;
386 }
387
388 /**
389 * Handles changes of the value property. Whenever this property changes,
390 * the JOptionPane dialog should be closed.
391 */
392 private static class ValuePropertyHandler
393 implements PropertyChangeListener
394 {
395 /**
396 * The dialog to close.
397 */
398 JDialog dialog;
399
400 /**
401 * Creates a new instance.
402 *
403 * @param d the dialog to be closed
404 */
405 ValuePropertyHandler(JDialog d)
406 {
407 dialog = d;
408 }
409
410 /**
411 * Receives notification when any of the properties change.
412 */
413 public void propertyChange(PropertyChangeEvent p)
414 {
415 String prop = p.getPropertyName();
416 Object val = p.getNewValue();
417 if (prop.equals(VALUE_PROPERTY) && val != null
418 && val != UNINITIALIZED_VALUE)
419 {
420 dialog.setVisible(false);
421 }
422 }
423 }
424
425 /**
426 * This method creates a new JInternalFrame that is in the JLayeredPane
427 * which contains the parentComponent given. If no suitable JLayeredPane
428 * can be found from the parentComponent given, a RuntimeException will be
429 * thrown.
430 *
431 * @param parentComponent The parent to find a JDesktopPane from.
432 * @param title The title of the JInternalFrame.
433 *
434 * @return A new JInternalFrame based on the JOptionPane configuration.
435 *
436 * @throws RuntimeException If no suitable JDesktopPane is found.
437 *
438 * @specnote The specification says that the internal frame is placed
439 * in the nearest <code>JDesktopPane</code> that is found in
440 * <code>parent</code>'s ancestors. The behaviour of the JDK
441 * is that it actually looks up the nearest
442 * <code>JLayeredPane</code> in <code>parent</code>'s ancestors.
443 * So do we.
444 */
445 public JInternalFrame createInternalFrame(Component parentComponent,
446 String title)
447 throws RuntimeException
448 {
449 // Try to find a JDesktopPane.
450 JLayeredPane toUse = getDesktopPaneForComponent(parentComponent);
451 // If we don't have a JDesktopPane, we try to find a JLayeredPane.
452 if (toUse == null)
453 toUse = JLayeredPane.getLayeredPaneAbove(parentComponent);
454 // If this still fails, we throw a RuntimeException.
455 if (toUse == null)
456 throw new RuntimeException
457 ("parentComponent does not have a valid parent");
458
459 JInternalFrame frame = new JInternalFrame(title);
460
461 inputValue = UNINITIALIZED_VALUE;
462 value = UNINITIALIZED_VALUE;
463
464 frame.setContentPane(this);
465 frame.setClosable(true);
466
467 toUse.add(frame);
468 frame.setLayer(JLayeredPane.MODAL_LAYER);
469
470 frame.pack();
471 frame.setVisible(true);
472
473 return frame;
474 }
475
476 /**
477 * Returns the object that provides accessibility features for this
478 * <code>JOptionPane</code> component.
479 *
480 * @return The accessible context (an instance of
481 * {@link AccessibleJOptionPane}).
482 */
483 public AccessibleContext getAccessibleContext()
484 {
485 if (accessibleContext == null)
486 accessibleContext = new AccessibleJOptionPane();
487 return accessibleContext;
488 }
489
490 /**
491 * This method returns the JDesktopPane for the given parentComponent or
492 * null if none can be found.
493 *
494 * @param parentComponent The component to look in.
495 *
496 * @return The JDesktopPane for the given component or null if none can be
497 * found.
498 */
499 public static JDesktopPane getDesktopPaneForComponent(Component parentComponent)
500 {
501 return (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
502 parentComponent);
503 }
504
505 /**
506 * This method returns the Frame for the given parentComponent or null if
507 * none can be found.
508 *
509 * @param parentComponent The component to look in.
510 *
511 * @return The Frame for the given component or null if none can be found.
512 */
513 public static Frame getFrameForComponent(Component parentComponent)
514 {
515 return (Frame) SwingUtilities.getAncestorOfClass(Frame.class,
516 parentComponent);
517 }
518
519 /**
520 * This method returns the icon displayed.
521 *
522 * @return The icon displayed.
523 */
524 public Icon getIcon()
525 {
526 return icon;
527 }
528
529 /**
530 * This method returns the value initially selected from the list of values
531 * the user can input.
532 *
533 * @return The initial selection value.
534 */
535 public Object getInitialSelectionValue()
536 {
537 return initialSelectionValue;
538 }
539
540 /**
541 * This method returns the value that is focused from the list of options.
542 *
543 * @return The initial value from options.
544 */
545 public Object getInitialValue()
546 {
547 return initialValue;
548 }
549
550 /**
551 * This method returns the value that the user input.
552 *
553 * @return The user's input value.
554 */
555 public Object getInputValue()
556 {
557 if (getValue().equals(new Integer(CANCEL_OPTION)))
558 setInputValue(null);
559 return inputValue;
560 }
561
562 /**
563 * This method returns the maximum characters per line. By default, this is
564 * Integer.MAX_VALUE.
565 *
566 * @return The maximum characters per line.
567 */
568 public int getMaxCharactersPerLineCount()
569 {
570 return Integer.MAX_VALUE;
571 }
572
573 /**
574 * This method returns the message displayed.
575 *
576 * @return The message displayed.
577 */
578 public Object getMessage()
579 {
580 return message;
581 }
582
583 /**
584 * This method returns the message type.
585 *
586 * @return The message type.
587 */
588 public int getMessageType()
589 {
590 return messageType;
591 }
592
593 /**
594 * This method returns the options.
595 *
596 * @return The options.
597 */
598 public Object[] getOptions()
599 {
600 return options;
601 }
602
603 /**
604 * This method returns the option type.
605 *
606 * @return The option type.
607 */
608 public int getOptionType()
609 {
610 return optionType;
611 }
612
613 /**
614 * This method returns the Frame used by JOptionPane dialog's that have no
615 * parent.
616 *
617 * @return The Frame used by dialogs that have no parent.
618 */
619 public static Frame getRootFrame()
620 {
621 return privFrame;
622 }
623
624 /**
625 * This method returns the selection values.
626 *
627 * @return The selection values.
628 */
629 public Object[] getSelectionValues()
630 {
631 return selectionValues;
632 }
633
634 /**
635 * This method returns the UI used by the JOptionPane.
636 *
637 * @return The UI used by the JOptionPane.
638 */
639 public OptionPaneUI getUI()
640 {
641 return (OptionPaneUI) ui;
642 }
643
644 /**
645 * This method returns an identifier to determine which UI class will act as
646 * the UI.
647 *
648 * @return The UI identifier.
649 */
650 public String getUIClassID()
651 {
652 return "OptionPaneUI";
653 }
654
655 /**
656 * This method returns the value that the user selected out of options.
657 *
658 * @return The value that the user selected out of options.
659 */
660 public Object getValue()
661 {
662 return value;
663 }
664
665 /**
666 * This method returns whether this JOptionPane wants input.
667 *
668 * @return Whether this JOptionPane wants input.
669 */
670 public boolean getWantsInput()
671 {
672 return wantsInput;
673 }
674
675 /**
676 * This method returns a String that describes this JOptionPane.
677 *
678 * @return A String that describes this JOptionPane.
679 */
680 protected String paramString()
681 {
682 return "JOptionPane";
683 }
684
685 /**
686 * This method requests focus for the initial value.
687 */
688 public void selectInitialValue()
689 {
690 if (ui != null)
691 ((OptionPaneUI) ui).selectInitialValue(this);
692 }
693
694 /**
695 * This method changes the icon property.
696 *
697 * @param newIcon The new icon to use.
698 */
699 public void setIcon(Icon newIcon)
700 {
701 if (icon != newIcon)
702 {
703 Icon old = icon;
704 icon = newIcon;
705 firePropertyChange(ICON_PROPERTY, old, icon);
706 }
707 }
708
709 /**
710 * This method changes the initial selection property.
711 *
712 * @param newValue The new initial selection.
713 */
714 public void setInitialSelectionValue(Object newValue)
715 {
716 if (initialSelectionValue != newValue)
717 {
718 Object old = initialSelectionValue;
719 initialSelectionValue = newValue;
720 firePropertyChange(INITIAL_SELECTION_VALUE_PROPERTY, old,
721 initialSelectionValue);
722 }
723 }
724
725 /**
726 * This method changes the initial value property.
727 *
728 * @param newValue The new initial value.
729 */
730 public void setInitialValue(Object newValue)
731 {
732 if (initialValue != newValue)
733 {
734 Object old = initialValue;
735 initialValue = newValue;
736 firePropertyChange(INITIAL_VALUE_PROPERTY, old, initialValue);
737 }
738 }
739
740 /**
741 * This method changes the inputValue property.
742 *
743 * @param newValue The new inputValue.
744 */
745 public void setInputValue(Object newValue)
746 {
747 if (inputValue != newValue)
748 {
749 Object old = inputValue;
750 inputValue = newValue;
751 firePropertyChange(INPUT_VALUE_PROPERTY, old, inputValue);
752 }
753 }
754
755 /**
756 * This method changes the message property.
757 *
758 * @param newMessage The new message.
759 */
760 public void setMessage(Object newMessage)
761 {
762 if (message != newMessage)
763 {
764 Object old = message;
765 message = newMessage;
766 firePropertyChange(MESSAGE_PROPERTY, old, message);
767 }
768 }
769
770 /**
771 * This method changes the messageType property.
772 *
773 * @param newType The new messageType.
774 *
775 * @throws IllegalArgumentException If the messageType is not valid.
776 */
777 public void setMessageType(int newType)
778 {
779 if (! validMessageType(newType))
780 throw new IllegalArgumentException("Message Type not legal value.");
781 if (newType != messageType)
782 {
783 int old = messageType;
784 messageType = newType;
785 firePropertyChange(MESSAGE_TYPE_PROPERTY, old, messageType);
786 }
787 }
788
789 /**
790 * This method changes the options property.
791 *
792 * @param newOptions The new options.
793 */
794 public void setOptions(Object[] newOptions)
795 {
796 if (options != newOptions)
797 {
798 Object[] old = options;
799 options = newOptions;
800 firePropertyChange(OPTIONS_PROPERTY, old, options);
801 }
802 }
803
804 /**
805 * This method changes the optionType property.
806 *
807 * @param newType The new optionType.
808 *
809 * @throws IllegalArgumentException If the optionType is not valid.
810 */
811 public void setOptionType(int newType)
812 {
813 if (! validOptionType(newType))
814 throw new IllegalArgumentException("Option Type not legal value.");
815 if (newType != optionType)
816 {
817 int old = optionType;
818 optionType = newType;
819 firePropertyChange(OPTION_TYPE_PROPERTY, old, optionType);
820 }
821 }
822
823 /**
824 * This method changes the Frame used for JOptionPane dialogs that have no
825 * parent.
826 *
827 * @param newRootFrame The Frame to use for dialogs that have no parent.
828 */
829 public static void setRootFrame(Frame newRootFrame)
830 {
831 privFrame = newRootFrame;
832 }
833
834 /**
835 * This method changes the selectionValues property.
836 *
837 * @param newValues The new selectionValues.
838 */
839 public void setSelectionValues(Object[] newValues)
840 {
841 if (newValues != selectionValues)
842 {
843 if (newValues != null)
844 wantsInput = true;
845 Object[] old = selectionValues;
846 selectionValues = newValues;
847 firePropertyChange(SELECTION_VALUES_PROPERTY, old, selectionValues);
848 }
849 }
850
851 /**
852 * This method sets the UI used with the JOptionPane.
853 *
854 * @param ui The UI used with the JOptionPane.
855 */
856 public void setUI(OptionPaneUI ui)
857 {
858 super.setUI(ui);
859 }
860
861 /**
862 * This method sets the value has been selected out of options.
863 *
864 * @param newValue The value that has been selected out of options.
865 */
866 public void setValue(Object newValue)
867 {
868 if (value != newValue)
869 {
870 Object old = value;
871 value = newValue;
872 firePropertyChange(VALUE_PROPERTY, old, value);
873 }
874 }
875
876 /**
877 * This method changes the wantsInput property.
878 *
879 * @param newValue Whether this JOptionPane requires input.
880 */
881 public void setWantsInput(boolean newValue)
882 {
883 if (wantsInput != newValue)
884 {
885 boolean old = wantsInput;
886 wantsInput = newValue;
887 firePropertyChange(WANTS_INPUT_PROPERTY, old, wantsInput);
888 }
889 }
890
891 /**
892 * This method shows a confirmation dialog with the title "Select an Option"
893 * and displays the given message. The parent frame will be the same as the
894 * parent frame of the given parentComponent. This method returns the
895 * option chosen by the user.
896 *
897 * @param parentComponent The parentComponent to find a frame in.
898 * @param message The message to display.
899 *
900 * @return The option that was selected.
901 */
902 public static int showConfirmDialog(Component parentComponent, Object message)
903 {
904 JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
905 JDialog dialog = pane.createDialog(parentComponent, "Select an Option");
906 dialog.show();
907
908 if (pane.getValue() instanceof Integer)
909 return ((Integer) pane.getValue()).intValue();
910 return -1;
911 }
912
913 /**
914 * This method shows a confirmation dialog with the given message,
915 * optionType and title. The frame that owns the dialog will be the same
916 * frame that holds the given parentComponent. This method returns the
917 * option that was chosen.
918 *
919 * @param parentComponent The component to find a frame in.
920 * @param message The message displayed.
921 * @param title The title of the dialog.
922 * @param optionType The optionType.
923 *
924 * @return The option that was chosen.
925 */
926 public static int showConfirmDialog(Component parentComponent,
927 Object message, String title,
928 int optionType)
929 {
930 JOptionPane pane = new JOptionPane(message, PLAIN_MESSAGE, optionType);
931 JDialog dialog = pane.createDialog(parentComponent, title);
932 dialog.show();
933
934 if (pane.getValue() instanceof Integer)
935 return ((Integer) pane.getValue()).intValue();
936 return -1;
937 }
938
939 /**
940 * This method shows a confirmation dialog with the given message, title,
941 * messageType and optionType. The frame owner will be the same frame as
942 * the one that holds the given parentComponent. This method returns the
943 * option selected by the user.
944 *
945 * @param parentComponent The component to find a frame in.
946 * @param message The message displayed.
947 * @param title The title of the dialog.
948 * @param optionType The optionType.
949 * @param messageType The messageType.
950 *
951 * @return The selected option.
952 */
953 public static int showConfirmDialog(Component parentComponent,
954 Object message, String title,
955 int optionType, int messageType)
956 {
957 JOptionPane pane = new JOptionPane(message, messageType, optionType);
958 JDialog dialog = pane.createDialog(parentComponent, title);
959 dialog.show();
960
961 if (pane.getValue() instanceof Integer)
962 return ((Integer) pane.getValue()).intValue();
963 return -1;
964 }
965
966 /**
967 * This method shows a confirmation dialog with the given message, title,
968 * optionType, messageType and icon. The frame owner will be the same as
969 * the one that holds the given parentComponent. This method returns the
970 * option selected by the user.
971 *
972 * @param parentComponent The component to find a frame in.
973 * @param message The message displayed.
974 * @param title The title of the dialog.
975 * @param optionType The optionType.
976 * @param messageType The messsageType.
977 * @param icon The icon displayed.
978 *
979 * @return The selected option.
980 */
981 public static int showConfirmDialog(Component parentComponent,
982 Object message, String title,
983 int optionType, int messageType,
984 Icon icon)
985 {
986 JOptionPane pane = new JOptionPane(message, messageType, optionType, icon);
987 JDialog dialog = pane.createDialog(parentComponent, title);
988 dialog.show();
989
990 if (pane.getValue() instanceof Integer)
991 return ((Integer) pane.getValue()).intValue();
992 return -1;
993 }
994
995 /**
996 * This method will show a QUESTION_MESSAGE input dialog with the given
997 * message. No selectionValues is set so the Look and Feel will usually
998 * give the user a TextField to fill out. The frame owner will be the same
999 * frame that holds the given parentComponent. This method will return the
1000 * value entered by the user.
1001 *
1002 * @param parentComponent The component to find a frame in.
1003 * @param message The message displayed.
1004 *
1005 * @return The value entered by the user.
1006 */
1007 public static String showInputDialog(Component parentComponent,
1008 Object message)
1009 {
1010 JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
1011 pane.setWantsInput(true);
1012 JDialog dialog = pane.createDialog(parentComponent, null);
1013 dialog.show();
1014
1015 return (String) pane.getInputValue();
1016 }
1017
1018 /**
1019 * This method will show a QUESTION_MESSAGE type input dialog with the given
1020 * message and initialSelectionValue. Since there is no selectionValues
1021 * set, the Look and Feel will usually give a TextField to fill out. The
1022 * frame owner will be the same as the one that holds the given
1023 * parentComponent. This method will return the value entered by the user.
1024 *
1025 * @param parentComponent The component to find a frame in.
1026 * @param message The message to display.
1027 * @param initialSelectionValue The initially selected value.
1028 *
1029 * @return The value the user input.
1030 */
1031 public static String showInputDialog(Component parentComponent,
1032 Object message,
1033 Object initialSelectionValue)
1034 {
1035 JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
1036 pane.setInitialSelectionValue(initialSelectionValue);
1037 pane.setWantsInput(true);
1038 JDialog dialog = pane.createDialog(parentComponent, null);
1039 dialog.show();
1040
1041 return (String) pane.getInputValue();
1042 }
1043
1044 /**
1045 * This method displays a new input dialog with the given message, title and
1046 * messageType. Since no selectionValues value is given, the Look and Feel
1047 * will usually give the user a TextField to input data to. This method
1048 * returns the value the user inputs.
1049 *
1050 * @param parentComponent The component to find a frame in.
1051 * @param message The message to display.
1052 * @param title The title of the dialog.
1053 * @param messageType The messageType.
1054 *
1055 * @return The value the user input.
1056 */
1057 public static String showInputDialog(Component parentComponent,
1058 Object message, String title,
1059 int messageType)
1060 {
1061 JOptionPane pane = new JOptionPane(message, messageType);
1062 pane.setWantsInput(true);
1063 JDialog dialog = pane.createDialog(parentComponent, title);
1064 dialog.show();
1065
1066 return (String) pane.getInputValue();
1067 }
1068
1069 /**
1070 * This method shows an input dialog with the given message, title,
1071 * messageType, icon, selectionValues, and initialSelectionValue. This
1072 * method returns the value that the user selects.
1073 *
1074 * @param parentComponent The component to find a frame in.
1075 * @param message The message displayed.
1076 * @param title The title of the dialog.
1077 * @param messageType The messageType.
1078 * @param icon The icon displayed.
1079 * @param selectionValues The list of values to select from.
1080 * @param initialSelectionValue The initially selected value.
1081 *
1082 * @return The user selected value.
1083 */
1084 public static Object showInputDialog(Component parentComponent,
1085 Object message, String title,
1086 int messageType, Icon icon,
1087 Object[] selectionValues,
1088 Object initialSelectionValue)
1089 {
1090 JOptionPane pane = new JOptionPane(message, messageType);
1091 pane.setWantsInput(true);
1092 pane.setIcon(icon);
1093 pane.setSelectionValues(selectionValues);
1094 pane.setInitialSelectionValue(initialSelectionValue);
1095 JDialog dialog = pane.createDialog(parentComponent, title);
1096 dialog.show();
1097
1098 return pane.getInputValue();
1099 }
1100
1101 /**
1102 * This method shows a QUESTION_MESSAGE type input dialog. Since no
1103 * selectionValues is set, the Look and Feel will usually give the user a
1104 * TextField to input data to. This method returns the value the user
1105 * inputs.
1106 *
1107 * @param message The message to display.
1108 *
1109 * @return The user selected value.
1110 */
1111 public static String showInputDialog(Object message)
1112 {
1113 JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
1114 pane.setWantsInput(true);
1115 JDialog dialog = pane.createDialog(null, null);
1116 dialog.show();
1117
1118 return (String) pane.getInputValue();
1119 }
1120
1121 /**
1122 * This method shows a QUESTION_MESSAGE type input dialog. Since no
1123 * selectionValues is set, the Look and Feel will usually give the user a
1124 * TextField to input data to. The input component will be initialized with
1125 * the initialSelectionValue. This method returns the value the user
1126 * inputs.
1127 *
1128 * @param message The message to display.
1129 * @param initialSelectionValue The initialSelectionValue.
1130 *
1131 * @return The user selected value.
1132 */
1133 public static String showInputDialog(Object message,
1134 Object initialSelectionValue)
1135 {
1136 JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
1137 pane.setWantsInput(true);
1138 pane.setInitialSelectionValue(initialSelectionValue);
1139 JDialog dialog = pane.createDialog(null, null);
1140 dialog.show();
1141
1142 return (String) pane.getInputValue();
1143 }
1144
1145 /**
1146 * This method shows an internal confirmation dialog with the given message.
1147 * The internal frame dialog will be placed in the first JDesktopPane
1148 * ancestor of the given parentComponent. This method will return the value
1149 * selected.
1150 *
1151 * @param parentComponent The parent to find a JDesktopPane in.
1152 * @param message The message to display.
1153 *
1154 * @return The value selected.
1155 */
1156 public static int showInternalConfirmDialog(Component parentComponent,
1157 Object message)
1158 {
1159 JOptionPane pane = new JOptionPane(message);
1160 JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
1161
1162 startModal(frame);
1163
1164 if (pane.getValue() instanceof Integer)
1165 return ((Integer) pane.getValue()).intValue();
1166 return -1;
1167 }
1168
1169 /**
1170 * This method shows an internal confirmation dialog with the given message,
1171 * optionType and title. The internal frame dialog will be placed in the
1172 * first JDesktopPane ancestor of the given parentComponent. This method
1173 * will return the selected value.
1174 *
1175 * @param parentComponent The parent to find a JDesktopPane in.
1176 * @param message The message to display.
1177 * @param title The title to display.
1178 * @param optionType The option type.
1179 *
1180 * @return The selected value.
1181 */
1182 public static int showInternalConfirmDialog(Component parentComponent,
1183 Object message, String title,
1184 int optionType)
1185 {
1186 JOptionPane pane = new JOptionPane(message, PLAIN_MESSAGE, optionType);
1187 JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
1188
1189 startModal(frame);
1190
1191 if (pane.getValue() instanceof Integer)
1192 return ((Integer) pane.getValue()).intValue();
1193 return -1;
1194 }
1195
1196 /**
1197 * This method shows an internal confirmation dialog with the given message,
1198 * title, optionTypes and icon for the given message type. The internal
1199 * confirmation dialog will be placed in the first instance of
1200 * JDesktopPane ancestor of the given parentComponent.
1201 *
1202 * @param parentComponent The component to find a JDesktopPane in.
1203 * @param message The message to display.
1204 * @param title The title of the dialog.
1205 * @param optionType The option type.
1206 * @param messageType The message type.
1207 *
1208 * @return The selected value.
1209 */
1210 public static int showInternalConfirmDialog(Component parentComponent,
1211 Object message, String title,
1212 int optionType, int messageType)
1213 {
1214 JOptionPane pane = new JOptionPane(message, messageType, optionType);
1215 JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
1216
1217 startModal(frame);
1218
1219 if (pane.getValue() instanceof Integer)
1220 return ((Integer) pane.getValue()).intValue();
1221 return -1;
1222 }
1223
1224 /**
1225 * This method shows an internal confirmation dialog with the given message,
1226 * title, option type, message type, and icon. The internal frame dialog
1227 * will be placed in the first JDesktopPane ancestor that is found in the
1228 * given parentComponent. This method returns the selected value.
1229 *
1230 * @param parentComponent The parent to find a JDesktopPane in.
1231 * @param message The message to display.
1232 * @param title The title to display.
1233 * @param optionType The option type.
1234 * @param messageType The message type.
1235 * @param icon The icon to display.
1236 *
1237 * @return The selected value.
1238 */
1239 public static int showInternalConfirmDialog(Component parentComponent,
1240 Object message, String title,
1241 int optionType, int messageType,
1242 Icon icon)
1243 {
1244 JOptionPane pane = new JOptionPane(message, messageType, optionType, icon);
1245 JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
1246
1247 startModal(frame);
1248
1249 if (pane.getValue() instanceof Integer)
1250 return ((Integer) pane.getValue()).intValue();
1251 return -1;
1252 }
1253
1254 /**
1255 * This method shows an internal input dialog with the given message. The
1256 * internal frame dialog will be placed in the first JDesktopPane ancestor
1257 * of the given parent component. This method returns the value input by
1258 * the user.
1259 *
1260 * @param parentComponent The parent to find a JDesktopPane in.
1261 * @param message The message to display.
1262 *
1263 * @return The user selected value.
1264 */
1265 public static String showInternalInputDialog(Component parentComponent,
1266 Object message)
1267 {
1268 JOptionPane pane = new JOptionPane(message);
1269 pane.setWantsInput(true);
1270 JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
1271
1272 startModal(frame);
1273
1274 return (String) pane.getInputValue();
1275 }
1276
1277 /**
1278 * This method shows an internal input dialog with the given message, title
1279 * and message type. The internal input dialog will be placed in the first
1280 * JDesktopPane ancestor found in the given parent component. This method
1281 * will return the input value given by the user.
1282 *
1283 * @param parentComponent The component to find a JDesktopPane in.
1284 * @param message The message to display.
1285 * @param title The title to display.
1286 * @param messageType The message type.
1287 *
1288 * @return The user input value.
1289 */
1290 public static String showInternalInputDialog(Component parentComponent,
1291 Object message, String title,
1292 int messageType)
1293 {
1294 JOptionPane pane = new JOptionPane(message, messageType);
1295 pane.setWantsInput(true);
1296 JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
1297
1298 startModal(frame);
1299
1300 return (String) pane.getInputValue();
1301 }
1302
1303 /**
1304 * This method shows an internal input dialog with the given message, title
1305 * message type, icon, selection value list and initial selection value.
1306 * The internal frame dialog will be placed in the first JDesktopPane
1307 * ancestor found in the given parent component. This method returns the
1308 * input value from the user.
1309 *
1310 * @param parentComponent The parent to find a JDesktopPane in.
1311 * @param message The message to display.
1312 * @param title The title to display.
1313 * @param messageType The message type.
1314 * @param icon The icon to display.
1315 * @param selectionValues The selection value list.
1316 * @param initialSelectionValue The initial selection value.
1317 *
1318 * @return The user input value.
1319 */
1320 public static Object showInternalInputDialog(Component parentComponent,
1321 Object message, String title,
1322 int messageType, Icon icon,
1323 Object[] selectionValues,
1324 Object initialSelectionValue)
1325 {
1326 JOptionPane pane = new JOptionPane(message, messageType);
1327 pane.setWantsInput(true);
1328 pane.setIcon(icon);
1329 pane.setSelectionValues(selectionValues);
1330 pane.setInitialSelectionValue(initialSelectionValue);
1331 JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
1332
1333 startModal(frame);
1334
1335 return pane.getInputValue();
1336 }
1337
1338 /**
1339 * This method shows an internal message dialog with the given message. The
1340 * internal frame dialog will be placed in the first JDesktopPane ancestor
1341 * found in the given parent component.
1342 *
1343 * @param parentComponent The component to find a JDesktopPane in.
1344 * @param message The message to display.
1345 */
1346 public static void showInternalMessageDialog(Component parentComponent,
1347 Object message)
1348 {
1349 JOptionPane pane = new JOptionPane(message);
1350 JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
1351
1352 startModal(frame);
1353 }
1354
1355 /**
1356 * This method shows an internal message dialog with the given message,
1357 * title and message type. The internal message dialog is placed in the
1358 * first JDesktopPane ancestor found in the given parent component.
1359 *
1360 * @param parentComponent The parent component to find a JDesktopPane in.
1361 * @param message The message to display.
1362 * @param title The title to display.
1363 * @param messageType The message type.
1364 */
1365 public static void showInternalMessageDialog(Component parentComponent,
1366 Object message, String title,
1367 int messageType)
1368 {
1369 JOptionPane pane = new JOptionPane(message, messageType);
1370 JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
1371
1372 startModal(frame);
1373 }
1374
1375 /**
1376 * This method shows an internal message dialog with the given message,
1377 * title, message type and icon. The internal message dialog is placed in
1378 * the first JDesktopPane ancestor found in the given parent component.
1379 *
1380 * @param parentComponent The component to find a JDesktopPane in.
1381 * @param message The message to display.
1382 * @param title The title to display.
1383 * @param messageType The message type.
1384 * @param icon The icon to display.
1385 */
1386 public static void showInternalMessageDialog(Component parentComponent,
1387 Object message, String title,
1388 int messageType, Icon icon)
1389 {
1390 JOptionPane pane = new JOptionPane(message, messageType);
1391 pane.setIcon(icon);
1392 JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
1393
1394 startModal(frame);
1395 }
1396
1397 /**
1398 * This method displays an internal option dialog with the given message,
1399 * title, option type, message type, icon, option list, and initial option
1400 * value. The internal option dialog is placed in the first JDesktopPane
1401 * ancestor found in the parent component. This method returns the option
1402 * selected.
1403 *
1404 * @param parentComponent The parent to find a JDesktopPane in.
1405 * @param message The message displayed.
1406 * @param title The title displayed.
1407 * @param optionType The option type.
1408 * @param messageType The message type.
1409 * @param icon The icon to display.
1410 * @param options The array of options.
1411 * @param initialValue The initial value selected.
1412 *
1413 * @return The option that was selected.
1414 */
1415 public static int showInternalOptionDialog(Component parentComponent,
1416 Object message, String title,
1417 int optionType, int messageType,
1418 Icon icon, Object[] options,
1419 Object initialValue)
1420 {
1421 JOptionPane pane = new JOptionPane(message, messageType, optionType, icon,
1422 options, initialValue);
1423
1424 JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
1425
1426 startModal(frame);
1427
1428 if (pane.getValue() instanceof Integer)
1429 return ((Integer) pane.getValue()).intValue();
1430 return -1;
1431 }
1432
1433 /**
1434 * This method shows an INFORMATION_MESSAGE type message dialog.
1435 *
1436 * @param parentComponent The component to find a frame in.
1437 * @param message The message displayed.
1438 */
1439 public static void showMessageDialog(Component parentComponent,
1440 Object message)
1441 {
1442 JOptionPane pane = new JOptionPane(message, INFORMATION_MESSAGE);
1443 JDialog dialog = pane.createDialog(parentComponent, null);
1444 dialog.show();
1445 }
1446
1447 /**
1448 * This method shows a message dialog with the given message, title and
1449 * messageType.
1450 *
1451 * @param parentComponent The component to find a frame in.
1452 * @param message The message displayed.
1453 * @param title The title of the dialog.
1454 * @param messageType The messageType.
1455 */
1456 public static void showMessageDialog(Component parentComponent,
1457 Object message, String title,
1458 int messageType)
1459 {
1460 JOptionPane pane = new JOptionPane(message, messageType);
1461 JDialog dialog = pane.createDialog(parentComponent, title);
1462 dialog.show();
1463 }
1464
1465 /**
1466 * This method shows a message dialog with the given message, title,
1467 * messageType and icon.
1468 *
1469 * @param parentComponent The component to find a frame in.
1470 * @param message The message displayed.
1471 * @param title The title of the dialog.
1472 * @param messageType The messageType.
1473 * @param icon The icon displayed.
1474 */
1475 public static void showMessageDialog(Component parentComponent,
1476 Object message, String title,
1477 int messageType, Icon icon)
1478 {
1479 JOptionPane pane = new JOptionPane(message, messageType);
1480 pane.setIcon(icon);
1481 JDialog dialog = pane.createDialog(parentComponent, title);
1482 dialog.show();
1483 }
1484
1485 /**
1486 * This method shows an option dialog with the given message, title,
1487 * optionType, messageType, icon, options and initialValue. This method
1488 * returns the option that was selected.
1489 *
1490 * @param parentComponent The component to find a frame in.
1491 * @param message The message displayed.
1492 * @param title The title of the dialog.
1493 * @param optionType The optionType.
1494 * @param messageType The messageType.
1495 * @param icon The icon displayed.
1496 * @param options The options to choose from.
1497 * @param initialValue The initial value.
1498 *
1499 * @return The selected option.
1500 */
1501 public static int showOptionDialog(Component parentComponent,
1502 Object message, String title,
1503 int optionType, int messageType,
1504 Icon icon, Object[] options,
1505 Object initialValue)
1506 {
1507 JOptionPane pane = new JOptionPane(message, messageType, optionType, icon,
1508 options, initialValue);
1509
1510 JDialog dialog = pane.createDialog(parentComponent, title);
1511 dialog.show();
1512
1513 if (pane.getValue() instanceof Integer)
1514 return ((Integer) pane.getValue()).intValue();
1515 return -1;
1516 }
1517
1518 /**
1519 * This method resets the UI to the Look and Feel default.
1520 */
1521 public void updateUI()
1522 {
1523 setUI((OptionPaneUI) UIManager.getUI(this));
1524 }
1525
1526 /**
1527 * This method returns true if the key is a valid messageType.
1528 *
1529 * @param key The key to check.
1530 *
1531 * @return True if key is valid.
1532 */
1533 private boolean validMessageType(int key)
1534 {
1535 switch (key)
1536 {
1537 case ERROR_MESSAGE:
1538 case INFORMATION_MESSAGE:
1539 case PLAIN_MESSAGE:
1540 case QUESTION_MESSAGE:
1541 case WARNING_MESSAGE:
1542 return true;
1543 }
1544 return false;
1545 }
1546
1547 /**
1548 * This method returns true if the key is a valid optionType.
1549 *
1550 * @param key The key to check.
1551 *
1552 * @return True if key is valid.
1553 */
1554 private boolean validOptionType(int key)
1555 {
1556 switch (key)
1557 {
1558 case DEFAULT_OPTION:
1559 case OK_CANCEL_OPTION:
1560 case YES_NO_CANCEL_OPTION:
1561 case YES_NO_OPTION:
1562 return true;
1563 }
1564 return false;
1565 }
1566
1567 /**
1568 * This helper method makes the JInternalFrame wait until it is notified by
1569 * an InternalFrameClosing event. This method also adds the given
1570 * JOptionPane to the JInternalFrame and sizes it according to the
1571 * JInternalFrame's preferred size.
1572 *
1573 * @param f The JInternalFrame to make modal.
1574 */
1575 private static void startModal(JInternalFrame f)
1576 {
1577 // We need to add an additional glasspane-like component directly
1578 // below the frame, which intercepts all mouse events that are not
1579 // directed at the frame itself.
1580 JPanel modalInterceptor = new JPanel();
1581 modalInterceptor.setOpaque(false);
1582 JLayeredPane lp = JLayeredPane.getLayeredPaneAbove(f);
1583 lp.setLayer(modalInterceptor, JLayeredPane.MODAL_LAYER.intValue());
1584 modalInterceptor.setBounds(0, 0, lp.getWidth(), lp.getHeight());
1585 modalInterceptor.addMouseListener(new MouseAdapter(){});
1586 modalInterceptor.addMouseMotionListener(new MouseMotionAdapter(){});
1587 lp.add(modalInterceptor);
1588 f.toFront();
1589
1590 // We need to explicitly dispatch events when we are blocking the event
1591 // dispatch thread.
1592 EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
1593 try
1594 {
1595 while (! f.isClosed())
1596 {
1597 if (EventQueue.isDispatchThread())
1598 {
1599 // The getNextEventMethod() issues wait() when no
1600 // event is available, so we don't need do explicitly wait().
1601 AWTEvent ev = queue.getNextEvent();
1602 // This mimics EventQueue.dispatchEvent(). We can't use
1603 // EventQueue.dispatchEvent() directly, because it is
1604 // protected, unfortunately.
1605 if (ev instanceof ActiveEvent)
1606 ((ActiveEvent) ev).dispatch();
1607 else if (ev.getSource() instanceof Component)
1608 ((Component) ev.getSource()).dispatchEvent(ev);
1609 else if (ev.getSource() instanceof MenuComponent)
1610 ((MenuComponent) ev.getSource()).dispatchEvent(ev);
1611 // Other events are ignored as per spec in
1612 // EventQueue.dispatchEvent
1613 }
1614 else
1615 {
1616 // Give other threads a chance to become active.
1617 Thread.yield();
1618 }
1619 }
1620 }
1621 catch (InterruptedException ex)
1622 {
1623 // If we get interrupted, then leave the modal state.
1624 }
1625 finally
1626 {
1627 // Clean up the modal interceptor.
1628 lp.remove(modalInterceptor);
1629
1630 // Remove the internal frame from its parent, so it is no longer
1631 // lurking around and clogging memory.
1632 Container parent = f.getParent();
1633 if (parent != null)
1634 parent.remove(f);
1635 }
1636 }
1637 }