aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/com/itmill/toolkit/Application.java85
-rw-r--r--src/com/itmill/toolkit/ui/Window.java125
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;
- }
- }
/**
* <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);
}
}
}
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.
+ *
+ * <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);
+ }
+
}