Frames | No Frames |
1: /* JFrame.java -- 2: Copyright (C) 2002, 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 gnu.java.lang.CPStringBuilder; 42: 43: import java.awt.AWTEvent; 44: import java.awt.BorderLayout; 45: import java.awt.Component; 46: import java.awt.Container; 47: import java.awt.Dimension; 48: import java.awt.Frame; 49: import java.awt.Graphics; 50: import java.awt.GraphicsConfiguration; 51: import java.awt.LayoutManager; 52: import java.awt.event.KeyEvent; 53: import java.awt.event.WindowEvent; 54: 55: import javax.accessibility.Accessible; 56: import javax.accessibility.AccessibleContext; 57: 58: /** 59: * A window that supports window decorations (titlebar and borders). 60: * This is an extension of {@link java.awt.Frame} that provides support 61: * for the Swing architecture. Most importantly it contains a {@link JRootPane} 62: * as it's only top-level child, that manages the content pane, the menu and 63: * a glass pane. 64: * 65: * Also, unlike <code>java.awt.Frame</code>s, JFrames support the 66: * Swing Pluggable Look & Feel architecture. 67: * 68: * @author Ronald Veldema (rveldema@cs.vu.nl) 69: */ 70: public class JFrame extends Frame 71: implements WindowConstants, RootPaneContainer, Accessible 72: { 73: /** 74: * Provides accessibility support for <code>JFrame</code>s. 75: */ 76: protected class AccessibleJFrame extends Frame.AccessibleAWTFrame 77: { 78: /** 79: * Creates a new instance of <code>AccessibleJFrame</code>. 80: */ 81: protected AccessibleJFrame() 82: { 83: super(); 84: // Nothing to do here. 85: } 86: } 87: 88: /** 89: * A flag for {@link #setDefaultCloseOperation(int)}, indicating that the 90: * application should be exited, when this <code>JFrame</code> is closed. 91: * Note that in version 1.4, the equivalent constant has been added to 92: * {@link WindowConstants}. 93: * 94: * @since 1.3 95: */ 96: public static final int EXIT_ON_CLOSE = 3; 97: 98: private static final long serialVersionUID = -3362141868504252139L; 99: private static boolean defaultLookAndFeelDecorated; 100: private int closeAction = HIDE_ON_CLOSE; 101: protected AccessibleContext accessibleContext; 102: protected JRootPane rootPane; 103: 104: /** 105: * @specnote rootPaneCheckingEnabled is false to comply with J2SE 5.0 106: */ 107: protected boolean rootPaneCheckingEnabled = false; 108: 109: /** 110: * Creates a new frame with an empty string for the title. 111: */ 112: public JFrame() 113: { 114: super(""); 115: frameInit(); 116: } 117: 118: /** 119: * Creates a new <code>JFrame</code> with the specified title. 120: * 121: * @param title the frame title (<code>null</code> permitted). 122: */ 123: public JFrame(String title) 124: { 125: super(title); 126: frameInit(); 127: } 128: 129: /** 130: * Creates a new JFrame in the specified {@link GraphicsConfiguration} 131: * and with an empty title. 132: * 133: * @param gc the <code>GraphicsConfiguration</code> that is used for 134: * the new <code>JFrame</code> 135: * 136: * @see Frame#Frame(GraphicsConfiguration) 137: */ 138: public JFrame(GraphicsConfiguration gc) 139: { 140: super(gc); 141: frameInit(); 142: } 143: 144: /** 145: * Creates a new JFrame in the specified {@link GraphicsConfiguration} 146: * and with the specified title. 147: * 148: * @param title the title for the new <code>JFrame</code> 149: * @param gc the <code>GraphicsConfiguration</code> that is used for 150: * the new <code>JFrame</code> 151: * 152: * @see Frame#Frame(String, GraphicsConfiguration) 153: */ 154: public JFrame(String title, GraphicsConfiguration gc) 155: { 156: super(title, gc); 157: frameInit(); 158: } 159: 160: protected void frameInit() 161: { 162: // We need to explicitly enable events here so that our processKeyEvent() 163: // and processWindowEvent() gets called. 164: enableEvents(AWTEvent.WINDOW_EVENT_MASK | AWTEvent.KEY_EVENT_MASK); 165: 166: super.setLayout(new BorderLayout()); 167: setBackground(UIManager.getDefaults().getColor("control")); 168: enableEvents(AWTEvent.WINDOW_EVENT_MASK); 169: getRootPane(); // will do set/create 170: 171: // Setup the defaultLookAndFeelDecoration if requested. 172: if (isDefaultLookAndFeelDecorated() 173: && UIManager.getLookAndFeel().getSupportsWindowDecorations()) 174: { 175: setUndecorated(true); 176: getRootPane().setWindowDecorationStyle(JRootPane.FRAME); 177: } 178: 179: // We're now done the init stage. 180: setRootPaneCheckingEnabled(true); 181: } 182: 183: public Dimension getPreferredSize() 184: { 185: return super.getPreferredSize(); 186: } 187: 188: public JMenuBar getJMenuBar() 189: { 190: return getRootPane().getJMenuBar(); 191: } 192: 193: public void setJMenuBar(JMenuBar menubar) 194: { 195: getRootPane().setJMenuBar(menubar); 196: } 197: 198: public void setLayout(LayoutManager manager) 199: { 200: // Check if we're in initialization stage. If so, call super.setLayout 201: // otherwise, valid calls go to the content pane. 202: if (isRootPaneCheckingEnabled()) 203: getContentPane().setLayout(manager); 204: else 205: super.setLayout(manager); 206: } 207: 208: public void setLayeredPane(JLayeredPane layeredPane) 209: { 210: getRootPane().setLayeredPane(layeredPane); 211: } 212: 213: public JLayeredPane getLayeredPane() 214: { 215: return getRootPane().getLayeredPane(); 216: } 217: 218: public JRootPane getRootPane() 219: { 220: if (rootPane == null) 221: setRootPane(createRootPane()); 222: return rootPane; 223: } 224: 225: protected void setRootPane(JRootPane root) 226: { 227: if (rootPane != null) 228: remove(rootPane); 229: 230: rootPane = root; 231: add(rootPane, BorderLayout.CENTER); 232: } 233: 234: protected JRootPane createRootPane() 235: { 236: return new JRootPane(); 237: } 238: 239: public Container getContentPane() 240: { 241: return getRootPane().getContentPane(); 242: } 243: 244: public void setContentPane(Container contentPane) 245: { 246: getRootPane().setContentPane(contentPane); 247: } 248: 249: public Component getGlassPane() 250: { 251: return getRootPane().getGlassPane(); 252: } 253: 254: public void setGlassPane(Component glassPane) 255: { 256: getRootPane().setGlassPane(glassPane); 257: } 258: 259: protected void addImpl(Component comp, Object constraints, int index) 260: { 261: // If we're adding in the initialization stage use super.add. 262: // Otherwise pass the add onto the content pane. 263: if (isRootPaneCheckingEnabled() && comp != rootPane) 264: getContentPane().add(comp,constraints,index); 265: else 266: super.addImpl(comp, constraints, index); 267: } 268: 269: public void remove(Component comp) 270: { 271: // If we're removing the root pane, use super.remove. Otherwise 272: // pass it on to the content pane instead. 273: if (comp==rootPane) 274: super.remove(rootPane); 275: else 276: getContentPane().remove(comp); 277: } 278: 279: protected boolean isRootPaneCheckingEnabled() 280: { 281: return rootPaneCheckingEnabled; 282: } 283: 284: protected void setRootPaneCheckingEnabled(boolean enabled) 285: { 286: rootPaneCheckingEnabled = enabled; 287: } 288: 289: public void update(Graphics g) 290: { 291: paint(g); 292: } 293: 294: protected void processKeyEvent(KeyEvent e) 295: { 296: super.processKeyEvent(e); 297: } 298: 299: public static void setDefaultLookAndFeelDecorated(boolean decorated) 300: { 301: defaultLookAndFeelDecorated = decorated; 302: } 303: 304: public static boolean isDefaultLookAndFeelDecorated() 305: { 306: return defaultLookAndFeelDecorated; 307: } 308: 309: /** 310: * Returns the object that provides accessibility features for this 311: * <code>JFrame</code>. 312: * 313: * @return The accessible context (an instance of {@link AccessibleJFrame}). 314: */ 315: public AccessibleContext getAccessibleContext() 316: { 317: if (accessibleContext == null) 318: accessibleContext = new AccessibleJFrame(); 319: return accessibleContext; 320: } 321: 322: /** 323: * Returns a code for the default operation when the frame is closed. The 324: * default value is {@link WindowConstants#HIDE_ON_CLOSE}. 325: * 326: * @return One of: {@link WindowConstants#DO_NOTHING_ON_CLOSE}, 327: * {@link WindowConstants#HIDE_ON_CLOSE}, 328: * {@link WindowConstants#DISPOSE_ON_CLOSE}, {@link #EXIT_ON_CLOSE}. 329: * 330: * @see #setDefaultCloseOperation(int) 331: */ 332: public int getDefaultCloseOperation() 333: { 334: return closeAction; 335: } 336: 337: /** 338: * Returns a string describing the attributes for the <code>JFrame</code>, 339: * for use in debugging. The return value is guaranteed to be 340: * non-<code>null</code>, but the format may vary between implementations. 341: * 342: * @return A string describing the attributes of the <code>JFrame</code>. 343: */ 344: protected String paramString() 345: { 346: CPStringBuilder sb = new CPStringBuilder(super.paramString()); 347: sb.append(",defaultCloseOperation="); 348: sb.append(SwingUtilities.convertWindowConstantToString( 349: getDefaultCloseOperation())); 350: sb.append(",rootPane="); 351: if (rootPane != null) 352: sb.append(rootPane); 353: sb.append(",rootPaneCheckingEnabled=").append(rootPaneCheckingEnabled); 354: return sb.toString(); 355: } 356: 357: protected void processWindowEvent(WindowEvent e) 358: { 359: super.processWindowEvent(e); 360: if (e.getID() == WindowEvent.WINDOW_CLOSING) 361: { 362: switch (closeAction) 363: { 364: case EXIT_ON_CLOSE: 365: System.exit(0); 366: break; 367: case DISPOSE_ON_CLOSE: 368: dispose(); 369: break; 370: case HIDE_ON_CLOSE: 371: setVisible(false); 372: break; 373: case DO_NOTHING_ON_CLOSE: 374: break; 375: } 376: } 377: } 378: 379: /** 380: * Sets the default operation that is performed when this frame is closed. 381: * The default is <code>HIDE_ON_CLOSE</code>. When 382: * <code>EXIT_ON_CLOSE</code> is specified this method calls 383: * <code>SecurityManager.checkExit(0)</code> which might throw a 384: * <code>SecurityException</code>. 385: * 386: * @param operation a code for the operation (one of: 387: * {@link WindowConstants#DO_NOTHING_ON_CLOSE}, 388: * {@link WindowConstants#HIDE_ON_CLOSE}, 389: * {@link WindowConstants#DISPOSE_ON_CLOSE} and 390: * {@link WindowConstants#EXIT_ON_CLOSE}). 391: * 392: * @throws IllegalArgumentException if <code>operation</code> is not one of 393: * the specified codes. 394: * 395: * @see #getDefaultCloseOperation() 396: */ 397: public void setDefaultCloseOperation(int operation) 398: { 399: SecurityManager sm = System.getSecurityManager(); 400: if (sm != null && operation == EXIT_ON_CLOSE) 401: sm.checkExit(0); 402: 403: if (operation != EXIT_ON_CLOSE && operation != DISPOSE_ON_CLOSE 404: && operation != HIDE_ON_CLOSE && operation != DO_NOTHING_ON_CLOSE) 405: throw new IllegalArgumentException("operation must be EXIT_ON_CLOSE, " 406: + "HIDE_ON_CLOSE, DISPOSE_ON_CLOSE, or DO_NOTHING_ON_CLOSE"); 407: 408: closeAction = operation; 409: } 410: }