/*
* @(#)Frame.java 1.10 06/10/10
*
* Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*
*/
/*
* Warning :
* Two versions of this file exist in this workspace.
* One for Personal Basis, and one for Personal Profile.
* Don't edit the wrong one !!!
*/
package java.awt;
import java.awt.event.*;
import sun.awt.AppContext;
import java.util.Vector;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import javax.swing.JMenuBar;
/**
* A Frame is window with additional properties, such as a title bar,
* a menu bar, a cursor, and an icon image where appropriate.
* A Personal Profile implementation is not required to support multiple
* frames. It must allow at least one frame to be created then it may
* throw an <em>UnsupportedOperationException</em> on subsequent <code>Frame</code> creations.
* <p>
* <li>The Title Property
* The title property can be set when the frame is created and changed
* at any time. How the title property is displayed and used is platform dependent.
* <li>The Resizable Property
* The Resizable property determines if a frame can be resized by the
* user. Personal Profile and PersonalJava, implementations are not required
* to support resizable frames.
* <li>The Cursor Property
* Not all cursors may be supported
* <h3>System Properties</h3>
* <code>java.awt.frame.SupportsMultipleFrames</code> "true" if the Personal Profile
* implementation supports multiple frames, otherwise "false".
* <p>
* <code>java.awt.frame.SupportsResizable</code> "true" if the Personal Profile
* implementation supports resizable frames, otherwise "false".
*
* @version 1.6, 08/19/02
* @author Nicholas Allen
* @see WindowEvent
* @see Window#addWindowListener
* @since JDK1.0
*/
public class Frame extends Window implements MenuContainer {
/* Note: These are being obsoleted; programs should use the Cursor class
* variables going forward. See Cursor and Component.setCursor.
*/
/**
*
*/
public static final int DEFAULT_CURSOR = Cursor.DEFAULT_CURSOR;
/**
*
*/
public static final int CROSSHAIR_CURSOR = Cursor.CROSSHAIR_CURSOR;
/**
*
*/
public static final int TEXT_CURSOR = Cursor.TEXT_CURSOR;
/**
*
*/
public static final int WAIT_CURSOR = Cursor.WAIT_CURSOR;
/**
*
*/
public static final int SW_RESIZE_CURSOR = Cursor.SW_RESIZE_CURSOR;
/**
*
*/
public static final int SE_RESIZE_CURSOR = Cursor.SE_RESIZE_CURSOR;
/**
*
*/
public static final int NW_RESIZE_CURSOR = Cursor.NW_RESIZE_CURSOR;
/**
*
*/
public static final int NE_RESIZE_CURSOR = Cursor.NE_RESIZE_CURSOR;
/**
*
*/
public static final int N_RESIZE_CURSOR = Cursor.N_RESIZE_CURSOR;
/**
*
*/
public static final int S_RESIZE_CURSOR = Cursor.S_RESIZE_CURSOR;
/**
*
*/
public static final int W_RESIZE_CURSOR = Cursor.W_RESIZE_CURSOR;
/**
*
*/
public static final int E_RESIZE_CURSOR = Cursor.E_RESIZE_CURSOR;
/**
*
*/
public static final int HAND_CURSOR = Cursor.HAND_CURSOR;
/**
*
*/
public static final int MOVE_CURSOR = Cursor.MOVE_CURSOR;
String title = "Untitled";
Image icon;
MenuBar menuBar;
boolean resizable = true;
boolean mbManagement = false; /* used only by the Motif impl. */
/*
* The Windows owned by the Frame.
*/
Vector ownedWindows;
private static final String base = "frame";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 2673458971256075116L;
/**
* Constructs a new <code>Frame</code>
* <h3>Compatibility</h3>
* A Personal Profile implementation is not required to support multiple
* Frames (the current Frame must be destroyed before a subsequent Frame
* can be created). Support for menu objects is independent of the level
* of Frame support.
* <p>
* A PersonalJava implementation, which fully supported Frame, also
* supported CheckBoxMenuItem, Menu, MenuBar and MenuShortcut.
* JDK Fully supports multiple frames.
* @exception UnsupportedOperationException if multiple frames are created
* on a platform which only supports a single frame.
* @see Component#setSize
* @see Component#setVisible
* @since JDK1.0
*/
public Frame() {
this("");
}
/**
* Constructs a new <code>Frame</code>
* <h3>Compatibility</h3>
* A Personal Profile implementation is not required to support multiple
* Frames (the current Frame must be destroyed before a subsequent Frame
* can be created). Support for menu objects is independent of the level
* of Frame support.
* <p>
* A PersonalJava implementation, which fully supported Frame, also
* supported CheckBoxMenuItem, Menu, MenuBar and MenuShortcut.
* JDK Fully supports multiple frames.
* @param title is the string specifying the frames title.
* @exception UnsupportedOperationException if multiple frames are created
* on a platform which only supports a single frame.
* @see java.awt.Component#setSize
* @see java.awt.Component#setVisible
* @since JDK1.0
*/
public Frame(String title) {
this.title = title;
visible = false;
setLayout(new BorderLayout());
}
/**
* Construct a name for this component. Called by getName() when the
* name is null.
*/
String constructComponentName() {
return base + nameCounter++;
}
/**
* Adds the specified window to the list of windows owned by
* the frame.
* @param window the window to be added
*/
Window addOwnedWindow(Window window) {
if (window != null) {
if (ownedWindows == null) {
ownedWindows = new Vector();
}
ownedWindows.addElement(window);
}
return window;
}
/**
* Removes the specified window from the list of windows owned by
* the frame.
* @param window the window to be added
*/
void removeOwnedWindow(Window window) {
if (window != null) {
if (ownedWindows != null) {
ownedWindows.removeElement(window);
}
}
}
ComponentXWindow createXWindow() {
return new FrameXWindow(this);
}
public Graphics getGraphics() {
Graphics g = super.getGraphics();
// Clip graphics so cannot draw in menu bar area
if (g != null && menuBar != null) {
Insets insets = getInsets();
g.clipRect(0, insets.top, width, height);
}
return g;
}
public void addNotify() {
super.addNotify();
MenuBar menuBar = this.menuBar;
if (menuBar != null)
menuBar.addNotify();
}
public void removeNotify() {
super.removeNotify();
MenuBar menuBar = this.menuBar;
if (menuBar != null)
menuBar.removeNotify();
}
/**
* Gets the title of the frame.
* @return the title of this frame, or <code>null</code>
* if this frame doesn't have a title.
* @see java.awt.Frame#setTitle
* @since JDK1.0
*/
public String getTitle() {
return title;
}
/**
* Sets the title for this frame to the specified title.
* @param title the specified title of this frame.
* @see java.awt.Frame#getTitle
* @since JDK1.0
*/
public synchronized void setTitle(String title) {
this.title = title;
FrameXWindow xwindow = (FrameXWindow) this.xwindow;
if (xwindow != null) {
xwindow.setTitle(title);
}
}
/**
* Gets the icon image for this frame.
* @return the icon image for this frame, or <code>null</code>
* if this frame doesn't have an icon image.
* @see java.awt.Frame#setIconImage
* @since JDK1.0
*/
public Image getIconImage() {
return icon;
}
public Insets getInsets() {
Insets insets = super.getInsets();
if (menuBar != null)
insets.top += menuBar.jMenuBar.getHeight();
return insets;
}
public void validate() {
MenuBar menuBar = this.menuBar;
if (menuBar != null) {
Insets insets = super.getInsets();
menuBar.jMenuBar.setBounds(insets.left, insets.top, width - insets.left - insets.right, menuBar.jMenuBar.getPreferredSize().height);
menuBar.jMenuBar.validate();
}
super.validate();
}
void dispatchEventImpl(AWTEvent e) {
super.dispatchEventImpl(e);
// Paint the JMenuBar if a menubar is attatched to this frame.
if (e instanceof PaintEvent) {
PaintEvent paintEvent = (PaintEvent) e;
MenuBar menuBar = this.menuBar;
if (menuBar != null) {
// Get super graphics because our graphics is clipped to prevent drawing
// in the menu bar area.
Graphics g = super.getGraphics();
if (g != null) {
Rectangle clip = paintEvent.getUpdateRect();
g.clipRect(clip.x, clip.y, clip.width, clip.height);
Component c = menuBar.jMenuBar;
Graphics cg = g.create(c.x, c.y, c.width, c.height);
try {
c.paint(cg);
} finally {
cg.dispose();
g.dispose();
Toolkit.getDefaultToolkit().sync();
}
}
}
}
}
/**
* Sets the image to display when this frame is iconized.
* Not all platforms support the concept of iconizing a window.
* @param image the icon image to be displayed
* @see java.awt.Frame#getIconImage
* @since JDK1.0
*/
public synchronized void setIconImage(Image image) {
this.icon = image;
FrameXWindow xwindow = (FrameXWindow) this.xwindow;
if (xwindow != null) {
xwindow.setIconImage(image);
}
}
/**
* Gets the menu bar for this frame.
* @return the menu bar for this frame, or <code>null</code>
* if this frame doesn't have a menu bar.
* @see java.awt.Frame#setMenuBar
* @since JDK1.0
*/
public MenuBar getMenuBar() {
return menuBar;
}
/**
* Sets this Frame's menu bar.
* <h3>Compatability</h3>
* In PersonalJava and PersonalProfile, this operation is optional and throws an
* UnsupportedOperationException if it is not supported.
* @param mb the menu bar being set
* @exception UnsupportedOperationException if it is not supported.
* @see java.awt.Frame#getMenuBar
* @see java.awt.MenuBar
* @since JDK1.0
*/
public void setMenuBar(MenuBar mb) {
synchronized (getTreeLock()) {
if (menuBar == mb) {
return;
}
if (menuBar != null) {
remove(menuBar);
}
menuBar = mb;
if (mb != null) {
if (mb.parent != null)
mb.parent.remove(mb);
mb.parent = this;
if (xwindow != null)
mb.addNotify();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
invalidate();
validate();
}
}
);
}
}
/**
* Indicates whether this frame is resizable.
* By default, all frames are initially resizable.
* @return <code>true</code> if the user can resize this frame;
* <code>false</code> otherwise.
* @see java.awt.Frame#setResizable
* @since JDK1.0
*/
public boolean isResizable() {
return resizable;
}
/**
* Sets the resizable Property
* <h3>Compatability</h3>
* In Personal Profile this method can have no effect. The
* <code>isResizable()</code> method may be used to verify this.
* Also the system property java.awt.frame.SupportsResizable is
* <code>"true"</code> if the platform supports resizable frames.
* @param resizable if <code>true</code>, the frame becomes resizable,
* otherwise the frame become non resizable.
* @see java.awt.Frame#isResizable
* @since JDK1.0
*/
public synchronized void setResizable(boolean resizable) {
this.resizable = resizable;
FrameXWindow xwindow = (FrameXWindow) this.xwindow;
if (xwindow != null) {
xwindow.setResizable(resizable);
}
}
/**
* Removes the specified menu bar from this frame.
* @param m the menu component to remove.
* @since JDK1.0
*/
public void remove(MenuComponent m) {
synchronized (getTreeLock()) {
if (m != null && m == menuBar) {
menuBar.parent = null;
menuBar = null;
if (xwindow != null)
m.removeNotify();
} else {
super.remove(m);
}
}
}
/**
* Disposes of the Frame. This method must
* be called to release the resources that
* are used for the frame. All components
* contained by the frame and all windows
* owned by the frame will also be destroyed.
* @since JDK1.0
*/
public void dispose() { // synch removed.
synchronized (getTreeLock()) {
if (ownedWindows != null) {
int ownedWindowCount = ownedWindows.size();
Window ownedWindowCopy[] = new Window[ownedWindowCount];
ownedWindows.copyInto(ownedWindowCopy);
for (int i = 0; i < ownedWindowCount; i++) {
ownedWindowCopy[i].dispose();
}
}
if (menuBar != null) {
remove(menuBar);
menuBar = null;
}
}
super.dispose();
}
void postProcessKeyEvent(KeyEvent e) {
if (menuBar != null && menuBar.handleShortcut(e)) {
e.consume();
return;
}
super.postProcessKeyEvent(e);
}
/**
* Returns the parameter String of this Frame.
*/
protected String paramString() {
String str = super.paramString();
if (resizable) {
str += ",resizable";
}
if (title != null) {
str += ",title=" + title;
}
return str;
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>Component.setCursor(Cursor)</code>.
*/
public synchronized void setCursor(int cursorType) {
if (cursorType < DEFAULT_CURSOR || cursorType > MOVE_CURSOR) {
throw new IllegalArgumentException("illegal cursor type");
}
setCursor(Cursor.getPredefinedCursor(cursorType));
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>Component.getCursor()</code>.
*/
public int getCursorType() {
return (getCursor().getType());
}
/**
* Returns an array containing all Frames created by the application.
* If called from an applet, the array will only include the Frames
* accessible by that applet.
* @since 1.2
*/
public static Frame[] getFrames() {
synchronized (Frame.class) {
Frame realCopy[];
Vector frameList =
(Vector) AppContext.getAppContext().get(Frame.class);
if (frameList != null) {
// Recall that frameList is actually a Vector of WeakReferences
// and calling get() on one of these references may return
// null. Make two arrays-- one the size of the Vector
// (fullCopy with size fullSize), and one the size of all
// non-null get()s (realCopy with size realSize).
int fullSize = frameList.size();
int realSize = 0;
Frame fullCopy[] = new Frame[fullSize];
for (int i = 0; i < fullSize; i++) {
fullCopy[realSize] = (Frame)
(((WeakReference) (frameList.elementAt(i))).get());
if (fullCopy[realSize] != null) {
realSize++;
}
}
if (fullSize != realSize) {
realCopy = new Frame[realSize];
System.arraycopy(fullCopy, 0, realCopy, 0, realSize);
} else {
realCopy = fullCopy;
}
} else {
realCopy = new Frame[0];
}
return realCopy;
}
}
/* Serialization support. If there's a MenuBar we restore
* its (transient) parent field here. Likewise for top level
* windows that are "owned" by this frame.
*/
private int frameSerializedDataVersion = 1;
private void writeObject(ObjectOutputStream s)
throws IOException {
s.defaultWriteObject();
}
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException {
s.defaultReadObject();
if (menuBar != null)
menuBar.parent = this;
if (ownedWindows != null) {
for (int i = 0; i < ownedWindows.size(); i++) {
Window child = (Window) (ownedWindows.elementAt(i));
child.parent = this;
}
}
}
}