From 5f5931cd7cf920198060c871c4500d1a8165847c Mon Sep 17 00:00:00 2001 From: Joonas Lehtinen Date: Fri, 24 Aug 2007 16:25:23 +0000 Subject: [PATCH] API changes and most of the base library implementation needed for new Windowing system. Implementation for gwt-adater (both client and server). svn changeset:2125/svn branch:trunk --- src/com/itmill/toolkit/Application.java | 85 +++++++++------- src/com/itmill/toolkit/ui/Window.java | 125 ++++++++++++++++++++++-- 2 files changed, 166 insertions(+), 44 deletions(-) diff --git a/src/com/itmill/toolkit/Application.java b/src/com/itmill/toolkit/Application.java index 6702de2037..b6a98ed541 100644 --- a/src/com/itmill/toolkit/Application.java +++ b/src/com/itmill/toolkit/Application.java @@ -192,28 +192,6 @@ public abstract class Application implements URIHandler, Terminal.ErrorListener private String logoutURL = null; private Focusable pendingFocus; - - /** - * Flag to indicate if first ajax request is sent - */ - private boolean ajaxInitSent = false; - - /** - * This function should only be called in AjaxApplicationManager to - * tell ajax engine (browser) that this is application restart. Returns - * true on first call, false on subsequent calls. - * - * TODO consider moving this to WebApplicationContext - * - * @return true if in ajax init state - */ - public boolean ajaxInit() { - if(this.ajaxInitSent) { - return false; - } else { - return this.ajaxInitSent = true; - } - } /** *

@@ -221,6 +199,18 @@ public abstract class Application implements URIHandler, Terminal.ErrorListener * not running or it does not contain a window corresponding to the name. *

* + *

Since version 5.0 all windows can be referenced by their names in + * url http://host:port/foo/bar/ where http://host:port/foo/ + * is the application url as returned by getURL() and bar is the name + * of the window.

+ * + *

One should note that this method can, as a side effect create new windows + * if needed by the application. This can be achieved by overriding the default + * implementation.

+ * + *

The method should return null if the window does not exists (and is not + * created as a side-effect) or if the application is not running anymore

. + * * @param name * the name of the window. * @return the window associated with the given URI or null @@ -245,14 +235,25 @@ public abstract class Application implements URIHandler, Terminal.ErrorListener * {@link com.itmill.toolkit.ui.Window#setApplication(Application)} method. *

* + *

+ * Note that all application-level windows can be accessed by their names in + * url http://host:port/foo/bar/ where + * http://host:port/foo/ is the application url as returned + * by getURL() and bar is the name of the window. Also note + * that not all windows should be added to application - one can also add + * windows inside other windows - these windows show as smaller windows + * inside those windows. + *

+ * * @param window - * the new Window to add. + * the new Window to add. If the name of the + * window is null, an unique name is + * automatically given for the window. * @throws IllegalArgumentException * if a window with the same name as the new window already * exists in the application. * @throws NullPointerException - * if the given Window or its name is - * null. + * if the given Window is null. */ public void addWindow(Window window) throws IllegalArgumentException, NullPointerException { @@ -295,6 +296,18 @@ public abstract class Application implements URIHandler, Terminal.ErrorListener windows.put(name, window); window.setApplication(this); + fireWindowAttachEvent(window); + + // If no main window is set, declare the window to be main window + if (getMainWindow() == null) + setMainWindow(window); + } + + /** Send information to all listeners about new Windows associated with this application. + * + * @param window + */ + private void fireWindowAttachEvent(Window window) { // Fires the window attach event if (windowAttachListeners != null) { Object[] listeners = windowAttachListeners.toArray(); @@ -303,10 +316,6 @@ public abstract class Application implements URIHandler, Terminal.ErrorListener ((WindowAttachListener) listeners[i]).windowAttached(event); } } - - // If no main window is set, declare the window to be main window - if (getMainWindow() == null) - setMainWindow(window); } /** @@ -329,13 +338,17 @@ public abstract class Application implements URIHandler, Terminal.ErrorListener if (window.getApplication() == this) window.setApplication(null); - // Fires the window detach event - if (windowDetachListeners != null) { - Object[] listeners = windowDetachListeners.toArray(); - WindowDetachEvent event = new WindowDetachEvent(window); - for (int i = 0; i < listeners.length; i++) { - ((WindowDetachListener) listeners[i]).windowDetached(event); - } + fireWindowDetachEvent(window); + } + } + + private void fireWindowDetachEvent(Window window) { + // Fires the window detach event + if (windowDetachListeners != null) { + Object[] listeners = windowDetachListeners.toArray(); + WindowDetachEvent event = new WindowDetachEvent(window); + for (int i = 0; i < listeners.length; i++) { + ((WindowDetachListener) listeners[i]).windowDetached(event); } } } diff --git a/src/com/itmill/toolkit/ui/Window.java b/src/com/itmill/toolkit/ui/Window.java index d458ea874a..890ae5c410 100644 --- a/src/com/itmill/toolkit/ui/Window.java +++ b/src/com/itmill/toolkit/ui/Window.java @@ -29,6 +29,8 @@ package com.itmill.toolkit.ui; import com.itmill.toolkit.Application; +import com.itmill.toolkit.Application.WindowAttachEvent; +import com.itmill.toolkit.Application.WindowAttachListener; import com.itmill.toolkit.terminal.DownloadStream; import com.itmill.toolkit.terminal.PaintException; import com.itmill.toolkit.terminal.PaintTarget; @@ -42,10 +44,13 @@ import java.lang.ref.WeakReference; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.Map; import java.util.Iterator; +import java.util.Set; /** * Application window component. @@ -91,6 +96,9 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * List of parameter handlers for this window. */ private LinkedList parameterHandlerList = null; + + /** Set of subwindows */ + private HashSet subwindows = new HashSet(); /** * Explicitly specified theme of this window. If null, application theme is @@ -222,12 +230,24 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * @return the parent application of the component. */ public final Application getApplication() { + if (getParent() == null) return this.application; + return ((Window)getParent()).getApplication(); } /** - * Getter for property parent. Parent is the visual parent of a component. - * Each component can belong to only one ComponentContainer at time. + * Getter for property parent. + * + *

+ * Parent is the visual parent of a component. Each component can belong to + * only one ComponentContainer at time. + *

+ * + *

+ * For windows attached directly to the application, parent is + * null. For windows inside other windows, parent is the + * window containing this window. + *

* * @return the Value of property parent. */ @@ -236,15 +256,18 @@ public class Window extends Panel implements URIHandler, ParameterHandler { } /** - * Setter for property parent. Parent is the visual parent of a component. - * This is mostly called by containers add method. Setting parent is not - * allowed for the window, and thus this call should newer be called. + * Setter for property parent. + * + *

+ * Parent is the visual parent of a component. This is mostly called by + * containers add method and should not be called directly + *

* * @param parent * the New value of property parent. */ public void setParent(Component parent) { - throw new RuntimeException("Setting parent for Window is not allowed"); + super.setParent(parent); } /** @@ -265,6 +288,8 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * the URI handler to add. */ public void addURIHandler(URIHandler handler) { + // TODO Subwindow support + if (uriHandlerList == null) uriHandlerList = new LinkedList(); synchronized (uriHandlerList) { @@ -280,6 +305,8 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * the URI handler to remove. */ public void removeURIHandler(URIHandler handler) { + // TODO Subwindow support + if (handler == null || uriHandlerList == null) return; synchronized (uriHandlerList) { @@ -296,6 +323,8 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * @param relativeUri */ public DownloadStream handleURI(URL context, String relativeUri) { + // TODO Subwindow support + DownloadStream result = null; if (uriHandlerList != null) { Object[] handlers; @@ -326,6 +355,7 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * the parameter handler to add. */ public void addParameterHandler(ParameterHandler handler) { + // TODO Subwindow support if (parameterHandlerList == null) parameterHandlerList = new LinkedList(); synchronized (parameterHandlerList) { @@ -341,6 +371,7 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * the parameter handler to remove. */ public void removeParameterHandler(ParameterHandler handler) { + // TODO Subwindow support if (handler == null || parameterHandlerList == null) return; synchronized (parameterHandlerList) { @@ -367,6 +398,8 @@ public class Window extends Panel implements URIHandler, ParameterHandler { /** * Gets the theme for this window. * + *

Subwindows do not support themes and thus return theme used by the parent

+ * * @return the Name of the theme used in window. If the theme for this * individual window is not explicitly set, the application theme is * used instead. If application is not assigned the @@ -374,6 +407,7 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * returned */ public String getTheme() { + if (getParent() != null) return ((Window) getParent()).getTheme(); if (theme != null) return theme; if ((application != null) && (application.getTheme() != null)) @@ -386,10 +420,12 @@ public class Window extends Panel implements URIHandler, ParameterHandler { /** * Sets the theme for this window. * + * Setting theme for subwindows is not supported. * @param theme * the New theme for this window. Null implies the default theme. */ public void setTheme(String theme) { + if (getParent() != null) throw new UnsupportedOperationException("Setting theme for sub-windws is not supported."); this.theme = theme; requestRepaint(); } @@ -406,10 +442,12 @@ public class Window extends Panel implements URIHandler, ParameterHandler { throws PaintException { // Sets the window name - target.addAttribute("name", getName()); + String name = getName(); + target.addAttribute("name", name == null ? "" : name); // Sets the window theme - target.addAttribute("theme", getTheme()); + String theme = getTheme(); + target.addAttribute("theme", theme == null ? "" : theme); // Marks the main window if (getApplication() != null @@ -441,6 +479,12 @@ public class Window extends Panel implements URIHandler, ParameterHandler { + this.focusedComponent.getFocusableId()); else target.addVariable(this, "focused", ""); + + // Paint subwindows + for (Iterator i=subwindows.iterator(); i.hasNext();) { + Window w = (Window) i.next(); + w.paint(target); + } } @@ -527,6 +571,18 @@ public class Window extends Panel implements URIHandler, ParameterHandler { /** * Gets the unique name of the window that indentifies it on the terminal. * + *

+ * Name identifies the URL used to access application-level windows, but is + * not used for windows inside other windows. all application-level windows + * can be accessed by their names in url + * http://host:port/foo/bar/ where + * http://host:port/foo/ is the application url as returned + * by getURL() and bar is the name of the window. Also note + * that not all windows should be added to application - one can also add + * windows inside other windows - these windows show as smaller windows + * inside those windows. + *

+ * * @return the Name of the Window. */ public String getName() { @@ -950,4 +1006,57 @@ public class Window extends Panel implements URIHandler, ParameterHandler { fireEvent(new Window.CloseEvent(this)); } + /** + * Adds a new 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. + *

+ * + * @param window + * @throws IllegalArgumentException + * if a window is added inside non-application level window. + * @throws NullPointerException + * if the given Window is null. + */ + public void addWindow(Window window) throws IllegalArgumentException, + NullPointerException { + + if (getParent() != null) + throw new IllegalArgumentException( + "You can only add windows inside application-level windows"); + + if (window == null) throw new NullPointerException("Argument must not be null"); + + subwindows.add(window); + window.setParent(this); + requestRepaint(); + } + + /** Remove the given subwindow from this window. + * + * @param window Window to be removed. + */ + public void removeWindow(Window window) { + subwindows.remove(window); + window.setParent(null); + requestRepaint(); + + } + + /** Get the set of all child windows. + * + * @return Set of child windows. + */ + public Set getChildWindows() { + return Collections.unmodifiableSet(subwindows); + } + } -- 2.39.5