Source for java.awt.Dialog

   1: /* Dialog.java -- An AWT dialog box
   2:  Copyright (C) 1999, 2000, 2001, 2002, 2005, 2006
   3:  Free Software Foundation, Inc.
   4: 
   5:  This file is part of GNU Classpath.
   6: 
   7:  GNU Classpath is free software; you can redistribute it and/or modify
   8:  it under the terms of the GNU General Public License as published by
   9:  the Free Software Foundation; either version 2, or (at your option)
  10:  any later version.
  11: 
  12:  GNU Classpath is distributed in the hope that it will be useful, but
  13:  WITHOUT ANY WARRANTY; without even the implied warranty of
  14:  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15:  General Public License for more details.
  16: 
  17:  You should have received a copy of the GNU General Public License
  18:  along with GNU Classpath; see the file COPYING.  If not, write to the
  19:  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20:  02110-1301 USA.
  21: 
  22:  Linking this library statically or dynamically with other modules is
  23:  making a combined work based on this library.  Thus, the terms and
  24:  conditions of the GNU General Public License cover the whole
  25:  combination.
  26: 
  27:  As a special exception, the copyright holders of this library give you
  28:  permission to link this library with independent modules to produce an
  29:  executable, regardless of the license terms of these independent
  30:  modules, and to copy and distribute the resulting executable under
  31:  terms of your choice, provided that you also meet, for each linked
  32:  independent module, the terms and conditions of the license of that
  33:  module.  An independent module is a module which is not derived from
  34:  or based on this library.  If you modify this library, you may extend
  35:  this exception to your version of the library, but you are not
  36:  obligated to do so.  If you do not wish to do so, delete this
  37:  exception statement from your version. */
  38: 
  39: 
  40: package java.awt;
  41: 
  42: import java.awt.peer.DialogPeer;
  43: 
  44: import javax.accessibility.AccessibleContext;
  45: import javax.accessibility.AccessibleRole;
  46: import javax.accessibility.AccessibleState;
  47: import javax.accessibility.AccessibleStateSet;
  48: 
  49: /**
  50:  * <code>Dialog</code> provides a top-level window normally used to receive
  51:  * user input in applications.
  52:  * <p>
  53:  * A dialog always has another top-level window as owner and is only visible
  54:  * if this owner is visible to the user. The default layout of dialogs is the
  55:  * <code>BorderLayout</code>. Dialogs can be modal (blocks user input to other
  56:  * components) or non-modal (user input in other components are allowed).
  57:  * </p>
  58:  *
  59:  * @author Aaron M. Renn (arenn@urbanophile.com)
  60:  * @author Tom Tromey (tromey@redhat.com)
  61:  */
  62: public class Dialog extends Window
  63: {
  64:   public enum ModalExclusionType
  65:   {
  66:     APPLICATION_EXCLUDE,
  67:     NO_EXCLUDE,
  68:     TOOLKIT_EXCLUDE
  69:   }
  70: 
  71:   public enum ModalityType
  72:   {
  73:     APPLICATION_MODAL,
  74:     DOCUMENT_MODAL,
  75:     MODELESS,
  76:     TOOLKIT_MODAL
  77:   }
  78: 
  79:   // Serialization constant
  80:   private static final long serialVersionUID = 5920926903803293709L;
  81: 
  82:   /**
  83:    * @serial Indicates whether or not this dialog box is modal.
  84:    */
  85:   private boolean modal;
  86: 
  87:   /**
  88:    * @serial Indicates whether or not this dialog box is resizable.
  89:    */
  90:   private boolean resizable = true;
  91: 
  92:   /**
  93:    * @serial The title string for this dialog box, which can be
  94:    *         <code>null</code>.
  95:    */
  96:   private String title;
  97: 
  98:   /**
  99:    * This field indicates whether the dialog is undecorated or not.
 100:    */
 101:   private boolean undecorated = false;
 102: 
 103:   /**
 104:    * Indicates that we are blocked for modality in show
 105:    */
 106:   private boolean blocked = false;
 107: 
 108:   /**
 109:    * Secondary EventQueue to handle AWT events while we are blocked for
 110:    * modality in show.
 111:    */
 112:   private EventQueue eq2 = null;
 113: 
 114:   /**
 115:    * The number used to generate the name returned by getName.
 116:    */
 117:   private static transient long next_dialog_number;
 118: 
 119:   /**
 120:    * Initializes a new instance of <code>Dialog</code> with the specified
 121:    * parent, that is resizable and not modal, and which has no title.
 122:    *
 123:    * @param parent The parent frame of this dialog box.
 124:    * @exception IllegalArgumentException If the owner's GraphicsConfiguration
 125:    * is not from a screen device, or if owner is null. This exception is
 126:    * always thrown when GraphicsEnvironment.isHeadless() returns true.
 127:    */
 128:   public Dialog(Frame parent)
 129:   {
 130:     this(parent, "", false);
 131:   }
 132: 
 133:   /**
 134:    * Initializes a new instance of <code>Dialog</code> with the specified
 135:    * parent and modality, that is resizable and which has no title.
 136:    *
 137:    * @param parent The parent frame of this dialog box.
 138:    * @param modal <code>true</code> if this dialog box is modal,
 139:    * <code>false</code> otherwise.
 140:    *
 141:    * @exception IllegalArgumentException If the owner's GraphicsConfiguration
 142:    * is not from a screen device, or if owner is null. This exception is
 143:    * always thrown when GraphicsEnvironment.isHeadless() returns true.
 144:    */
 145:   public Dialog(Frame parent, boolean modal)
 146:   {
 147:     this(parent, "", modal);
 148:   }
 149: 
 150:   /**
 151:    * Initializes a new instance of <code>Dialog</code> with the specified
 152:    * parent, that is resizable and not modal, and which has the specified
 153:    * title.
 154:    *
 155:    * @param parent The parent frame of this dialog box.
 156:    * @param title The title string for this dialog box.
 157:    *
 158:    * @exception IllegalArgumentException If the owner's GraphicsConfiguration
 159:    * is not from a screen device, or if owner is null. This exceptionnis
 160:    * always thrown when GraphicsEnvironment.isHeadless() returns true.
 161:    */
 162:   public Dialog(Frame parent, String title)
 163:   {
 164:     this(parent, title, false);
 165:   }
 166: 
 167:   /**
 168:    * Initializes a new instance of <code>Dialog</code> with the specified,
 169:    * parent, title, and modality, that is resizable.
 170:    *
 171:    * @param parent The parent frame of this dialog box.
 172:    * @param title The title string for this dialog box.
 173:    * @param modal <code>true</code> if this dialog box is modal,
 174:    * <code>false</code> otherwise.
 175:    *
 176:    * @exception IllegalArgumentException If owner is null or
 177:    *              GraphicsEnvironment.isHeadless() returns true.
 178:    */
 179:   public Dialog(Frame parent, String title, boolean modal)
 180:   {
 181:     this(parent, title, modal, parent.getGraphicsConfiguration());
 182:   }
 183: 
 184:   /**
 185:    * Initializes a new instance of <code>Dialog</code> with the specified,
 186:    * parent, title, modality and <code>GraphicsConfiguration</code>, that is
 187:    * resizable.
 188:    *
 189:    * @param parent The parent frame of this dialog box.
 190:    * @param title The title string for this dialog box.
 191:    * @param modal <code>true</code> if this dialog box is modal,
 192:    * <code>false</code> otherwise.
 193:    * @param gc The <code>GraphicsConfiguration</code> object to use. If
 194:    * <code>null</code> the <code>GraphicsConfiguration</code> of the target
 195:    * frame is used.
 196:    *
 197:    * @exception IllegalArgumentException If owner is null, the
 198:    *              GraphicsConfiguration is not a screen device or
 199:    *              GraphicsEnvironment.isHeadless() returns true.
 200:    * @since 1.4
 201:    */
 202:   public Dialog(Frame parent, String title, boolean modal,
 203:                 GraphicsConfiguration gc)
 204:   {
 205:     super(parent, (gc == null) ? parent.getGraphicsConfiguration() : gc);
 206: 
 207:     // A null title is equivalent to an empty title
 208:     this.title = (title != null) ? title : "";
 209:     this.modal = modal;
 210:     visible = false;
 211: 
 212:     setLayout(new BorderLayout());
 213:     setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
 214:   }
 215: 
 216:   /**
 217:    * Initializes a new instance of <code>Dialog</code> with the specified,
 218:    * parent, that is resizable.
 219:    *
 220:    * @param owner The parent frame of this dialog box.
 221:    *
 222:    * @exception IllegalArgumentException If parent is null. This exception is
 223:    * always thrown when GraphicsEnvironment.isHeadless() returns true.
 224:    *
 225:    * @since 1.2
 226:    */
 227:   public Dialog(Dialog owner)
 228:   {
 229:     this(owner, "", false, owner.getGraphicsConfiguration());
 230:   }
 231: 
 232:   /**
 233:    * Initializes a new instance of <code>Dialog</code> with the specified,
 234:    * parent and title, that is resizable.
 235:    *
 236:    * @param owner The parent frame of this dialog box.
 237:    * @param title The title string for this dialog box.
 238:    *
 239:    * @exception IllegalArgumentException If parent is null. This exception is
 240:    *              always thrown when GraphicsEnvironment.isHeadless() returns
 241:    *              true.
 242:    * @since 1.2
 243:    */
 244:   public Dialog(Dialog owner, String title)
 245:   {
 246:     this(owner, title, false, owner.getGraphicsConfiguration());
 247:   }
 248: 
 249:   /**
 250:    * Initializes a new instance of <code>Dialog</code> with the specified,
 251:    * parent, title and modality, that is resizable.
 252:    *
 253:    * @param owner The parent frame of this dialog box.
 254:    * @param title The title string for this dialog box.
 255:    * @param modal <code>true</code> if this dialog box is modal,
 256:    * <code>false</code> otherwise.
 257:    *
 258:    * @exception IllegalArgumentException If parent is null. This exception is
 259:    * always thrown when GraphicsEnvironment.isHeadless() returns true.
 260:    * @since 1.2
 261:    */
 262:   public Dialog(Dialog owner, String title, boolean modal)
 263:   {
 264:     this(owner, title, modal, owner.getGraphicsConfiguration());
 265:   }
 266: 
 267:   /**
 268:    * Initializes a new instance of <code>Dialog</code> with the specified,
 269:    * parent, title, modality and <code>GraphicsConfiguration</code>, that is
 270:    * resizable.
 271:    *
 272:    * @param parent The parent frame of this dialog box.
 273:    * @param title The title string for this dialog box.
 274:    * @param modal <code>true</code> if this dialog box is modal,
 275:    * <code>false</code> otherwise.
 276:    * @param gc The <code>GraphicsConfiguration</code> object to use. If
 277:    * <code>null</code> the <code>GraphicsConfiguration</code> of the target
 278:    * frame is used.
 279:    *
 280:    * @exception IllegalArgumentException If parent is null, the
 281:    * GraphicsConfiguration is not a screen device or
 282:    * GraphicsEnvironment.isHeadless() returns true.
 283:    *
 284:    * @since 1.4
 285:    */
 286:   public Dialog(Dialog parent, String title, boolean modal,
 287:                 GraphicsConfiguration gc)
 288:   {
 289:     super(parent, (gc == null) ? parent.getGraphicsConfiguration() : gc);
 290: 
 291:     // A null title is equivalent to an empty title
 292:     this.title = (title != null) ? title : "";
 293:     this.modal = modal;
 294:     visible = false;
 295: 
 296:     setLayout(new BorderLayout());
 297:     setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
 298:   }
 299: 
 300:   /**
 301:    * Returns the title of this dialog box.
 302:    *
 303:    * @return The title of this dialog box.
 304:    */
 305:   public String getTitle()
 306:   {
 307:     return title;
 308:   }
 309: 
 310:   /**
 311:    * Sets the title of this dialog box to the specified string.
 312:    *
 313:    * @param title the new title. If <code>null</code> an empty
 314:    * title will be set.
 315:    */
 316:   public synchronized void setTitle(String title)
 317:   {
 318:     // A null title is equivalent to an empty title
 319:     this.title = (title != null) ? title : "";
 320: 
 321:     if (peer != null)
 322:       {
 323:         DialogPeer d = (DialogPeer) peer;
 324:         d.setTitle(title);
 325:       }
 326:   }
 327: 
 328:   /**
 329:    * Tests whether or not this dialog box is modal.
 330:    *
 331:    * @return <code>true</code> if this dialog box is modal, <code>false</code>
 332:    * otherwise.
 333:    */
 334:   public boolean isModal()
 335:   {
 336:     return modal;
 337:   }
 338: 
 339:   /**
 340:    * Changes the modality of this dialog box. This can only be done before the
 341:    * peer is created.
 342:    *
 343:    * @param modal <code>true</code> to make this dialog box modal,
 344:    * <code>false</code> to make it non-modal.
 345:    */
 346:   public void setModal(boolean modal)
 347:   {
 348:     this.modal = modal;
 349:   }
 350: 
 351:   /**
 352:    * Tests whether or not this dialog box is resizable.
 353:    *
 354:    * @return <code>true</code> if this dialog is resizable,
 355:    * <code>false</code> otherwise.
 356:    */
 357:   public boolean isResizable()
 358:   {
 359:     return resizable;
 360:   }
 361: 
 362:   /**
 363:    * Changes the resizability of this dialog box.
 364:    *
 365:    * @param resizable <code>true</code> to make this dialog resizable,
 366:    * <code>false</code> to make it non-resizable.
 367:    */
 368:   public synchronized void setResizable(boolean resizable)
 369:   {
 370:     this.resizable = resizable;
 371:     if (peer != null)
 372:       {
 373:         DialogPeer d = (DialogPeer) peer;
 374:         d.setResizable(resizable);
 375:       }
 376:   }
 377: 
 378:   /**
 379:    * Creates this object's native peer.
 380:    */
 381:   public synchronized void addNotify()
 382:   {
 383:     if (peer == null)
 384:       peer = getToolkit().createDialog(this);
 385:     super.addNotify();
 386:   }
 387: 
 388:   /**
 389:    * Makes this dialog visible and brings it to the front. If the dialog is
 390:    * modal and is not already visible, this call will not return until the
 391:    * dialog is hidden by someone calling hide or dispose. If this is the event
 392:    * dispatching thread we must ensure that another event thread runs while the
 393:    * one which invoked this method is blocked.
 394:    *
 395:    * @deprecated Use {@link Component#setVisible(boolean)} instead.
 396:    */
 397:   public synchronized void show()
 398:   {
 399:     super.show();
 400: 
 401:     if (isModal())
 402:       {
 403:         // If already shown (and blocked) just return
 404:         if (blocked)
 405:           return;
 406: 
 407:         /*
 408:          * If show is called in the dispatch thread for a modal dialog it will
 409:          * block so we must run another thread so the events keep being
 410:          * dispatched.
 411:          */
 412:         if (EventQueue.isDispatchThread())
 413:           {
 414:             EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
 415:             eq2 = new EventQueue();
 416:             eq.push(eq2);
 417:           }
 418: 
 419:         try
 420:           {
 421:             blocked = true;
 422:             wait();
 423:             blocked = false;
 424:           }
 425:         catch (InterruptedException e)
 426:           {
 427:             blocked = false;
 428:           }
 429: 
 430:         if (eq2 != null)
 431:           {
 432:             eq2.pop();
 433:             eq2 = null;
 434:           }
 435:       }
 436:   }
 437: 
 438:   /**
 439:    * Hides the Dialog and then causes show() to return if it is currently
 440:    * blocked.
 441:    *
 442:    * @deprecated Use {@link Component#setVisible(boolean)} instead.
 443:    */
 444:   public synchronized void hide()
 445:   {
 446:     if (blocked)
 447:       {
 448:         notifyAll();
 449:       }
 450: 
 451:     super.hide();
 452:   }
 453: 
 454:   /**
 455:    * Disposes the Dialog and then causes show() to return if it is currently
 456:    * blocked.
 457:    */
 458:   public synchronized void dispose()
 459:   {
 460:     if (blocked)
 461:       {
 462:         notifyAll();
 463:       }
 464: 
 465:     super.dispose();
 466:   }
 467: 
 468:   /**
 469:    * Returns a debugging string for this component.
 470:    *
 471:    * @return A debugging string for this component.
 472:    */
 473:   protected String paramString()
 474:   {
 475:     return "title+" + title + ",modal=" + modal + ",resizable=" + resizable
 476:             + "," + super.paramString();
 477:   }
 478: 
 479:   /**
 480:    * Returns whether this frame is undecorated or not.
 481:    *
 482:    * @return <code>true</code> if this dialog is undecorated,
 483:    * <code>false</code> otherwise.
 484:    *
 485:    * @since 1.4
 486:    */
 487:   public boolean isUndecorated()
 488:   {
 489:     return undecorated;
 490:   }
 491: 
 492:   /**
 493:    * Disables or enables decorations for this frame. This method can only be
 494:    * called while the frame is not displayable.
 495:    *
 496:    * @param undecorated <code>true</code> to disable dialog decorations,
 497:    * <code>false</code> otherwise.
 498:    *
 499:    * @exception IllegalComponentStateException If this frame is displayable.
 500:    * @since 1.4
 501:    */
 502:   public void setUndecorated(boolean undecorated)
 503:   {
 504:     if (isDisplayable())
 505:       throw new IllegalComponentStateException();
 506: 
 507:     this.undecorated = undecorated;
 508:   }
 509: 
 510:   /**
 511:    * Accessibility support for <code>Dialog</code>.
 512:    */
 513:   protected class AccessibleAWTDialog
 514:       extends AccessibleAWTWindow
 515:   {
 516:     private static final long serialVersionUID = 4837230331833941201L;
 517: 
 518:     /**
 519:      * Gets the role of this object.
 520:      * @return AccessibleRole.DIALOG
 521:      */
 522:     public AccessibleRole getAccessibleRole()
 523:     {
 524:       return AccessibleRole.DIALOG;
 525:     }
 526: 
 527:     /**
 528:      * Gets the state set of this object.
 529:      * @return The current state of this dialog.
 530:      */
 531:     public AccessibleStateSet getAccessibleStateSet()
 532:     {
 533:       AccessibleStateSet states = super.getAccessibleStateSet();
 534:       if (isResizable())
 535:         states.add(AccessibleState.RESIZABLE);
 536:       if (isModal())
 537:         states.add(AccessibleState.MODAL);
 538:       return states;
 539:     }
 540:   }
 541: 
 542:   /**
 543:    * Gets the AccessibleContext associated with this <code>Dialog</code>. The
 544:    * context is created, if necessary.
 545:    *
 546:    * @return the associated context
 547:    */
 548:   public AccessibleContext getAccessibleContext()
 549:   {
 550:     /* Create the context if this is the first request */
 551:     if (accessibleContext == null)
 552:       accessibleContext = new AccessibleAWTDialog();
 553:     return accessibleContext;
 554:   }
 555: 
 556:   /**
 557:    * Generate a unique name for this <code>Dialog</code>.
 558:    *
 559:    * @return A unique name for this <code>Dialog</code>.
 560:    */
 561:   String generateName()
 562:   {
 563:     return "dialog" + getUniqueLong();
 564:   }
 565: 
 566:   private static synchronized long getUniqueLong()
 567:   {
 568:     return next_dialog_number++;
 569:   }
 570: }