/* * This file is part of the Echo Web Application Framework (hereinafter "Echo"). * Copyright (C) 2002-2009 NextApp, Inc. * * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. */ package nextapp.echo2.app; import java.util.EventListener; import nextapp.echo2.app.event.WindowPaneEvent; import nextapp.echo2.app.event.WindowPaneListener; /** * A <code>Component</code> which renders its contents in a floating, * movable window. * <p> * <b>NOTE:</b> A <code>WindowPane</code> may only be added to * a <code>ContentPane</code>. */ public class WindowPane extends Component implements FloatingPane, ModalSupport, PaneContainer { public static final String INPUT_CLOSE = "input_close"; public static final String PROPERTY_BACKGROUND_IMAGE = "backgroundImage"; public static final String PROPERTY_BORDER = "border"; public static final String PROPERTY_CLOSABLE = "closable"; public static final String PROPERTY_CLOSE_ICON = "closeIcon"; public static final String PROPERTY_CLOSE_ICON_INSETS = "closeIconInsets"; public static final String PROPERTY_DEFAULT_CLOSE_OPERATION = "defaultCloseOperation"; public static final String PROPERTY_HEIGHT = "height"; public static final String PROPERTY_ICON = "icon"; public static final String PROPERTY_ICON_INSETS = "iconInsets"; public static final String PROPERTY_INSETS = "insets"; public static final String PROPERTY_MAXIMUM_HEIGHT = "maximumHeight"; public static final String PROPERTY_MAXIMUM_WIDTH = "maximumWidth"; public static final String PROPERTY_MINIMUM_HEIGHT = "minimumHeight"; public static final String PROPERTY_MINIMUM_WIDTH = "minimumWidth"; public static final String PROPERTY_MOVABLE = "movable"; public static final String PROPERTY_POSITION_X = "positionX"; public static final String PROPERTY_POSITION_Y = "positionY"; public static final String PROPERTY_RESIZABLE = "resizable"; public static final String PROPERTY_TITLE = "title"; public static final String PROPERTY_TITLE_BACKGROUND = "titleBackground"; public static final String PROPERTY_TITLE_BACKGROUND_IMAGE = "titleBackgroundImage"; public static final String PROPERTY_TITLE_BAR_INSETS = "titleBarInsets"; public static final String PROPERTY_TITLE_FONT = "titleFont"; public static final String PROPERTY_TITLE_FOREGROUND = "titleForeground"; public static final String PROPERTY_TITLE_HEIGHT = "titleHeight"; public static final String PROPERTY_TITLE_INSETS = "titleInsets"; public static final String PROPERTY_WIDTH = "width"; public static final String Z_INDEX_CHANGED_PROPERTY = "zIndex"; /** * A constant for the <code>defaultCloseOperation</code> property * indicating that nothing should be done when the user attempts * to close a window. */ public static final int DO_NOTHING_ON_CLOSE = 0; /** * A constant for the <code>defaultCloseOperation</code> property * indicating that a window should be hidden when the user attempts * to close it. */ public static final int HIDE_ON_CLOSE = 1; /** * A constant for the <code>defaultCloseOperation</code> property * indicating that a window should be removed from the component * hierarchy when a user attempts to close it. */ public static final int DISPOSE_ON_CLOSE = 2; private boolean modal = false; private int zIndex = 0; /** * Creates a new <code>WindowPane</code>. */ public WindowPane() { this(null, null, null); } /** * Creates a new <code>WindowPane</code> with the specified title * and dimensions. * * @param title the title * @param width The width * @param height The height */ public WindowPane(String title, Extent width, Extent height) { super(); if (title != null) { setTitle(title); } if (width != null) { setWidth(width); } if (height != null) { setHeight(height); } } /** * Adds a <code>WindowPaneListener</code> to receive event notifications. * * @param l the <code>WindowPaneListener</code> to add */ public void addWindowPaneListener(WindowPaneListener l) { getEventListenerList().addListener(WindowPaneListener.class, l); } /** * Notifies <code>WindowPaneListener</code>s that the user has requested * to close this <code>WindowPane</code>. */ protected void fireWindowClosing() { if (!hasEventListenerList()) { return; } EventListener[] listeners = getEventListenerList().getListeners(WindowPaneListener.class); if (listeners.length == 0) { return; } WindowPaneEvent e = new WindowPaneEvent(this); for (int i = 0; i < listeners.length; ++i) { ((WindowPaneListener) listeners[i]).windowPaneClosing(e); } } /** * Returns the background image of the <code>WindowPane</code>. * * @return the background image */ public FillImage getBackgroundImage() { return (FillImage) getProperty(PROPERTY_BACKGROUND_IMAGE); } /** * Returns the border which surrounds the entire <code>WindowPane</code>. * * @return border */ public FillImageBorder getBorder() { return (FillImageBorder) getProperty(PROPERTY_BORDER); } /** * Returns the close button icon. * * @return the icon */ public ImageReference getCloseIcon() { return (ImageReference) getProperty(PROPERTY_CLOSE_ICON); } /** * Returns the inset margin around the close button icon. * * @return the inset margin */ public Insets getCloseIconInsets() { return (Insets) getProperty(PROPERTY_CLOSE_ICON_INSETS); } /** * Returns the default close operation. * * @return the default close operation, one of the following values: * <ul> * <li>DO_NOTHING_ON_CLOSE</li> * <li>HIDE_ON_CLOSE</li> * <li>DISPOSE_ON_CLOSE</li> * </ul> */ public int getDefaultCloseOperation() { Integer defaultCloseOperationValue = (Integer) getProperty(PROPERTY_DEFAULT_CLOSE_OPERATION); return defaultCloseOperationValue == null ? 0 : defaultCloseOperationValue.intValue(); } /** * Returns the height of the content region of the window. * * @return the height */ public Extent getHeight() { return (Extent) getProperty(PROPERTY_HEIGHT); } /** * Returns the icon displayed in the title region. * * @return the icon */ public ImageReference getIcon() { return (ImageReference) getProperty(PROPERTY_ICON); } /** * Returns the inset margin around the icon. * * @return the inset margin */ public Insets getIconInsets() { return (Insets) getProperty(PROPERTY_ICON_INSETS); } /** * Returns the inset of the window content. * This property is not rendered when the content is a <code>Pane</code> * component. * * @return the inset */ public Insets getInsets() { return (Insets) getProperty(PROPERTY_INSETS); } /** * Returns the maximum height of the content region of the * <code>WindowPane</code>. * * @return the maximum height */ public Extent getMaximumHeight() { return (Extent) getProperty(PROPERTY_MAXIMUM_HEIGHT); } /** * Returns the maximum width of the content region of the * <code>WindowPane</code>. * * @return the maximum width */ public Extent getMaximumWidth() { return (Extent) getProperty(PROPERTY_MAXIMUM_WIDTH); } /** * Returns the minimum height of the content region of the * <code>WindowPane</code>. * * @return the minimum height */ public Extent getMinimumHeight() { return (Extent) getProperty(PROPERTY_MINIMUM_HEIGHT); } /** * Returns the minimum width of the content region of the * <code>WindowPane</code>. * * @return the minimum width */ public Extent getMinimumWidth() { return (Extent) getProperty(PROPERTY_MINIMUM_WIDTH); } /** * Returns the horizontal (Y) position of the <code>WindowPane</code> with * respect to its container. * * @return the position */ public Extent getPositionX() { return (Extent) getProperty(PROPERTY_POSITION_X); } /** * Returns the vertical (Y) position of the <code>WindowPane</code> with * respect to its container. * * @return the position */ public Extent getPositionY() { return (Extent) getProperty(PROPERTY_POSITION_Y); } /** * Returns the title of the <code>WindowPane</code>. * * @return the title */ public String getTitle() { return (String) getProperty(PROPERTY_TITLE); } /** * Returns the background color of the title region. * * @return the color */ public Color getTitleBackground() { return (Color) getProperty(PROPERTY_TITLE_BACKGROUND); } /** * Returns the background image of the title region. * * @return the background image */ public FillImage getTitleBackgroundImage() { return (FillImage) getProperty(PROPERTY_TITLE_BACKGROUND_IMAGE); } /** * Returns the horizontal inset of the entire title bar (relative to the content area). * Setting this value will result in the title bar being narrower than the rest of the * content region, which may be necessary to accommodate particular border styles. * * @return the insets */ public Insets getTitleBarInsets() { return (Insets) getProperty(PROPERTY_TITLE_BAR_INSETS); } /** * Returns the font of the title region. * * @return the font */ public Font getTitleFont() { return (Font) getProperty(PROPERTY_TITLE_FONT); } /** * Returns the foreground color of the title region. * * @return the color */ public Color getTitleForeground() { return (Color) getProperty(PROPERTY_TITLE_FOREGROUND); } /** * Returns the height of the title region. * * @return the height */ public Extent getTitleHeight() { return (Extent) getProperty(PROPERTY_TITLE_HEIGHT); } /** * Returns the insets of the title region. * * @return the insets */ public Insets getTitleInsets() { return (Insets) getProperty(PROPERTY_TITLE_INSETS); } /** * Returns the width of the content region of the window. * * @return the width */ public Extent getWidth() { return (Extent) getProperty(PROPERTY_WIDTH); } /** * Returns the z-index of the window with respect to its parent * <code>ContentPane</code>. Windows with higher z-indices will * visually obscure windows with lower z-indices. * * @return the z-index */ public int getZIndex() { return zIndex; } /** * Determines if the window is closable via a provided close button in * the title bar. * * @return true if the window is closable */ public boolean isClosable() { Boolean value = (Boolean) getProperty(PROPERTY_CLOSABLE); return value == null ? true: value.booleanValue(); } /** * @see nextapp.echo2.app.ModalSupport#isModal() */ public boolean isModal() { return modal; } /** * Determines if the window is movable. * * @return true if the window is movable */ public boolean isMovable() { Boolean value = (Boolean) getProperty(PROPERTY_MOVABLE); return value == null ? true : value.booleanValue(); } /** * Determines if the window is resizable. * * @return true if the window is resizable */ public boolean isResizable() { Boolean value = (Boolean) getProperty(PROPERTY_RESIZABLE); return value == null ? true : value.booleanValue(); } /** * Limit content to a single child. * * @see nextapp.echo2.app.Component#isValidChild(nextapp.echo2.app.Component) */ public boolean isValidChild(Component component) { return getComponentCount() == 0; } /** * Only allow <code>ContentPane</code>s as parents. * * @see nextapp.echo2.app.Component#isValidParent(nextapp.echo2.app.Component) */ public boolean isValidParent(Component parent) { return parent instanceof ContentPane; } /** * @see nextapp.echo2.app.Component#processInput(java.lang.String, java.lang.Object) */ public void processInput(String inputName, Object inputValue) { if (INPUT_CLOSE.equals(inputName)) { userClose(); } else if (PROPERTY_POSITION_X.equals(inputName)) { setPositionX((Extent) inputValue); } else if (PROPERTY_POSITION_Y.equals(inputName)) { setPositionY((Extent) inputValue); } else if (PROPERTY_WIDTH.equals(inputName)) { setWidth((Extent) inputValue); } else if (PROPERTY_HEIGHT.equals(inputName)) { setHeight((Extent) inputValue); } else if (Z_INDEX_CHANGED_PROPERTY.equals(inputName)) { setZIndex(((Integer) inputValue).intValue()); } } /** * Sets the background image of the <code>WindowPane</code>. * * @param newValue the new background image */ public void setBackgroundImage(FillImage newValue) { setProperty(PROPERTY_BACKGROUND_IMAGE, newValue); } /** * Sets the border which surrounds the entire <code>WindowPane</code>. * * @param newValue the new border */ public void setBorder(FillImageBorder newValue) { setProperty(PROPERTY_BORDER, newValue); } /** * Sets whether the window is closable via a provided close button in * the title bar. * * @param newValue true if the window is closable */ public void setClosable(boolean newValue) { setProperty(PROPERTY_CLOSABLE, Boolean.valueOf(newValue)); } /** * Sets the close button icon. * * @param newValue the new icon */ public void setCloseIcon(ImageReference newValue) { setProperty(PROPERTY_CLOSE_ICON, newValue); } /** * Sets the inset margin around the close button icon. * * @param newValue the new inset margin */ public void setCloseIconInsets(Insets newValue) { setProperty(PROPERTY_CLOSE_ICON_INSETS, newValue); } /** * Sets the default close operation. * * @param newValue the new default close operation, one of the following * values: * <ul> * <li>DO_NOTHING_ON_CLOSE</li> * <li>HIDE_ON_CLOSE</li> * <li>DISPOSE_ON_CLOSE</li> * </ul> */ public void setDefaultCloseOperation(int newValue) { setProperty(PROPERTY_DEFAULT_CLOSE_OPERATION, new Integer(newValue)); } /** * Sets the height of the content region of the <code>WindowPane</code>. * Values must be in pixel units. * * @param newValue the new height */ public void setHeight(Extent newValue) { Extent.validate(newValue, Extent.PX); setProperty(PROPERTY_HEIGHT, newValue); } /** * Sets the icon displayed in the title region. * * @param newValue the new icon */ public void setIcon(ImageReference newValue) { setProperty(PROPERTY_ICON, newValue); } /** * Sets the inset margin around the icon. * * @param newValue the new inset margin */ public void setIconInsets(Insets newValue) { setProperty(PROPERTY_ICON_INSETS, newValue); } /** * Sets the inset of the window content. * This property is not rendered when the content is a <code>Pane</code> * component. * * @param newValue the new inset */ public void setInsets(Insets newValue) { setProperty(PROPERTY_INSETS, newValue); } /** * Sets the maximum height of the content region of the * <code>WindowPane</code>. * Values must be in pixel units. * * @param newValue the new maximum height */ public void setMaximumHeight(Extent newValue) { Extent.validate(newValue, Extent.PX); setProperty(PROPERTY_MAXIMUM_HEIGHT, newValue); } /** * Sets the maximum width of the content region of the * <code>WindowPane</code>. * Values must be in pixel units. * * @param newValue the new maximum width */ public void setMaximumWidth(Extent newValue) { Extent.validate(newValue, Extent.PX); setProperty(PROPERTY_MAXIMUM_WIDTH, newValue); } /** * Sets the minimum height of the content region of the * <code>WindowPane</code>. * Values must be in pixel units. * * @param newValue the new minimum height */ public void setMinimumHeight(Extent newValue) { Extent.validate(newValue, Extent.PX); setProperty(PROPERTY_MINIMUM_HEIGHT, newValue); } /** * Sets the minimum width of the content region of the * <code>WindowPane</code>. * Values must be in pixel units. * * @param newValue the new minimum width */ public void setMinimumWidth(Extent newValue) { Extent.validate(newValue, Extent.PX); setProperty(PROPERTY_MINIMUM_WIDTH, newValue); } /** * Warning: when setting multiple windows modal, ensure that the window z-indices are also set such that the current * modal window will appear on top. * * @see nextapp.echo2.app.ModalSupport#setModal(boolean) */ public void setModal(boolean newValue) { boolean oldValue = modal; modal = newValue; firePropertyChange(MODAL_CHANGED_PROPERTY, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); } /** * Sets whether the window is movable. * * @param newValue true if the window may be moved by the user */ public void setMovable(boolean newValue) { setProperty(PROPERTY_MOVABLE, Boolean.valueOf(newValue)); } /** * Sets the horizontal (X) position of the <code>WindowPane</code> with * respect to its container. * Values must be in pixel units. * * @param newValue the new position */ public void setPositionX(Extent newValue) { Extent.validate(newValue, Extent.PX); setProperty(PROPERTY_POSITION_X, newValue); } /** * Sets the vertical (Y) position of the <code>WindowPane</code> with * respect to its container. * Values must be in pixel units. * * @param newValue the new position */ public void setPositionY(Extent newValue) { Extent.validate(newValue, Extent.PX); setProperty(PROPERTY_POSITION_Y, newValue); } /** * Sets whether the window is resizable. * * @param newValue true if the window may be resized by the user */ public void setResizable(boolean newValue) { setProperty(PROPERTY_RESIZABLE, Boolean.valueOf(newValue)); } /** * Sets the title of the <code>WindowPane</code>. * * @param newValue the title */ public void setTitle(String newValue) { setProperty(PROPERTY_TITLE, newValue); } /** * Sets the background color of the title region. * * @param newValue the new color */ public void setTitleBackground(Color newValue) { setProperty(PROPERTY_TITLE_BACKGROUND, newValue); } /** * Sets the background image of the title region. * * @param newValue the new background image */ public void setTitleBackgroundImage(FillImage newValue) { setProperty(PROPERTY_TITLE_BACKGROUND_IMAGE, newValue); } /** * Sets the horizontal inset of the entire title bar (relative to the content area). * Setting this value will result in the title bar being narrower than the rest of the * content region, which may be necessary to accommodate particular border styles. * * @param newValue the new insets */ public void setTitleBarInsets(Insets newValue) { setProperty(PROPERTY_TITLE_BAR_INSETS, newValue); } /** * Sets the font of the title region. * * @param newValue the new font */ public void setTitleFont(Font newValue) { setProperty(PROPERTY_TITLE_FONT, newValue); } /** * Sets the foreground color of the title region. * * @param newValue the new color */ public void setTitleForeground(Color newValue) { setProperty(PROPERTY_TITLE_FOREGROUND, newValue); } /** * Sets the height of the title region. * Values must be in pixel units. * * @param newValue the new height */ public void setTitleHeight(Extent newValue) { Extent.validate(newValue, Extent.PX); setProperty(PROPERTY_TITLE_HEIGHT, newValue); } /** * Sets the insets of the title region. * * @param newValue the new insets */ public void setTitleInsets(Insets newValue) { setProperty(PROPERTY_TITLE_INSETS, newValue); } /** * Sets the width of the content region of the window. * Values must be in pixel units. * * @param newValue the new width */ public void setWidth(Extent newValue) { Extent.validate(newValue, Extent.PX); setProperty(PROPERTY_WIDTH, newValue); } /** * Sets the z-index of the window with respect to its parent * <code>ContentPane</code>. Windows with higher z-indices will * visually obscure windows with lower z-indices. * * @param newValue the new z-index */ public void setZIndex(int newValue) { int oldValue = zIndex; zIndex = newValue; firePropertyChange(Z_INDEX_CHANGED_PROPERTY, new Integer(oldValue), new Integer(newValue)); } /** * Removes a <code>WindowPaneListener</code> from receiving event notifications. * * @param l the <code>WindowPaneListener</code> to remove */ public void removeWindowPaneListener(WindowPaneListener l) { if (!hasEventListenerList()) { return; } getEventListenerList().removeListener(WindowPaneListener.class, l); } /** * Processes a user request to close the window (via the close button). */ public void userClose() { fireWindowClosing(); Integer defaultCloseOperationValue = (Integer) getRenderProperty(PROPERTY_DEFAULT_CLOSE_OPERATION); int defaultCloseOperation = defaultCloseOperationValue == null ? DISPOSE_ON_CLOSE : defaultCloseOperationValue.intValue(); switch (defaultCloseOperation) { case DISPOSE_ON_CLOSE: getParent().remove(this); break; case HIDE_ON_CLOSE: setVisible(false); break; } } }