]> source.dussan.org Git - vaadin-framework.git/commitdiff
API changes and most of the base library implementation needed for new Windowing...
authorJoonas Lehtinen <joonas.lehtinen@itmill.com>
Fri, 24 Aug 2007 16:25:23 +0000 (16:25 +0000)
committerJoonas Lehtinen <joonas.lehtinen@itmill.com>
Fri, 24 Aug 2007 16:25:23 +0000 (16:25 +0000)
svn changeset:2125/svn branch:trunk

src/com/itmill/toolkit/Application.java
src/com/itmill/toolkit/ui/Window.java

index 6702de20370daa00a0506dc032a931c4bab37945..b6a98ed541e1c89345abd06e50d2cb6b051511ba 100644 (file)
@@ -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;
-               }
-       }
 
        /**
         * <p>
@@ -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.
         * </p>
         * 
+        * <p>Since version 5.0 all windows can be referenced by their names in 
+        * url <code>http://host:port/foo/bar/</code> where <code>http://host:port/foo/</code>
+        * is the application url as returned by getURL() and <code>bar</code> is the name 
+        * of the window.</p>
+        * 
+        * <p>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.</p>
+        * 
+        * <p>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</p>.
+        * 
         * @param name
         *            the name of the window.
         * @return the window associated with the given URI or <code>null</code>
@@ -245,14 +235,25 @@ public abstract class Application implements URIHandler, Terminal.ErrorListener
         * {@link com.itmill.toolkit.ui.Window#setApplication(Application)} method.
         * </p>
         * 
+        * <p>
+        * Note that all application-level windows can be accessed by their names in
+        * url <code>http://host:port/foo/bar/</code> where
+        * <code>http://host:port/foo/</code> is the application url as returned
+        * by getURL() and <code>bar</code> 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.
+        * </p>
+        * 
         * @param window
-        *            the new <code>Window</code> to add.
+        *            the new <code>Window</code> to add. If the name of the
+        *            window is <code>null</code>, 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 <code>Window</code> or its name is
-        *             <code>null</code>.
+        *             if the given <code>Window</code> is <code>null</code>.
         */
        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);
                        }
                }
        }
index d458ea874ab0cd070f45dcf78dfe0603444d1d13..890ae5c41070e2d84aff1ceebc7b4ac2dc0a3329 100644 (file)
@@ -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.
+        * 
+        * <p>
+        * Parent is the visual parent of a component. Each component can belong to
+        * only one ComponentContainer at time.
+        * </p>
+        * 
+        * <p>
+        * For windows attached directly to the application, parent is
+        * <code>null</code>. For windows inside other windows, parent is the
+        * window containing this window.
+        * </p>
         * 
         * @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.
+        * 
+        * <p>
+        * Parent is the visual parent of a component. This is mostly called by
+        * containers add method and should not be called directly
+        * </p>
         * 
         * @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.
         * 
+        * <p>Subwindows do not support themes and thus return theme used by the parent</p>
+        * 
         * @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.
         * 
+        * <p>
+        * 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
+        * <code>http://host:port/foo/bar/</code> where
+        * <code>http://host:port/foo/</code> is the application url as returned
+        * by getURL() and <code>bar</code> 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.
+        * </p>
+        * 
         * @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.
+        * 
+        * <p>
+        * 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.
+        * </p>
+        * 
+        * <p>
+        * Only one level of subwindows are supported. Thus you can add windows
+        * inside such windows whose parent is <code>null</code>.
+        * </p>
+        * 
+        * @param window
+        * @throws IllegalArgumentException
+        *             if a window is added inside non-application level window.
+        * @throws NullPointerException
+        *             if the given <code>Window</code> is <code>null</code>.
+        */
+       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);
+       }
+
 }