/*
* Beryl - A web platform based on XML, XSLT and Java
* This file is part of the Beryl XML GUI
*
* Copyright (C) 2004 Wenzel Jakob <wazlaf@tigris.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-3107 USA
*/
package org.beryl.gui.widgets;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.border.Border;
import org.beryl.gui.GUIEvent;
import org.beryl.gui.GUIEventListener;
import org.beryl.gui.GUIException;
import org.beryl.gui.GUIUtils;
import org.beryl.gui.ImageIconFactory;
import org.beryl.gui.Widget;
import org.beryl.gui.WidgetInfo;
/**
* Frame class
*
* Has an 11px border by default. Can be overwritten
* using 'spacing'
*/
public class Frame extends Widget {
private static final Border windowBorder =
BorderFactory.createEmptyBorder(
WINDOW_BORDER_SPACING,
WINDOW_BORDER_SPACING,
WINDOW_BORDER_SPACING,
WINDOW_BORDER_SPACING);
protected static WidgetInfo frameInfo = null;
private JFrame frame = null;
private Panel panel = null;
private Button defaultButton = null;
private boolean visible = false;
private boolean locationHasBeenSet = false;
private boolean isConstructed = false;
static {
frameInfo = new WidgetInfo(Frame.class, widgetInfo);
frameInfo.addProperty("border", "border", BorderFactory.createEmptyBorder());
frameInfo.addProperty("defaultCloseOperation", "enum", new Integer(JFrame.DISPOSE_ON_CLOSE));
frameInfo.addProperty("layout", "layout", new BorderLayout());
frameInfo.addProperty("location", "point", new Point(100, 100));
frameInfo.addProperty("resizable", "bool", Boolean.TRUE);
frameInfo.addProperty("spacing", "int", new Integer(WINDOW_BORDER_SPACING));
try {
frameInfo.addProperty("iconImage", "icon", ImageIconFactory.getIcon("broken"));
} catch (Exception e) {
throw new RuntimeException(e);
}
frameInfo.addProperty("size", "dimension", new Dimension(100, 100));
frameInfo.addProperty("title", "istring", "");
frameInfo.addProperty("visible", "bool", Boolean.FALSE);
frameInfo.addEvent("close");
frameInfo.removeProperty("enabled");
frameInfo.setSupportsAnchor(false);
};
public Frame(Widget parent, String name) throws GUIException {
super(parent, name);
frame = new JFrame();
panel = new Panel(this, null);
addChild(panel);
JPanel jpanel = (JPanel) panel.getWidget();
jpanel.setBorder(windowBorder);
frame.getContentPane().add(jpanel);
GUIUtils.register(this);
}
public Object getProperty(String name) throws GUIException {
if (name.equals("default")) {
return defaultButton;
} else {
return super.getProperty(name);
}
}
public void setProperty(String name, Object value) throws GUIException {
if ("layout".equals(name) || "border".equals(name) || "spacing".equals(name) || "background".equals(name)) {
panel.setProperty(name, value);
} else if ("helpid".equals(name)) {
if (helpBroker == null)
throw new GUIException("JavaHelp has not been activated");
if (value != null)
helpBroker.enableHelpKey(frame.getRootPane(), (String) value, null);
} else if ("iconImage".equals(name)) {
frame.setIconImage(((ImageIcon) value).getImage());
} else if ("size".equals(name)) {
/* Workaround: This makes the content and not the window have the
* requested size. Therefore the window content and the window decoration
* will be bigger than they would be using the normal setSize() */
((JPanel) panel.getRealWidget()).setPreferredSize((Dimension) value);
frame.pack();
} else if ("realSize".equals(name)) {
frame.setSize((Dimension) value);
frame.show();
} else if ("location".equals(name)) {
frame.setLocation((Point) value);
locationHasBeenSet = true;
} else if ("default".equals(name)) {
defaultButton = (Button) value;
JButton jbutton = null;
if (value != null) {
jbutton = (JButton) ((Button) value).getRealWidget();
}
frame.getRootPane().setDefaultButton(jbutton);
} else if ("visible".equals(name)) {
visible = ((Boolean) value).booleanValue();
if (isConstructed)
frame.setVisible(visible);
} else {
super.setProperty(name, value);
}
}
public Widget getChild(int index) {
return (Widget) panel.getChild(index);
}
public int getChildIndex(Widget child) {
return panel.getChildIndex(child);
}
public int getChildCount() {
return panel.getChildCount();
}
protected void finalize() {
GUIUtils.unregister(this);
}
public void addListener(String event, final String name, final GUIEventListener listener) throws GUIException {
if ("close".equals(event)) {
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
listener.eventOccured(new GUIEvent(Frame.this, name, e));
}
});
} else {
super.addListener(event, name, listener);
}
}
public void addChild(Widget widget, Object constraint) throws GUIException {
if (widget instanceof MenuBar) {
frame.setJMenuBar((JMenuBar) ((MenuBar) widget).getRealWidget());
panel.addChild(widget);
} else {
panel.addChild(widget, constraint);
}
}
public void removeChildWidget(Widget widget) throws GUIException {
if (widget instanceof MenuBar) {
frame.setJMenuBar(null);
super.removeChildWidget(widget);
} else {
panel.removeChildWidget(widget);
}
}
public void hide() {
frame.hide();
}
public void show() {
/* Workaround for Bug 4102292
* http://developer.java.sun.com/developer/bugParade/bugs/4102292.html
*/
if (!locationHasBeenSet) {
Dimension ss = frame.getToolkit().getScreenSize();
Dimension fs = frame.getSize();
frame.setLocation((ss.width - fs.width) / 2, (ss.height - fs.height) / 2);
}
frame.show();
}
/**
* Set the initial focus of the frame
*/
public void setInitialFocus(final Widget widget) {
frame.addWindowListener(new WindowAdapter() {
public void windowOpened(WindowEvent e) {
widget.requestFocus();
e.getWindow().removeWindowListener(this);
}
});
}
public void dispose() {
frame.dispose();
}
public void finalizeConstruction() throws GUIException {
isConstructed = true;
if (visible)
show();
}
public void revalidate() throws GUIException {
panel.revalidate();
}
public Panel getPanel() {
return panel;
}
public boolean isVisible() {
return frame.isVisible();
}
public Component getWidget() {
return frame;
}
public WidgetInfo getWidgetInfo() {
return frameInfo;
}
}