Frames | No Frames |
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: }