]> source.dussan.org Git - vaadin-framework.git/commitdiff
Removed the Root interface and renamed DefaultRoot class to Root
authorLeif Åstrand <leif@vaadin.com>
Thu, 3 Nov 2011 12:49:56 +0000 (14:49 +0200)
committerLeif Åstrand <leif@vaadin.com>
Thu, 3 Nov 2011 12:49:56 +0000 (14:49 +0200)
Also moved the scrollTo functionality from Window to Root as the change
in the Root class hierachy caused the functionality to not work in
Window.

src/com/vaadin/RootTestApplication.java
src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
src/com/vaadin/ui/DefaultRoot.java [deleted file]
src/com/vaadin/ui/Root.java
src/com/vaadin/ui/Window.java

index bf5ec99b0022ec1273dca85e11c192afa5072f9f..8e9bfacfa279e134927fe6872873dde4feca7a2c 100644 (file)
@@ -2,11 +2,10 @@ package com.vaadin;
 
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
-import com.vaadin.ui.DefaultRoot;
 import com.vaadin.ui.Root;
 
 public class RootTestApplication extends Application {
-    private final Root root = new DefaultRoot(new Button("Roots, bloody roots",
+    private final Root root = new Root(new Button("Roots, bloody roots",
             new Button.ClickListener() {
                 public void buttonClick(ClickEvent event) {
                     root.executeJavaScript("window.alert(\"Here\");");
index 0d092ae29fc8fe54ecf9df21200123f30a43ca22..d96eee1bf27daba3fb751fcca0ae5ccdf1b535dd 100644 (file)
@@ -317,7 +317,7 @@ public class ApplicationConfiguration implements EntryPoint {
                     unknownComponents = new HashMap<String, String>();
                 }
                 unknownComponents.put("" + value, key);
-            } else if (key == "com.vaadin.ui.DefaultRoot") {
+            } else if (key == "com.vaadin.ui.Root") {
                 windowId = "" + value;
             }
         }
@@ -361,7 +361,7 @@ public class ApplicationConfiguration implements EntryPoint {
                 cmd.execute();
             }
             callbacks.clear();
-        } else if(widgetsLoading == 0 && deferredWidgetLoader != null) {
+        } else if (widgetsLoading == 0 && deferredWidgetLoader != null) {
             deferredWidgetLoader.trigger();
         }
 
@@ -377,17 +377,17 @@ public class ApplicationConfiguration implements EntryPoint {
         int communicationFree = 0;
         int nextWidgetIndex = 0;
         private boolean pending;
-        
+
         public DeferredWidgetLoader() {
             schedule(5000);
         }
 
         public void trigger() {
-            if(!pending) {
+            if (!pending) {
                 schedule(FREE_CHECK_TIMEOUT);
             }
         }
-        
+
         @Override
         public void schedule(int delayMillis) {
             super.schedule(delayMillis);
@@ -438,9 +438,9 @@ public class ApplicationConfiguration implements EntryPoint {
             return communicationFree < FREE_LIMIT;
         }
     }
-    
+
     private static DeferredWidgetLoader deferredWidgetLoader;
-   
+
     public void onModuleLoad() {
 
         // Enable IE6 Background image caching
diff --git a/src/com/vaadin/ui/DefaultRoot.java b/src/com/vaadin/ui/DefaultRoot.java
deleted file mode 100644 (file)
index 7adf5a8..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-package com.vaadin.ui;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Terminal;
-import com.vaadin.terminal.gwt.client.ui.VView;
-import com.vaadin.ui.Window.CloseListener;
-import com.vaadin.ui.Window.Notification;
-
-@ClientWidget(VView.class)
-public class DefaultRoot extends AbstractComponentContainer implements Root {
-    private final Component content;
-    private Terminal terminal;
-    private Application application;
-
-    /**
-     * A list of notifications that are waiting to be sent to the client.
-     * Cleared (set to null) when the notifications have been sent.
-     */
-    private List<Notification> notifications;
-
-    /**
-     * A list of javascript commands that are waiting to be sent to the client.
-     * Cleared (set to null) when the commands have been sent.
-     */
-    private List<String> jsExecQueue = null;
-
-    /**
-     * List of windows in this root.
-     */
-    private final LinkedHashSet<Window> windows = new LinkedHashSet<Window>();
-
-    public DefaultRoot(Component content) {
-        this.content = content;
-        addComponent(content);
-    }
-
-    @Override
-    public Root getRoot() {
-        return this;
-    }
-
-    public void replaceComponent(Component oldComponent, Component newComponent) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Application getApplication() {
-        return application;
-    }
-
-    @Override
-    public void paintContent(PaintTarget target) throws PaintException {
-        content.paint(target);
-
-        // Paint subwindows
-        for (final Iterator<Window> i = windows.iterator(); i.hasNext();) {
-            final Window w = i.next();
-            w.paint(target);
-        }
-
-        // Paint notifications
-        if (notifications != null) {
-            target.startTag("notifications");
-            for (final Iterator<Notification> it = notifications.iterator(); it
-                    .hasNext();) {
-                final Notification n = it.next();
-                target.startTag("notification");
-                if (n.getCaption() != null) {
-                    target.addAttribute("caption", n.getCaption());
-                }
-                if (n.getDescription() != null) {
-                    target.addAttribute("message", n.getDescription());
-                }
-                if (n.getIcon() != null) {
-                    target.addAttribute("icon", n.getIcon());
-                }
-                if (!n.isHtmlContentAllowed()) {
-                    target.addAttribute(
-                            VView.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED, true);
-                }
-                target.addAttribute("position", n.getPosition());
-                target.addAttribute("delay", n.getDelayMsec());
-                if (n.getStyleName() != null) {
-                    target.addAttribute("style", n.getStyleName());
-                }
-                target.endTag("notification");
-            }
-            target.endTag("notifications");
-            notifications = null;
-        }
-
-        // Add executable javascripts if needed
-        if (jsExecQueue != null) {
-            for (String script : jsExecQueue) {
-                target.startTag("execJS");
-                target.addAttribute("script", script);
-                target.endTag("execJS");
-            }
-            jsExecQueue = null;
-        }
-
-        if (pendingFocus != null) {
-            // ensure focused component is still attached to this main window
-            if (pendingFocus.getRoot() == this
-                    || (pendingFocus.getRoot() != null && pendingFocus
-                            .getRoot().getParent() == this)) {
-                target.addAttribute("focused", pendingFocus);
-            }
-            pendingFocus = null;
-        }
-    }
-
-    public Iterator<Component> getComponentIterator() {
-        return Collections.singleton(content).iterator();
-    }
-
-    public String getName() {
-        return "";
-    }
-
-    public Terminal getTerminal() {
-        return terminal;
-    }
-
-    public void setTerminal(Terminal terminal) {
-        this.terminal = terminal;
-    }
-
-    public void setApplication(Application application) {
-        if (application == null) {
-            throw new NullPointerException("application");
-        } else if (this.application != null) {
-            throw new IllegalStateException("Application has already been set");
-        } else {
-            this.application = application;
-        }
-    }
-
-    /**
-     * Adds a window inside this root.
-     * 
-     * <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 (window == null) {
-            throw new NullPointerException("Argument must not be null");
-        }
-
-        if (window.getApplication() != null) {
-            throw new IllegalArgumentException(
-                    "Window is already attached to an application.");
-        }
-
-        attachWindow(window);
-    }
-
-    private void attachWindow(Window w) {
-        windows.add(w);
-        w.setParent(this);
-        requestRepaint();
-    }
-
-    /**
-     * Remove the given subwindow from this root.
-     * 
-     * 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 (!windows.remove(window)) {
-            // Window window is not a subwindow of this root.
-            return false;
-        }
-        window.setParent(null);
-        window.fireClose();
-        requestRepaint();
-
-        return true;
-    }
-
-    public Collection<Window> getWindows() {
-        return Collections.unmodifiableCollection(windows);
-    }
-
-    public int getTabIndex() {
-        throw new IllegalStateException("Tab index not defined for roots");
-    }
-
-    public void setTabIndex(int tabIndex) {
-        throw new IllegalStateException("Tab index not defined for roots");
-    }
-
-    @Override
-    public void focus() {
-        super.focus();
-    }
-
-    /**
-     * Component that should be focused after the next repaint. Null if no focus
-     * change should take place.
-     */
-    private Focusable pendingFocus;
-
-    /**
-     * This method is used by Component.Focusable objects to request focus to
-     * themselves. Focus renders must be handled at window level (instead of
-     * Component.Focusable) due we want the last focused component to be focused
-     * in client too. Not the one that is rendered last (the case we'd get if
-     * implemented in Focusable only).
-     * 
-     * To focus component from Vaadin application, use Focusable.focus(). See
-     * {@link Focusable}.
-     * 
-     * @param focusable
-     *            to be focused on next paint
-     */
-    public void setFocusedComponent(Focusable focusable) {
-        pendingFocus = focusable;
-        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<Notification>();
-        }
-        notifications.add(notification);
-        requestRepaint();
-    }
-
-    /**
-     * Executes JavaScript in this root.
-     * 
-     * <p>
-     * 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.
-     * </p>
-     * 
-     * <p>
-     * 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.
-     * </p>
-     * 
-     * @param script
-     *            JavaScript snippet that will be executed.
-     */
-    public void executeJavaScript(String script) {
-        if (jsExecQueue == null) {
-            jsExecQueue = new ArrayList<String>();
-        }
-
-        jsExecQueue.add(script);
-
-        requestRepaint();
-    }
-}
index 30659d98e3bed89be18518bfe7a2e3688fd5f9e8..0358cba4e8f49ff651e1243192fcb3dafbf7a0e2 100644 (file)
 package com.vaadin.ui;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
 
 import com.vaadin.Application;
+import com.vaadin.terminal.PaintException;
+import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Terminal;
+import com.vaadin.terminal.gwt.client.ui.VView;
+import com.vaadin.ui.Window.CloseListener;
 import com.vaadin.ui.Window.Notification;
 
-public interface Root extends Component, com.vaadin.ui.Component.Focusable {
+@ClientWidget(VView.class)
+public class Root extends AbstractComponentContainer {
+    private final Component content;
+    private Terminal terminal;
+    private Application application;
 
     /**
-     * Sets the application this root is attached to.
+     * A list of notifications that are waiting to be sent to the client.
+     * Cleared (set to null) when the notifications have been sent.
+     */
+    private List<Notification> notifications;
+
+    /**
+     * A list of javascript commands that are waiting to be sent to the client.
+     * Cleared (set to null) when the commands have been sent.
+     */
+    private List<String> jsExecQueue = null;
+
+    /**
+     * List of windows in this root.
+     */
+    private final LinkedHashSet<Window> windows = new LinkedHashSet<Window>();
+
+    /**
+     * The component that should be scrolled into view after the next repaint.
+     * Null if nothing should be scrolled into view.
+     */
+    private Component scrollIntoView;
+
+    public Root(Component content) {
+        this.content = content;
+        addComponent(content);
+    }
+
+    @Override
+    public Root getRoot() {
+        return this;
+    }
+
+    public void replaceComponent(Component oldComponent, Component newComponent) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Application getApplication() {
+        return application;
+    }
+
+    @Override
+    public void paintContent(PaintTarget target) throws PaintException {
+        content.paint(target);
+
+        // Paint subwindows
+        for (final Iterator<Window> i = windows.iterator(); i.hasNext();) {
+            final Window w = i.next();
+            w.paint(target);
+        }
+
+        // Paint notifications
+        if (notifications != null) {
+            target.startTag("notifications");
+            for (final Iterator<Notification> it = notifications.iterator(); it
+                    .hasNext();) {
+                final Notification n = it.next();
+                target.startTag("notification");
+                if (n.getCaption() != null) {
+                    target.addAttribute("caption", n.getCaption());
+                }
+                if (n.getDescription() != null) {
+                    target.addAttribute("message", n.getDescription());
+                }
+                if (n.getIcon() != null) {
+                    target.addAttribute("icon", n.getIcon());
+                }
+                if (!n.isHtmlContentAllowed()) {
+                    target.addAttribute(
+                            VView.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED, true);
+                }
+                target.addAttribute("position", n.getPosition());
+                target.addAttribute("delay", n.getDelayMsec());
+                if (n.getStyleName() != null) {
+                    target.addAttribute("style", n.getStyleName());
+                }
+                target.endTag("notification");
+            }
+            target.endTag("notifications");
+            notifications = null;
+        }
+
+        // Add executable javascripts if needed
+        if (jsExecQueue != null) {
+            for (String script : jsExecQueue) {
+                target.startTag("execJS");
+                target.addAttribute("script", script);
+                target.endTag("execJS");
+            }
+            jsExecQueue = null;
+        }
+
+        if (scrollIntoView != null) {
+            target.addAttribute("scrollTo", scrollIntoView);
+            scrollIntoView = null;
+        }
+
+        if (pendingFocus != null) {
+            // ensure focused component is still attached to this main window
+            if (pendingFocus.getRoot() == this
+                    || (pendingFocus.getRoot() != null && pendingFocus
+                            .getRoot().getParent() == this)) {
+                target.addAttribute("focused", pendingFocus);
+            }
+            pendingFocus = null;
+        }
+    }
+
+    public Iterator<Component> getComponentIterator() {
+        return Collections.singleton(content).iterator();
+    }
+
+    public String getName() {
+        return "";
+    }
+
+    public Terminal getTerminal() {
+        return terminal;
+    }
+
+    public void setTerminal(Terminal terminal) {
+        this.terminal = terminal;
+    }
+
+    public void setApplication(Application application) {
+        if (application == null) {
+            throw new NullPointerException("application");
+        } else if (this.application != null) {
+            throw new IllegalStateException("Application has already been set");
+        } else {
+            this.application = application;
+        }
+    }
+
+    /**
+     * Adds a window inside this root.
      * 
      * <p>
-     * This method is called by the framework and should not be called directly
-     * from application code.
+     * 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>
      * 
-     * @param application
-     *            the application the root is attached to
+     * <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 setApplication(Application application);
+    public void addWindow(Window window) throws IllegalArgumentException,
+            NullPointerException {
 
-    // TODO is this required?
-    public String getName();
+        if (window == null) {
+            throw new NullPointerException("Argument must not be null");
+        }
 
-    public Terminal getTerminal();
+        if (window.getApplication() != null) {
+            throw new IllegalArgumentException(
+                    "Window is already attached to an application.");
+        }
 
-    public void setTerminal(Terminal terminal);
+        attachWindow(window);
+    }
 
-    public void addWindow(Window window);
+    private void attachWindow(Window w) {
+        windows.add(w);
+        w.setParent(this);
+        requestRepaint();
+    }
 
-    public boolean removeWindow(Window window);
+    /**
+     * Remove the given subwindow from this root.
+     * 
+     * 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 (!windows.remove(window)) {
+            // Window window is not a subwindow of this root.
+            return false;
+        }
+        window.setParent(null);
+        window.fireClose();
+        requestRepaint();
 
-    public Collection<Window> getWindows();
+        return true;
+    }
 
-    public void setFocusedComponent(Focusable focusable);
+    public Collection<Window> getWindows() {
+        return Collections.unmodifiableCollection(windows);
+    }
 
-    public void showNotification(Notification notification);
+    @Override
+    public void focus() {
+        super.focus();
+    }
 
-    public void showNotification(String caption, String description,
-            int type, boolean htmlContentAllowed);
+    /**
+     * Component that should be focused after the next repaint. Null if no focus
+     * change should take place.
+     */
+    private Focusable pendingFocus;
 
-    public void showNotification(String caption, String description,
-            int type);
+    /**
+     * This method is used by Component.Focusable objects to request focus to
+     * themselves. Focus renders must be handled at window level (instead of
+     * Component.Focusable) due we want the last focused component to be focused
+     * in client too. Not the one that is rendered last (the case we'd get if
+     * implemented in Focusable only).
+     * 
+     * To focus component from Vaadin application, use Focusable.focus(). See
+     * {@link Focusable}.
+     * 
+     * @param focusable
+     *            to be focused on next paint
+     */
+    public void setFocusedComponent(Focusable focusable) {
+        pendingFocus = focusable;
+        requestRepaint();
+    }
 
-    public void showNotification(String caption, String description);
+    /**
+     * 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));
+    }
 
-    public void showNotification(String caption, int type);
+    /**
+     * 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<Notification>();
+        }
+        notifications.add(notification);
+        requestRepaint();
+    }
+
+    /**
+     * Executes JavaScript in this root.
+     * 
+     * <p>
+     * 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.
+     * </p>
+     * 
+     * <p>
+     * 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.
+     * </p>
+     * 
+     * @param script
+     *            JavaScript snippet that will be executed.
+     */
+    public void executeJavaScript(String script) {
+        if (jsExecQueue == null) {
+            jsExecQueue = new ArrayList<String>();
+        }
 
-    public void showNotification(String caption);
+        jsExecQueue.add(script);
 
-    public void executeJavaScript(String script);
+        requestRepaint();
+    }
 
+    /**
+     * Scrolls any component between the component and root to a suitable
+     * position so the component is visible to the user. The given component
+     * must belong to this root.
+     * 
+     * @param component
+     *            the component to be scrolled into view
+     * @throws IllegalArgumentException
+     *             if {@code component} does not belong to this root
+     */
+    public void scrollIntoView(Component component)
+            throws IllegalArgumentException {
+        if (component.getRoot() != this) {
+            throw new IllegalArgumentException(
+                    "The component where to scroll must belong to this root.");
+        }
+        scrollIntoView = component;
+        requestRepaint();
+    }
 }
index 4c72ecf844e9ff928a183f1524edbfd1078d7f87..f62ab28c85e428a1493c8a5f2b9cdf6db194dfef 100644 (file)
@@ -163,12 +163,6 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier {
      */
     private boolean resizeLazy = false;
 
-    /**
-     * The component that should be scrolled into view after the next repaint.
-     * Null if nothing should be scrolled into view.
-     */
-    private Component scrollIntoView;
-
     /**
      * Creates a new unnamed window with a default layout.
      */
@@ -431,11 +425,6 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier {
             centerRequested = false;
         }
 
-        if (scrollIntoView != null) {
-            target.addAttribute("scrollTo", scrollIntoView);
-            scrollIntoView = null;
-        }
-
         // Marks the main window
         // if (getApplication() != null
         // && this == getApplication().getMainWindow()) {
@@ -475,26 +464,6 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier {
 
     /* ********************************************************************* */
 
-    /**
-     * Scrolls any component between the component and window to a suitable
-     * position so the component is visible to the user. The given component
-     * must be inside this window.
-     * 
-     * @param component
-     *            the component to be scrolled into view
-     * @throws IllegalArgumentException
-     *             if {@code component} is not inside this window
-     */
-    public void scrollIntoView(Component component)
-            throws IllegalArgumentException {
-        if (component.getRoot() != this) {
-            throw new IllegalArgumentException(
-                    "The component where to scroll must be inside this window.");
-        }
-        scrollIntoView = component;
-        requestRepaint();
-    }
-
     // /**
     // * Opens the given resource in this window. The contents of this Window is
     // * replaced by the {@code Resource}.