/*
* 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 java.util.HashMap;
import java.util.Iterator;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
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.Widget;
import org.beryl.gui.WidgetInfo;
public class Dialog extends Widget {
protected static WidgetInfo dialogInfo = null;
private static final Border windowBorder =
BorderFactory.createEmptyBorder(
WINDOW_BORDER_SPACING,
WINDOW_BORDER_SPACING,
WINDOW_BORDER_SPACING,
WINDOW_BORDER_SPACING);
private JDialog dialog = null;
private Panel panel = null;
private Button defaultButton = null;
private JButton jDefaultButton = null;
private boolean isModal = true;
private String title = null;
private HashMap closeListeners = null;
private Point location = null;
static {
dialogInfo = new WidgetInfo(Dialog.class, widgetInfo);
dialogInfo.addProperty("border", "border", BorderFactory.createEmptyBorder());
dialogInfo.addProperty("defaultCloseOperation", "enum", new Integer(JFrame.DISPOSE_ON_CLOSE));
dialogInfo.addProperty("layout", "layout", new BorderLayout());
dialogInfo.addProperty("location", "point", new Point(100, 100));
dialogInfo.addProperty("resizable", "bool", Boolean.TRUE);
dialogInfo.addProperty("size", "dimension", new Dimension(100, 100));
dialogInfo.addProperty("spacing", "int", new Integer(WINDOW_BORDER_SPACING));
dialogInfo.addProperty("title", "istring", "");
dialogInfo.addEvent("close");
dialogInfo.removeProperty("enabled");
dialogInfo.setSupportsAnchor(false);
};
public Dialog(Widget parent, String name) throws GUIException {
super(parent, name);
panel = new Panel(this, null);
closeListeners = new HashMap();
((JPanel) panel.getWidget()).setBorder(windowBorder);
GUIUtils.register(this);
addChild(panel);
}
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 ("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);
if (dialog != null)
dialog.pack();
} else if ("helpid".equals(name)) {
if (helpBroker == null)
throw new GUIException("JavaHelp has not been activated");
if (value != null)
helpBroker.enableHelpKey(dialog.getRootPane(), (String) value, null);
} else if ("modal".equals(name)) {
isModal = ((Boolean) value).booleanValue();
} else if ("visible".equals(name)) {
throw new GUIException("Visible is not a settable property, use Dialog's 'show' method instead");
} else if ("location".equals(name)) {
location = (Point) value;
if (dialog != null)
dialog.setLocation((Point) value);
} else if ("default".equals(name)) {
defaultButton = (Button) value;
jDefaultButton = (JButton) defaultButton.getRealWidget();
if (dialog != null)
dialog.getRootPane().setDefaultButton(jDefaultButton);
} else if ("title".equals(name)) {
title = (String) value;
if (dialog != null)
dialog.setTitle(title);
} else {
if (dialog == null)
throw new GUIException("Property '" + name + "' is not yet supported by Dialog");
super.setProperty(name, value);
}
}
protected void finalize() {
GUIUtils.unregister(this);
}
public void addChild(Widget widget, Object constraint) throws GUIException {
panel.addChild(widget, constraint);
}
public void removeChildWidget(Widget widget) throws GUIException {
panel.removeChildWidget(widget);
}
public void addListener(String event, String name, GUIEventListener listener) throws GUIException {
if ("close".equals(event)) {
closeListeners.put(name, listener);
} else {
super.addListener(event, name, listener);
}
}
public void hide() {
dialog.hide();
}
public void initDialog(Widget parent) throws GUIException {
if (parent == null)
dialog = new JDialog(); // this is perfectly valid
else if (parent instanceof Dialog)
dialog = new JDialog((JDialog) parent.getRealWidget(), isModal);
else if (parent instanceof Frame)
dialog = new JDialog((JFrame) parent.getRealWidget(), isModal);
else if (parent instanceof Wizard)
dialog = new JDialog((JFrame) parent.getRealWidget(), isModal);
else
throw new GUIException("Invalid parent (no Dialog/Frame/Wizard/null)");
}
public void show() throws GUIException {
if (dialog != null) {
JPanel jpanel = (JPanel) panel.getWidget();
dialog.getContentPane().add(jpanel);
if (jDefaultButton != null)
dialog.getRootPane().setDefaultButton(jDefaultButton);
if (title != null)
dialog.setTitle(title);
dialog.pack();
/* Workaround for Bug 4102292
* http://developer.java.sun.com/developer/bugParade/bugs/4102292.html
*/
if (location == null) {
Dimension ss = dialog.getToolkit().getScreenSize();
Dimension fs = dialog.getSize();
dialog.setLocation((ss.width - fs.width) / 2, (ss.height - fs.height) / 2);
} else {
dialog.setLocation(location);
}
for (Iterator i = closeListeners.keySet().iterator(); i.hasNext();) {
final String name = (String) i.next();
final GUIEventListener listener = (GUIEventListener) closeListeners.get(name);
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
listener.eventOccured(new GUIEvent(Dialog.this, name, e));
}
});
}
} else
throw new GUIException("Initialize dialog first!");
dialog.show();
}
/**
* Set the initial focus of the dialog
*/
public void setInitialFocus(final Widget widget) throws GUIException {
if (dialog == null)
throw new GUIException("The dialog has not yet been created. Call setInitialFocus() after initDialog()");
dialog.addWindowListener(new WindowAdapter() {
public void windowOpened(WindowEvent e) {
widget.requestFocus();
e.getWindow().removeWindowListener(this);
}
});
}
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();
}
public void dispose() {
dialog.dispose();
}
public void revalidate() throws GUIException {
panel.revalidate();
}
public Panel getPanel() {
return panel;
}
public Component getWidget() {
return dialog;
}
public WidgetInfo getWidgetInfo() {
return dialogInfo;
}
}