Source for javax.swing.JOptionPane

   1: /* JOptionPane.java
   2:    Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing;
  40: 
  41: import java.awt.AWTEvent;
  42: import java.awt.ActiveEvent;
  43: import java.awt.Component;
  44: import java.awt.Container;
  45: import java.awt.EventQueue;
  46: import java.awt.Frame;
  47: import java.awt.MenuComponent;
  48: import java.awt.Toolkit;
  49: import java.awt.event.MouseAdapter;
  50: import java.awt.event.MouseMotionAdapter;
  51: import java.beans.PropertyChangeEvent;
  52: import java.beans.PropertyChangeListener;
  53: 
  54: import javax.accessibility.Accessible;
  55: import javax.accessibility.AccessibleContext;
  56: import javax.accessibility.AccessibleRole;
  57: import javax.swing.plaf.OptionPaneUI;
  58: 
  59: /**
  60:  * This class creates different types of JDialogs and JInternalFrames that can
  61:  * ask users for input or pass on information. JOptionPane can be used by
  62:  * calling one of the show static methods or  by creating an instance of
  63:  * JOptionPane and calling createDialog or createInternalFrame.
  64:  */
  65: public class JOptionPane extends JComponent implements Accessible
  66: {
  67:   /**
  68:    * Provides the accessibility features for the <code>JOptionPane</code>
  69:    * component.
  70:    */
  71:   protected class AccessibleJOptionPane extends JComponent.AccessibleJComponent
  72:   {
  73:     private static final long serialVersionUID = 686071432213084821L;
  74: 
  75:     /**
  76:      * Creates a new <code>AccessibleJOptionPane</code> instance.
  77:      */
  78:     protected AccessibleJOptionPane()
  79:     {
  80:       // Nothing to do here.
  81:     }
  82: 
  83:     /**
  84:      * Returns the accessible role of this object, which is always
  85:      * {@link AccessibleRole#OPTION_PANE}.
  86:      *
  87:      * @return the accessible role of this object
  88:      */
  89:     public AccessibleRole getAccessibleRole()
  90:     {
  91:       return AccessibleRole.OPTION_PANE;
  92:     }
  93:   }
  94: 
  95:   private static final long serialVersionUID = 5231143276678566796L;
  96: 
  97:   /** The value returned when cancel option is selected. */
  98:   public static final int CANCEL_OPTION = 2;
  99: 
 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: }