/* @VaadinApache2LicenseForJavaFiles@ */ package com.vaadin.ui; import java.io.Serializable; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.Map; import java.util.Set; import com.vaadin.Application; import com.vaadin.event.FieldEvents.BlurEvent; import com.vaadin.event.FieldEvents.BlurListener; import com.vaadin.event.FieldEvents.BlurNotifier; import com.vaadin.event.FieldEvents.FocusEvent; import com.vaadin.event.FieldEvents.FocusListener; import com.vaadin.event.FieldEvents.FocusNotifier; import com.vaadin.event.ShortcutAction; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.event.ShortcutAction.ModifierKey; import com.vaadin.event.ShortcutListener; import com.vaadin.terminal.DownloadStream; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.ParameterHandler; import com.vaadin.terminal.Resource; import com.vaadin.terminal.Sizeable; import com.vaadin.terminal.Terminal; import com.vaadin.terminal.URIHandler; import com.vaadin.terminal.gwt.client.ui.VView; import com.vaadin.terminal.gwt.client.ui.VWindow; /** * A component that represents an application (browser native) window or a sub * window. *
* If the window is a application window or a sub window depends on how it is * added to the application. Adding a {@code Window} to a {@code Window} using * {@link Window#addWindow(Window)} makes it a sub window and adding a * {@code Window} to the {@code Application} using * {@link Application#addWindow(Window)} makes it an application window. *
** An application window is the base of any view in a Vaadin application. All * applications contain a main application window (set using * {@link Application#setMainWindow(Window)} which is what is initially shown to * the user. The contents of a window is set using * {@link #setContent(ComponentContainer)}. The contents can in turn contain * other components. For multi-tab applications there is one window instance per * opened tab. *
** A sub window is floating popup style window that can be added to an * application window. Like the application window its content is set using * {@link #setContent(ComponentContainer)}. A sub window can be positioned on * the screen using absolute coordinates (pixels). The default content of the * Window is set to be suitable for application windows. For sub windows it * might be necessary to set the size of the content to work as expected. *
** Window caption is displayed in the browser title bar for application level * windows and in the window header for sub windows. *
** Certain methods in this class are only meaningful for sub windows and other * parts only for application windows. These are marked using Sub window * only and Application window only respectively in the javadoc. *
** Sub window is to be split into a separate component in Vaadin 7. *
* * @author Vaadin Ltd. * @version * @VERSION@ * @since 3.0 */ @SuppressWarnings("serial") @ClientWidget(VWindow.class) public class Window extends Panel implements URIHandler, ParameterHandler, FocusNotifier, BlurNotifier { /** * Application window only. A border style used for opening resources * in a window without a border. */ public static final int BORDER_NONE = 0; /** * Application window only. A border style used for opening resources * in a window with a minimal border. */ public static final int BORDER_MINIMAL = 1; /** * Application window only. A border style that indicates that the * default border style should be used when opening resources. */ public static final int BORDER_DEFAULT = 2; /** * Application window only. The user terminal for this window. */ private Terminal terminal = null; /** * Application window only. The application this window is attached * to or null. */ private Application application = null; /** * Application window only. List of URI handlers for this window. */ private LinkedList* This is always the window itself. *
** This method is not meant to be overridden. Due to CDI requirements we * cannot declare it as final even though it should be final. *
* * @see Component#getWindow() * @return the window itself */ @Override public Window getWindow() { return this; } /* * (non-Javadoc) * * @see com.vaadin.ui.AbstractComponent#getApplication() */ @Override public Application getApplication() { if (getParent() == null) { return application; } return getParent().getApplication(); } /** * Gets the parent component of the window. * ** The parent of an application window is always null. The parent of a sub * window is the application window the sub window is attached to. *
** This method is not meant to be overridden. Due to CDI requirements we * cannot declare it as final even though it should be final. *
* * * @return the parent window * @see Component#getParent() */ @Override public Window getParent() { return (Window) super.getParent(); } /* ********************************************************************* */ /** * Application window only. Adds a new URI handler to this window. If * this is a sub window the URI handler is attached to the parent * application window. * * @param handler * the URI handler to add. */ public void addURIHandler(URIHandler handler) { if (getParent() != null) { // this is subwindow, attach to main level instead // TODO hold internal list also and remove on detach Window mainWindow = getParent(); mainWindow.addURIHandler(handler); } else { if (uriHandlerList == null) { uriHandlerList = new LinkedList* If the theme for this window is not explicitly set, the application theme * name is returned. If the window is not attached to an application, the * terminal default theme name is returned. If the theme name cannot be * determined, null is returned *
** Subwindows do not support themes and return the theme used by the parent * window *
* * @return the name of the theme used for the window */ public String getTheme() { if (getParent() != null) { return (getParent()).getTheme(); } if (theme != null) { return theme; } if ((application != null) && (application.getTheme() != null)) { return application.getTheme(); } if (terminal != null) { return terminal.getDefaultTheme(); } return null; } /** * Application window only. Sets the name of the theme to use for * this window. Changing the theme will cause the page to be reloaded. * * @param theme * the name of the new theme for this window or null to use the * application theme. */ public void setTheme(String theme) { if (getParent() != null) { throw new UnsupportedOperationException( "Setting theme for sub-windows is not supported."); } this.theme = theme; requestRepaint(); } /* * (non-Javadoc) * * @see com.vaadin.ui.Panel#paintContent(com.vaadin.terminal.PaintTarget) */ @Override public synchronized void paintContent(PaintTarget target) throws PaintException { // Sets the window name final String name = getName(); target.addAttribute("name", name == null ? "" : name); // Sets the window theme final String theme = getTheme(); target.addAttribute("theme", theme == null ? "" : theme); if (modal) { target.addAttribute("modal", true); } if (resizable) { target.addAttribute("resizable", true); } if (resizeLazy) { target.addAttribute(VView.RESIZE_LAZY, resizeLazy); } if (!draggable) { // Inverted to prevent an extra attribute for almost all sub windows target.addAttribute("fixedposition", true); } if (bringToFront != null) { target.addAttribute("bringToFront", bringToFront.intValue()); bringToFront = null; } if (centerRequested) { target.addAttribute("center", true); centerRequested = false; } if (scrollIntoView != null) { target.addAttribute("scrollTo", scrollIntoView); scrollIntoView = null; } // Marks the main window if (getApplication() != null && this == getApplication().getMainWindow()) { target.addAttribute("main", true); } if (getContent() != null) { if (getContent().getHeightUnits() == Sizeable.UNITS_PERCENTAGE) { target.addAttribute("layoutRelativeHeight", true); } if (getContent().getWidthUnits() == Sizeable.UNITS_PERCENTAGE) { target.addAttribute("layoutRelativeWidth", true); } } // Open requested resource synchronized (openList) { if (!openList.isEmpty()) { for (final Iterator
* The supplied {@code windowName} is used as the target name in a
* window.open call in the client. This means that special values such as
* "_blank", "_self", "_top", "_parent" have special meaning. An empty or
* null
window name is also a special case.
*
* "", null and "_self" as {@code windowName} all causes the resource to be * opened in the current window, replacing any old contents. For * downloadable content you should avoid "_self" as "_self" causes the * client to skip rendering of any other changes as it considers them * irrelevant (the page will be replaced by the resource). This can speed up * the opening of a resource, but it might also put the client side into an * inconsistent state if the window content is not completely replaced e.g., * if the resource is downloaded instead of displayed in the browser. *
** "_blank" as {@code windowName} causes the resource to always be opened in * a new window or tab (depends on the browser and browser settings). *
** "_top" and "_parent" as {@code windowName} works as specified by the HTML * standard. *
** Any other {@code windowName} will open the resource in a window with that * name, either by opening a new window/tab in the browser or by replacing * the contents of an existing window with that name. *
** *
* * @param resource * the resource. * @param windowName * the name of the window. */ public void open(Resource resource, String windowName) { open(resource, windowName, true); } /** * Opens the given resource in a window with the given name and optionally * tries to force the resource to open in a new window instead of a new tab. *
* The supplied {@code windowName} is used as the target name in a
* window.open call in the client. This means that special values such as
* "_blank", "_self", "_top", "_parent" have special meaning. An empty or
* null
window name is also a special case.
*
* "", null and "_self" as {@code windowName} all causes the resource to be * opened in the current window, replacing any old contents. For * downloadable content you should avoid "_self" as "_self" causes the * client to skip rendering of any other changes as it considers them * irrelevant (the page will be replaced by the resource). This can speed up * the opening of a resource, but it might also put the client side into an * inconsistent state if the window content is not completely replaced e.g., * if the resource is downloaded instead of displayed in the browser. *
** "_blank" as {@code windowName} causes the resource to always be opened in * a new window or tab (depends on the browser and browser settings). *
** "_top" and "_parent" as {@code windowName} works as specified by the HTML * standard. *
** Any other {@code windowName} will open the resource in a window with that * name, either by opening a new window/tab in the browser or by replacing * the contents of an existing window with that name. *
** If {@code windowName} is set to open the resource in a new window or tab * and {@code tryToOpenAsPopup} is true, this method attempts to force the * browser to open a new window instead of a tab. NOTE: This is a * best-effort attempt and may not work reliably with all browsers and * different pop-up preferences. With most browsers using default settings, * {@code tryToOpenAsPopup} works properly. *
* * @param resource * the resource. * @param windowName * the name of the window. * @param tryToOpenAsPopup * Whether to try to force the resource to be opened in a new * window * */ public void open(Resource resource, String windowName, boolean tryToOpenAsPopup) { synchronized (openList) { if (!openList.contains(resource)) { openList.add(new OpenResource(resource, windowName, -1, -1, BORDER_DEFAULT, tryToOpenAsPopup)); } } requestRepaint(); } /** * Opens the given resource in a window with the given size, border and * name. For more information on the meaning of {@code windowName}, see * {@link #open(Resource, String)}. * * @param resource * the resource. * @param windowName * the name of the window. * @param width * the width of the window in pixels * @param height * the height of the window in pixels * @param border * the border style of the window. See {@link #BORDER_NONE * Window.BORDER_* constants} */ public void open(Resource resource, String windowName, int width, int height, int border) { synchronized (openList) { if (!openList.contains(resource)) { openList.add(new OpenResource(resource, windowName, width, height, border, true)); } } requestRepaint(); } /* ********************************************************************* */ /** * Gets the full URL of the window. The returned URL is window specific and * can be used to directly refer to the window. ** Note! This method can not be used for portlets. *
* * @return the URL of the window or null if the window is not attached to an * application */ public URL getURL() { if (application == null) { return null; } try { return new URL(application.getURL(), getName() + "/"); } catch (final MalformedURLException e) { throw new RuntimeException( "Internal problem getting window URL, please report"); } } /** * Application window only. Gets the unique name of the window. The * name of the window is used to uniquely identify it. ** The name also determines the URL that can be used for direct access to a * window. All windows can be accessed through * {@code http://host:port/app/win} where {@code http://host:port/app} is * the application URL (as returned by {@link Application#getURL()} and * {@code win} is the window name. *
** Note! Portlets do not support direct window access through URLs. *
* * @return the Name of the Window. */ public String getName() { return name; } /** * Returns the border style of the window. * * @see #setBorder(int) * @return the border style for the window */ public int getBorder() { return border; } /** * Sets the border style for this window. Valid values are * {@link Window#BORDER_NONE}, {@link Window#BORDER_MINIMAL}, * {@link Window#BORDER_DEFAULT}. ** Note! Setting this seems to currently have no effect whatsoever on * the window. *
* * @param border * the border style to set */ public void setBorder(int border) { this.border = border; } /** * Sets the application this window is attached to. * ** This method is called by the framework and should not be called directly * from application code. {@link com.vaadin.Application#addWindow(Window)} * should be used to add the window to an application and * {@link com.vaadin.Application#removeWindow(Window)} to remove the window * from the application. *
** This method invokes {@link Component#attach()} and * {@link Component#detach()} methods when necessary. *
* * @param application * the application the window is attached to */ public void setApplication(Application application) { // If the application is not changed, dont do nothing if (application == this.application) { return; } // Sends detach event if the window is connected to application if (this.application != null) { detach(); } // Connects to new parent this.application = application; // Sends the attach event if connected to a window if (application != null) { attach(); } } /** * Application window only. Sets the unique name of the window. The * name of the window is used to uniquely identify it inside the * application. *
* The name also determines the URL that can be used for direct access to a * window. All windows can be accessed through * {@code http://host:port/app/win} where {@code http://host:port/app} is * the application URL (as returned by {@link Application#getURL()} and * {@code win} is the window name. *
** This method can only be called before the window is added to an * application. *
** Note! Portlets do not support direct window access through URLs. *
* * @param name * the new name for the window or null if the application should * automatically assign a name to it * @throws IllegalStateException * if the window is attached to an application */ public void setName(String name) throws IllegalStateException { // The name can not be changed in application if (getApplication() != null) { throw new IllegalStateException( "Window name can not be changed while " + "the window is in application"); } this.name = name; } /** * Sets the user terminal. Used by the terminal adapter, should never be * called from application code. * * @param type * the terminal to set. */ public void setTerminal(Terminal type) { terminal = type; } /** * Private class for storing properties related to opening resources. */ private class OpenResource implements Serializable { /** * The resource to open */ private final Resource resource; /** * The name of the target window */ private final String name; /** * The width of the target window */ private final int width; /** * The height of the target window */ private final int height; /** * The border style of the target window */ private final int border; private final boolean tryToOpenAsPopup; /** * Creates a new open resource. * * @param resource * The resource to open * @param name * The name of the target window * @param width * The width of the target window * @param height * The height of the target window * @param border * The border style of the target window * @param tryToOpenAsPopup * Should try to open as a pop-up * */ private OpenResource(Resource resource, String name, int width, int height, int border, boolean tryToOpenAsPopup) { this.resource = resource; this.name = name; this.width = width; this.height = height; this.border = border; this.tryToOpenAsPopup = tryToOpenAsPopup; } /** * Paints the open request. Should be painted inside the window. * * @param target * the paint target * @throws PaintException * if the paint operation fails */ private void paintContent(PaintTarget target) throws PaintException { target.startTag("open"); target.addAttribute("src", resource); if (name != null && name.length() > 0) { target.addAttribute("name", name); } if (!tryToOpenAsPopup) { target.addAttribute("popup", tryToOpenAsPopup); } if (width >= 0) { target.addAttribute("width", width); } if (height >= 0) { target.addAttribute("height", height); } switch (border) { case Window.BORDER_MINIMAL: target.addAttribute("border", "minimal"); break; case Window.BORDER_NONE: target.addAttribute("border", "none"); break; } target.endTag("open"); } } /* * (non-Javadoc) * * @see com.vaadin.ui.Panel#changeVariables(java.lang.Object, java.util.Map) */ @Override public void changeVariables(Object source, Map* By default, sub-windows are removed from their respective parent windows * and thus visually closed on browser-side. Browser-level windows also * closed on the client-side, but they are not implicitly removed from the * application. *
* ** To explicitly close a sub-window, use {@link #removeWindow(Window)}. To * react to a window being closed (after it is closed), register a * {@link CloseListener}. *
*/ protected void close() { Window parent = getParent(); if (parent == null) { fireClose(); } else { // focus is restored to the parent window parent.focus(); // subwindow is removed from parent parent.removeWindow(this); } } /** * Gets the distance of Window left border in pixels from left border of the * containing (main window). * * @return the Distance of Window left border in pixels from left border of * the containing (main window). or -1 if unspecified. * @since 4.0.0 */ public int getPositionX() { return positionX; } /** * Sets the distance of Window left border in pixels from left border of the * containing (main window). * * @param positionX * the Distance of Window left border in pixels from left border * of the containing (main window). or -1 if unspecified. * @since 4.0.0 */ public void setPositionX(int positionX) { setPositionX(positionX, true); } /** * Sets the distance of Window left border in pixels from left border of the * containing (main window). * * @param positionX * the Distance of Window left border in pixels from left border * of the containing (main window). or -1 if unspecified. * @param repaintRequired * true if the window needs to be repainted, false otherwise * @since 6.3.4 */ private void setPositionX(int positionX, boolean repaintRequired) { this.positionX = positionX; centerRequested = false; if (repaintRequired) { requestRepaint(); } } /** * Gets the distance of Window top border in pixels from top border of the * containing (main window). * * @return Distance of Window top border in pixels from top border of the * containing (main window). or -1 if unspecified . * * @since 4.0.0 */ public int getPositionY() { return positionY; } /** * Sets the distance of Window top border in pixels from top border of the * containing (main window). * * @param positionY * the Distance of Window top border in pixels from top border of * the containing (main window). or -1 if unspecified * * @since 4.0.0 */ public void setPositionY(int positionY) { setPositionY(positionY, true); } /** * Sets the distance of Window top border in pixels from top border of the * containing (main window). * * @param positionY * the Distance of Window top border in pixels from top border of * the containing (main window). or -1 if unspecified * @param repaintRequired * true if the window needs to be repainted, false otherwise * * @since 6.3.4 */ private void setPositionY(int positionY, boolean repaintRequired) { this.positionY = positionY; centerRequested = false; if (repaintRequired) { requestRepaint(); } } private static final Method WINDOW_CLOSE_METHOD; static { try { WINDOW_CLOSE_METHOD = CloseListener.class.getDeclaredMethod( "windowClose", new Class[] { CloseEvent.class }); } catch (final java.lang.NoSuchMethodException e) { // This should never happen throw new java.lang.RuntimeException( "Internal error, window close method not found"); } } public class CloseEvent extends Component.Event { /** * * @param source */ public CloseEvent(Component source) { super(source); } /** * Gets the Window. * * @return the window. */ public Window getWindow() { return (Window) getSource(); } } /** * An interface used for listening to Window close events. Add the * CloseListener to a browser level window or a sub window and * {@link CloseListener#windowClose(CloseEvent)} will be called whenever the * user closes the window. * ** Since Vaadin 6.5, removing a window using {@link #removeWindow(Window)} * fires the CloseListener. *
*/ public interface CloseListener extends Serializable { /** * Called when the user closes a window. Use * {@link CloseEvent#getWindow()} to get a reference to the * {@link Window} that was closed. * * @param e * Event containing */ public void windowClose(CloseEvent e); } /** * Adds a CloseListener to the window. * * For a sub window the CloseListener is fired when the user closes it * (clicks on the close button). * * For a browser level window the CloseListener is fired when the browser * level window is closed. Note that closing a browser level window does not * mean it will be destroyed. Also note that Opera does not send events like * all other browsers and therefore the close listener might not be called * if Opera is used. * ** Since Vaadin 6.5, removing windows using {@link #removeWindow(Window)} * does fire the CloseListener. *
* * @param listener * the CloseListener to add. */ public void addListener(CloseListener listener) { addListener(CloseEvent.class, listener, WINDOW_CLOSE_METHOD); } /** * Removes the CloseListener from the window. * ** For more information on CloseListeners see {@link CloseListener}. *
* * @param listener * the CloseListener to remove. */ public void removeListener(CloseListener listener) { removeListener(CloseEvent.class, listener, WINDOW_CLOSE_METHOD); } protected void fireClose() { fireEvent(new Window.CloseEvent(this)); } /** * Method for the resize event. */ private static final Method WINDOW_RESIZE_METHOD; static { try { WINDOW_RESIZE_METHOD = ResizeListener.class.getDeclaredMethod( "windowResized", new Class[] { ResizeEvent.class }); } catch (final java.lang.NoSuchMethodException e) { // This should never happen throw new java.lang.RuntimeException( "Internal error, window resized method not found"); } } /** * Resize events are fired whenever the client-side fires a resize-event * (e.g. the browser window is resized). The frequency may vary across * browsers. */ public class ResizeEvent extends Component.Event { /** * * @param source */ public ResizeEvent(Component source) { super(source); } /** * Get the window form which this event originated * * @return the window */ public Window getWindow() { return (Window) getSource(); } } /** * Listener for window resize events. * * @see com.vaadin.ui.Window.ResizeEvent */ public interface ResizeListener extends Serializable { public void windowResized(ResizeEvent e); } /** * Add a resize listener. * * @param listener */ public void addListener(ResizeListener listener) { addListener(ResizeEvent.class, listener, WINDOW_RESIZE_METHOD); } /** * Remove a resize listener. * * @param listener */ public void removeListener(ResizeListener listener) { removeListener(ResizeEvent.class, listener); } /** * Fire the resize event. */ protected void fireResize() { fireEvent(new ResizeEvent(this)); } private void attachWindow(Window w) { subwindows.add(w); w.setParent(this); requestRepaint(); } /** * Adds a window inside another window. * ** Adding windows inside another window creates "subwindows". These windows * should not be added to application directly and are not accessible * directly with any url. Addding windows implicitly sets their parents. *
* *
* Only one level of subwindows are supported. Thus you can add windows
* inside such windows whose parent is null
.
*
Window
is null
.
*/
public void addWindow(Window window) throws IllegalArgumentException,
NullPointerException {
if (window == null) {
throw new NullPointerException("Argument must not be null");
}
if (window.getApplication() != null) {
throw new IllegalArgumentException(
"Window was already added to application"
+ " - it can not be added to another window also.");
} else if (getParent() != null) {
throw new IllegalArgumentException(
"You can only add windows inside application-level windows.");
} else if (window.subwindows.size() > 0) {
throw new IllegalArgumentException(
"Only one level of subwindows are supported.");
}
attachWindow(window);
}
/**
* Remove the given subwindow from this window.
*
* Since Vaadin 6.5, {@link CloseListener}s are called also when explicitly
* removing a window by calling this method.
*
* Since Vaadin 6.5, returns a boolean indicating if the window was removed
* or not.
*
* @param window
* Window to be removed.
* @return true if the subwindow was removed, false otherwise
*/
public boolean removeWindow(Window window) {
if (!subwindows.remove(window)) {
// Window window is not a subwindow of this window.
return false;
}
window.setParent(null);
window.fireClose();
requestRepaint();
return true;
}
private Integer bringToFront = null;
/*
* This sequesnce is used to keep the right order of windows if multiple
* windows are brought to front in a single changeset. Incremented and saved
* by childwindows. If sequence is not used, the order is quite random
* (depends on the order getting to dirty list. e.g. which window got
* variable changes).
*/
private int bringToFrontSequence = 0;
/**
* If there are currently several sub windows visible, calling this method
* makes this window topmost.
* * This method can only be called if this window is a sub window and * connected a top level window. Else an illegal state exception is thrown. * Also if there are modal windows and this window is not modal, and illegal * state exception is thrown. *
* Note, this API works on sub windows only. Browsers can't reorder
* OS windows.
*/
public void bringToFront() {
Window parent = getParent();
if (parent == null) {
throw new IllegalStateException(
"Window must be attached to parent before calling bringToFront method.");
}
for (Window w : parent.getChildWindows()) {
if (w.isModal() && !isModal()) {
throw new IllegalStateException(
"There are modal windows currently visible, non-modal window cannot be brought to front.");
}
}
bringToFront = getParent().bringToFrontSequence++;
requestRepaint();
}
/**
* Get the set of all child windows.
*
* @return Set of child windows.
*/
public Set
* NOTE: This method has several issues as currently implemented.
* Please refer to http://dev.vaadin.com/ticket/8971 for details.
*/
public void center() {
centerRequested = true;
requestRepaint();
}
/**
* Shows a notification message on the middle of the window. The message
* automatically disappears ("humanized message").
*
* Care should be taken to to avoid XSS vulnerabilities as the caption is
* rendered as html.
*
* @see #showNotification(com.vaadin.ui.Window.Notification)
* @see Notification
*
* @param caption
* The message
*/
public void showNotification(String caption) {
addNotification(new Notification(caption));
}
/**
* Shows a notification message the window. The position and behavior of the
* message depends on the type, which is one of the basic types defined in
* {@link Notification}, for instance Notification.TYPE_WARNING_MESSAGE.
*
* Care should be taken to to avoid XSS vulnerabilities as the caption is
* rendered as html.
*
* @see #showNotification(com.vaadin.ui.Window.Notification)
* @see Notification
*
* @param caption
* The message
* @param type
* The message type
*/
public void showNotification(String caption, int type) {
addNotification(new Notification(caption, type));
}
/**
* Shows a notification consisting of a bigger caption and a smaller
* description on the middle of the window. The message automatically
* disappears ("humanized message").
*
* Care should be taken to to avoid XSS vulnerabilities as the caption and
* description are rendered as html.
*
* @see #showNotification(com.vaadin.ui.Window.Notification)
* @see Notification
*
* @param caption
* The caption of the message
* @param description
* The message description
*
*/
public void showNotification(String caption, String description) {
addNotification(new Notification(caption, description));
}
/**
* Shows a notification consisting of a bigger caption and a smaller
* description. The position and behavior of the message depends on the
* type, which is one of the basic types defined in {@link Notification},
* for instance Notification.TYPE_WARNING_MESSAGE.
*
* Care should be taken to to avoid XSS vulnerabilities as the caption and
* description are rendered as html.
*
* @see #showNotification(com.vaadin.ui.Window.Notification)
* @see Notification
*
* @param caption
* The caption of the message
* @param description
* The message description
* @param type
* The message type
*/
public void showNotification(String caption, String description, int type) {
addNotification(new Notification(caption, description, type));
}
/**
* Shows a notification consisting of a bigger caption and a smaller
* description. The position and behavior of the message depends on the
* type, which is one of the basic types defined in {@link Notification},
* for instance Notification.TYPE_WARNING_MESSAGE.
*
* Care should be taken to avoid XSS vulnerabilities if html content is
* allowed.
*
* @see #showNotification(com.vaadin.ui.Window.Notification)
* @see Notification
*
* @param caption
* The message caption
* @param description
* The message description
* @param type
* The type of message
* @param htmlContentAllowed
* Whether html in the caption and description should be
* displayed as html or as plain text
*/
public void showNotification(String caption, String description, int type,
boolean htmlContentAllowed) {
addNotification(new Notification(caption, description, type,
htmlContentAllowed));
}
/**
* Shows a notification message.
*
* @see Notification
* @see #showNotification(String)
* @see #showNotification(String, int)
* @see #showNotification(String, String)
* @see #showNotification(String, String, int)
*
* @param notification
* The notification message to show
*/
public void showNotification(Notification notification) {
addNotification(notification);
}
private void addNotification(Notification notification) {
if (notifications == null) {
notifications = new LinkedList
* The notification message can consist of several parts: caption,
* description and icon. It is usually used with only caption - one should
* be wary of filling the notification with too much information.
*
* The notification message tries to be as unobtrusive as possible, while
* still drawing needed attention. There are several basic types of messages
* that can be used in different situations:
*
* In addition to the basic pre-configured types, a Notification can also be
* configured to show up in a custom position, for a specified time (or
* until clicked), and with a custom stylename. An icon can also be added.
*
* This method allows one to inject javascript from the server to client. A
* client implementation is not required to implement this functionality,
* but currently all web-based clients do implement this.
*
* Executing javascript this way often leads to cross-browser compatibility
* issues and regressions that are hard to resolve. Use of this method
* should be avoided and instead it is recommended to create new widgets
* with GWT. For more info on creating own, reusable client-side widgets in
* Java, read the corresponding chapter in Book of Vaadin.
*
*
*
* Note that this shortcut only reacts while the window has focus, closing
* itself - if you want to close a subwindow from a parent window, use
* {@link #addAction(com.vaadin.event.Action)} of the parent window instead.
*
* @param keyCode
* the keycode for invoking the shortcut
* @param modifiers
* the (optional) modifiers for invoking the shortcut, null for
* none
*/
public void setCloseShortcut(int keyCode, int... modifiers) {
if (closeShortcut != null) {
removeAction(closeShortcut);
}
closeShortcut = new CloseShortcut(this, keyCode, modifiers);
addAction(closeShortcut);
}
/**
* Removes the keyboard shortcut previously set with
* {@link #setCloseShortcut(int, int...)}.
*/
public void removeCloseShortcut() {
if (closeShortcut != null) {
removeAction(closeShortcut);
closeShortcut = null;
}
}
/**
* A {@link ShortcutListener} specifically made to define a keyboard
* shortcut that closes the window.
*
*
*
*
*/
public static class CloseShortcut extends ShortcutListener {
protected Window window;
/**
* Creates a keyboard shortcut for closing the given window using the
* shorthand notation defined in {@link ShortcutAction}.
*
* @param window
* to be closed when the shortcut is invoked
* @param shorthandCaption
* the caption with shortcut keycode and modifiers indicated
*/
public CloseShortcut(Window window, String shorthandCaption) {
super(shorthandCaption);
this.window = window;
}
/**
* Creates a keyboard shortcut for closing the given window using the
* given {@link KeyCode} and {@link ModifierKey}s.
*
* @param window
* to be closed when the shortcut is invoked
* @param keyCode
* KeyCode to react to
* @param modifiers
* optional modifiers for shortcut
*/
public CloseShortcut(Window window, int keyCode, int... modifiers) {
super(null, keyCode, modifiers);
this.window = window;
}
/**
* Creates a keyboard shortcut for closing the given window using the
* given {@link KeyCode}.
*
* @param window
* to be closed when the shortcut is invoked
* @param keyCode
* KeyCode to react to
*/
public CloseShortcut(Window window, int keyCode) {
this(window, keyCode, null);
}
@Override
public void handleAction(Object sender, Object target) {
window.close();
}
}
/**
* Note, that focus/blur listeners in Window class are only supported by sub
* windows. Also note that Window is not considered focused if its contained
* component currently has focus.
*
* @see com.vaadin.event.FieldEvents.FocusNotifier#addListener(com.vaadin.event.FieldEvents.FocusListener)
*/
public void addListener(FocusListener listener) {
addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
FocusListener.focusMethod);
}
public void removeListener(FocusListener listener) {
removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
}
/**
* Note, that focus/blur listeners in Window class are only supported by sub
* windows. Also note that Window is not considered focused if its contained
* component currently has focus.
*
* @see com.vaadin.event.FieldEvents.BlurNotifier#addListener(com.vaadin.event.FieldEvents.BlurListener)
*/
public void addListener(BlurListener listener) {
addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
BlurListener.blurMethod);
}
public void removeListener(BlurListener listener) {
removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
}
/**
* {@inheritDoc}
*
* If the window is a sub-window focusing will cause the sub-window to be
* brought on top of other sub-windows on gain keyboard focus.
*/
@Override
public void focus() {
if (getParent() != null) {
/*
* When focusing a sub-window it basically means it should be
* brought to the front. Instead of just moving the keyboard focus
* we focus the window and bring it top-most.
*/
bringToFront();
} else {
super.focus();
}
}
/**
* Notifies the child components and subwindows that the window is attached
* to the application.
*/
@Override
public void attach() {
super.attach();
for (Window w : subwindows) {
w.attach();
}
}
/**
* Notifies the child components and subwindows that the window is detached
* from the application.
*/
@Override
public void detach() {
super.detach();
for (Window w : subwindows) {
w.detach();
}
}
/**
* Gets the height of the viewport area of the browser window where this
* window is displayed.
*
* @return the browser viewport height in pixels
*/
public int getBrowserWindowHeight() {
// Size only reported by VView -> data only available from application
// level window
if (getParent() != null) {
return (getParent()).getBrowserWindowHeight();
}
return browserWindowHeight;
}
/**
* Gets the width of the viewport area of the browser window where this
* window is displayed.
*
* @return the browser viewport width in pixels
*/
public int getBrowserWindowWidth() {
// Size only reported by VView -> data only available from application
// level window
if (getParent() != null) {
return (getParent()).getBrowserWindowWidth();
}
return browserWindowWidth;
}
}
* // within the window using helper
* subWindow.setCloseShortcut(KeyCode.ESCAPE, null);
*
* // or globally
* getWindow().addAction(new Window.CloseShortcut(subWindow, KeyCode.ESCAPE));
*
*