]> source.dussan.org Git - vaadin-framework.git/commitdiff
steps toward simpler widgetset creation. Still needs a lot of cleaning and refining.
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Fri, 25 Sep 2009 12:07:09 +0000 (12:07 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Fri, 25 Sep 2009 12:07:09 +0000 (12:07 +0000)
svn changeset:8930/svn branch:2009-09-widget-packaging_3332

71 files changed:
build/build.xml
src/com/vaadin/demo/colorpicker/ColorPicker.java
src/com/vaadin/demo/colorpicker/gwt/ColorPickerWidgetSet.gwt.xml
src/com/vaadin/demo/colorpicker/gwt/client/ColorPickerWidgetSet.java [deleted file]
src/com/vaadin/demo/coverflow/Coverflow.java
src/com/vaadin/demo/coverflow/gwt/CoverflowWidgetSet.gwt.xml
src/com/vaadin/demo/coverflow/gwt/client/CoverflowWidgetSet.java [deleted file]
src/com/vaadin/demo/reservation/CalendarField.java
src/com/vaadin/demo/reservation/GoogleMap.java
src/com/vaadin/demo/reservation/gwt/ReservationWidgetSet.gwt.xml
src/com/vaadin/demo/reservation/gwt/client/ReservationWidgetSet.java [deleted file]
src/com/vaadin/demo/sampler/ActiveLink.java
src/com/vaadin/demo/sampler/CodeLabel.java
src/com/vaadin/demo/sampler/GoogleAnalytics.java
src/com/vaadin/demo/sampler/gwt/SamplerWidgetSet.gwt.xml
src/com/vaadin/demo/sampler/gwt/client/SamplerWidgetSet.java [deleted file]
src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml
src/com/vaadin/portal/gwt/client/PortalDefaultWidgetSet.java [deleted file]
src/com/vaadin/terminal/PaintTarget.java
src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
src/com/vaadin/terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml [deleted file]
src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
src/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java
src/com/vaadin/terminal/gwt/client/VDebugConsole.java
src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java
src/com/vaadin/terminal/gwt/client/WidgetMap.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/WidgetSet.java
src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java
src/com/vaadin/terminal/gwt/rebind/ClassPathExplorer.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/rebind/WidgetMapGenerator.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/server/CommunicationManager.java
src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java
src/com/vaadin/ui/AbsoluteLayout.java
src/com/vaadin/ui/AbstractComponent.java
src/com/vaadin/ui/Accordion.java
src/com/vaadin/ui/Button.java
src/com/vaadin/ui/CheckBox.java
src/com/vaadin/ui/ClientWidget.java [new file with mode: 0644]
src/com/vaadin/ui/CssLayout.java
src/com/vaadin/ui/CustomComponent.java
src/com/vaadin/ui/CustomLayout.java
src/com/vaadin/ui/DateField.java
src/com/vaadin/ui/Embedded.java
src/com/vaadin/ui/Form.java
src/com/vaadin/ui/FormLayout.java
src/com/vaadin/ui/GridLayout.java
src/com/vaadin/ui/HorizontalLayout.java
src/com/vaadin/ui/Label.java
src/com/vaadin/ui/Link.java
src/com/vaadin/ui/ListSelect.java
src/com/vaadin/ui/MenuBar.java
src/com/vaadin/ui/NativeSelect.java
src/com/vaadin/ui/OptionGroup.java
src/com/vaadin/ui/OrderedLayout.java
src/com/vaadin/ui/Panel.java
src/com/vaadin/ui/PopupView.java
src/com/vaadin/ui/ProgressIndicator.java
src/com/vaadin/ui/RichTextArea.java
src/com/vaadin/ui/Select.java
src/com/vaadin/ui/Slider.java
src/com/vaadin/ui/SplitPanel.java
src/com/vaadin/ui/TabSheet.java
src/com/vaadin/ui/Table.java
src/com/vaadin/ui/TextField.java
src/com/vaadin/ui/Tree.java
src/com/vaadin/ui/TwinColSelect.java
src/com/vaadin/ui/Upload.java
src/com/vaadin/ui/UriFragmentUtility.java
src/com/vaadin/ui/VerticalLayout.java
src/com/vaadin/ui/Window.java

index e69ebed14d74c9c705989f045ceef76dce31441e..ee73d898dbdffb07551f76edf7b8fc60d974ceee 100644 (file)
                        <classpath>
                                <pathelement location="${gwt-dir}/${platform}/gwt-user.jar" />
                                <pathelement location="${gwt-dir}/${platform}/${lib-gwt-dev}" />
+                               <pathelement location="build/classes" />
                                <pathelement location="${result-path}/src" />
                        </classpath>
                </java>
                                <pathelement location="${gwt-dir}/${platform}/gwt-user.jar" />
                                <pathelement location="${gwt-dir}/${platform}/${lib-gwt-dev}" />
                                <pathelement location="${result-path}/src" />
+                               <pathelement location="build/classes" />
                        </classpath>
                </java>
                <antcall target="remove-widgetset-gwt-tmp"/>
                                <pathelement location="${googlemaps-jar}" />
                                <!-- demo widgetset sources -->
                                <pathelement path="${output-dir}/WebContent/WEB-INF/src" />
+                               <pathelement location="build/classes" />
                        </classpath>
                </java>
                <antcall target="remove-widgetset-gwt-tmp"/>
                                <pathelement location="${result-path}/src" />
                                <!-- demo widgetset sources -->
                                <pathelement path="${output-dir}/WebContent/WEB-INF/src" />
+                               <pathelement location="build/classes" />
                        </classpath>
                </java>
                <antcall target="remove-widgetset-gwt-tmp"/>
                                <pathelement location="${result-path}/src" />
                                <!-- demo widgetset sources -->
                                <pathelement path="${output-dir}/WebContent/WEB-INF/src" />
+                               <pathelement location="build/classes" />
                        </classpath>
                </java>
                <antcall target="remove-widgetset-gwt-tmp"/>
                                <pathelement location="${result-path}/src" />
                                <!-- demo widgetset sources -->
                                <pathelement path="${output-dir}/WebContent/WEB-INF/src" />
+                               <pathelement location="build/classes" />
                        </classpath>
                </java>
                <antcall target="remove-widgetset-gwt-tmp"/>
index a811d7ac92a94e035e0b14c83afa320e032a67be..55de19b73cd75ab375dabb51189639f6f801e9e5 100644 (file)
@@ -6,11 +6,14 @@ package com.vaadin.demo.colorpicker;
 
 import java.util.Map;
 
+import com.vaadin.demo.colorpicker.gwt.client.ui.VColorPicker;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.ui.AbstractField;
+import com.vaadin.ui.ClientWidget;
 
 @SuppressWarnings("serial")
+@ClientWidget(VColorPicker.class)
 public class ColorPicker extends AbstractField {
 
     public ColorPicker() {
index 718ab9e2c6006909eb21db51000438b989395537..27ddc1d60f3dbf087d51074221d7dd5ad6df5018 100644 (file)
@@ -1,11 +1,8 @@
 <module>
        <!-- Inherit DefaultWidgetSet -->\r
-       <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" /> \r
+       <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" /> 
        \r
        <!-- WidgetSet default theme -->        
        <stylesheet src="colorpicker/styles.css"/>
 
-       <!-- Entry point -->
-       <entry-point class="com.vaadin.demo.colorpicker.gwt.client.ColorPickerWidgetSet"/>
-  
 </module>
diff --git a/src/com/vaadin/demo/colorpicker/gwt/client/ColorPickerWidgetSet.java b/src/com/vaadin/demo/colorpicker/gwt/client/ColorPickerWidgetSet.java
deleted file mode 100644 (file)
index 2c924c0..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* \r
-@ITMillApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.demo.colorpicker.gwt.client;\r
-\r
-import com.vaadin.demo.colorpicker.gwt.client.ui.VColorPicker;\r
-import com.vaadin.terminal.gwt.client.DefaultWidgetSet;\r
-import com.vaadin.terminal.gwt.client.Paintable;\r
-import com.vaadin.terminal.gwt.client.UIDL;\r
-\r
-public class ColorPickerWidgetSet extends DefaultWidgetSet {\r
-    /** Resolves UIDL tag name to widget class. */\r
-    @Override\r
-    protected Class<?> resolveWidgetType(UIDL uidl) {\r
-        final String tag = uidl.getTag();\r
-        if ("colorpicker".equals(tag)) {\r
-            return VColorPicker.class;\r
-        }\r
-\r
-        // Let the DefaultWidgetSet handle resolution of default widgets\r
-        return super.resolveWidgetType(uidl);\r
-    }\r
-\r
-    /** Creates a widget instance according to its class object. */\r
-    @Override\r
-    public Paintable createWidget(UIDL uidl) {\r
-        final Class<?> type = resolveWidgetType(uidl);\r
-        if (VColorPicker.class == type) {\r
-            return new VColorPicker();\r
-        }\r
-\r
-        // Let the DefaultWidgetSet handle creation of default widgets\r
-        return super.createWidget(uidl);\r
-    }\r
-}\r
index 149cf6e3837f1d541e28214f7fbd3fe87d83bef2..bd56261a3822754d515bc1ea756a72222c328d7a 100644 (file)
@@ -4,11 +4,14 @@
 
 package com.vaadin.demo.coverflow;
 
+import com.vaadin.demo.coverflow.gwt.client.ui.VCoverflow;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.ui.AbstractSelect;
+import com.vaadin.ui.ClientWidget;
 
 @SuppressWarnings( { "serial", "unchecked" })
+@ClientWidget(VCoverflow.class)
 public class Coverflow extends AbstractSelect {
 
     private String backgroundGradientStart = "FFFFFF";
index 36c016f131f06b84b7be3c2570344126d4b71e84..a1987af121347ee28ee68993876c8e56da5df836 100644 (file)
@@ -1,8 +1,5 @@
 <module>
        <!-- Inherit the NoEntry version to avoid multiple entrypoints -->
-       <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSetNoEntry" /> 
-
-       <!-- Entry point -->
-       <entry-point class="com.vaadin.demo.coverflow.gwt.client.CoverflowWidgetSet"/>
+       <inherits name="com.vaadin.terminal.gwt.DefaultWidget" /> 
   
 </module>
diff --git a/src/com/vaadin/demo/coverflow/gwt/client/CoverflowWidgetSet.java b/src/com/vaadin/demo/coverflow/gwt/client/CoverflowWidgetSet.java
deleted file mode 100644 (file)
index bbde252..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* 
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.demo.coverflow.gwt.client;
-
-import com.vaadin.demo.coverflow.gwt.client.ui.VCoverflow;
-import com.vaadin.terminal.gwt.client.DefaultWidgetSet;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class CoverflowWidgetSet extends DefaultWidgetSet {
-    /** Creates a widget according to its class name. */
-    @Override
-    public Paintable createWidget(UIDL uidl) {
-        final Class<?> classType = resolveWidgetType(uidl);
-        if (VCoverflow.class == classType) {
-            return new VCoverflow();
-        }
-
-        // Let the DefaultWidgetSet handle creation of default widgets
-        return super.createWidget(uidl);
-    }
-
-    /** Resolves UIDL tag name to class . */
-    @Override
-    protected Class<?> resolveWidgetType(UIDL uidl) {
-        final String tag = uidl.getTag();
-        if ("cover".equals(tag)) {
-            return VCoverflow.class;
-        }
-
-        // Let the DefaultWidgetSet handle resolution of default widgets
-        return super.resolveWidgetType(uidl);
-    }
-}
\ No newline at end of file
index 2af0f1ed71a80c29ecfcf594b7e33cfeb1f4e1b1..349c6b59a8b2b9059a4fcc60c5798cdecb4efcc7 100644 (file)
@@ -12,14 +12,17 @@ import java.util.Iterator;
 import com.vaadin.data.Container;\r
 import com.vaadin.data.Item;\r
 import com.vaadin.data.Property;\r
+import com.vaadin.demo.reservation.gwt.client.ui.VCalendarField;\r
 import com.vaadin.terminal.PaintException;\r
 import com.vaadin.terminal.PaintTarget;\r
+import com.vaadin.ui.ClientWidget;\r
 import com.vaadin.ui.DateField;\r
 \r
 // TODO send one month at a time, do lazyLoading\r
 // TODO check date limit when updating variables\r
 // TODO Allow item selection\r
 @SuppressWarnings("serial")\r
+@ClientWidget(VCalendarField.class)\r
 public class CalendarField extends DateField implements Container.Viewer {\r
 \r
     private static final String TAGNAME = "calendarfield";\r
index e82f7c0f6ac64217693a3ca21dd5f3867927897e..19dee3aacf13b52f6f3fd0abe6a4de20fee3473f 100644 (file)
@@ -12,12 +12,15 @@ import com.vaadin.data.Container;
 import com.vaadin.data.Item;\r
 import com.vaadin.data.Property;\r
 import com.vaadin.data.util.IndexedContainer;\r
+import com.vaadin.demo.reservation.gwt.client.ui.VGoogleMap;\r
 import com.vaadin.terminal.PaintException;\r
 import com.vaadin.terminal.PaintTarget;\r
 import com.vaadin.terminal.Sizeable;\r
 import com.vaadin.ui.AbstractComponent;\r
+import com.vaadin.ui.ClientWidget;\r
 \r
 @SuppressWarnings("serial")\r
+@ClientWidget(VGoogleMap.class)\r
 public class GoogleMap extends AbstractComponent implements Sizeable,\r
         Container.Viewer {\r
     private final String TAG_MARKERS = "markers";\r
index 1b2991d51c0b85aaa42471fea38e1c221cd68887..4f38e07f263259d9eef4943e79964ff9f82dae7d 100644 (file)
@@ -23,7 +23,4 @@
        <!-- Using key for http://demo.vaadin.com: -->
        <script src="http://maps.google.com/maps?gwt=1&amp;file=api&amp;v=2.x&amp;key=ABQIAAAAP3UBMIhn15mgO6uIqO_GVRTjfRw0y7NvUKCc8_UnYaOyzzWA_xRoBYGzLMNrw-8-IesNKDC1WFd_vg" />
 
-       <!-- Entry point -->
-       <entry-point class="com.vaadin.demo.reservation.gwt.client.ReservationWidgetSet"/>
-  
 </module>
diff --git a/src/com/vaadin/demo/reservation/gwt/client/ReservationWidgetSet.java b/src/com/vaadin/demo/reservation/gwt/client/ReservationWidgetSet.java
deleted file mode 100644 (file)
index 2520098..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* \r
-@ITMillApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.demo.reservation.gwt.client;\r
-\r
-import com.vaadin.demo.reservation.gwt.client.ui.VCalendarField;\r
-import com.vaadin.demo.reservation.gwt.client.ui.VGoogleMap;\r
-import com.vaadin.terminal.gwt.client.DefaultWidgetSet;\r
-import com.vaadin.terminal.gwt.client.Paintable;\r
-import com.vaadin.terminal.gwt.client.UIDL;\r
-\r
-public class ReservationWidgetSet extends DefaultWidgetSet {\r
-    @Override\r
-    public Paintable createWidget(UIDL uidl) {\r
-        final Class<?> type = resolveWidgetType(uidl);\r
-        if (VGoogleMap.class == type) {\r
-            return new VGoogleMap();\r
-        } else if (VCalendarField.class == type) {\r
-            return new VCalendarField();\r
-        }\r
-\r
-        return super.createWidget(uidl);\r
-    }\r
-\r
-    @Override\r
-    protected Class<?> resolveWidgetType(UIDL uidl) {\r
-        final String tag = uidl.getTag();\r
-        if ("googlemap".equals(tag)) {\r
-            return VGoogleMap.class;\r
-        } else if ("calendarfield".equals(tag)) {\r
-            return VCalendarField.class;\r
-        }\r
-        return super.resolveWidgetType(uidl);\r
-    }\r
-\r
-}\r
index 9b6a47cb3b5d79f47198d81fc43e51e68f274447..53c2c1b2b9993f05f05072608e7d32c75c2e285f 100644 (file)
@@ -5,14 +5,17 @@ import java.lang.reflect.Method;
 import java.util.HashSet;
 import java.util.Map;
 
+import com.vaadin.demo.sampler.gwt.client.ui.VActiveLink;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
+import com.vaadin.ui.ClientWidget;
 import com.vaadin.ui.Component;
 import com.vaadin.ui.Link;
 import com.vaadin.ui.Button.ClickEvent;
 
 @SuppressWarnings("serial")
+@ClientWidget(VActiveLink.class)
 public class ActiveLink extends Link {
 
     private static final String TAG = "activelink";
index bfc96d30fefa4871d62d77a2a2539d753d8c53db..3e4f985a65b2598d80ca8cb613ae57fea0ca44f2 100644 (file)
@@ -1,7 +1,10 @@
 package com.vaadin.demo.sampler;
 
+import com.vaadin.demo.sampler.gwt.client.ui.VCodeLabel;
+import com.vaadin.ui.ClientWidget;
 import com.vaadin.ui.Label;
 
+@ClientWidget(VCodeLabel.class)
 @SuppressWarnings("serial")
 public class CodeLabel extends Label {
 
index c8009983c33b2fe0d5dc6c542f7692c36271c583..9c654bff590e0e43d0d6054045c4e2dc6b4d16c8 100644 (file)
@@ -1,10 +1,13 @@
 package com.vaadin.demo.sampler;
 
+import com.vaadin.demo.sampler.gwt.client.ui.VGoogleAnalytics;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.ClientWidget;
 
 @SuppressWarnings("serial")
+@ClientWidget(VGoogleAnalytics.class)
 public class GoogleAnalytics extends AbstractComponent {
 
     private String trackerId;
index dc6d1b206c0a343641b6754b80a004ad266aec25..f40e421fbb194e3c18219a98344b6d8bb818ac2b 100644 (file)
@@ -9,7 +9,4 @@
        <stylesheet src="prettify/prettify.css"/>
        <script src="prettify/prettify.js" />
 
-       <!-- Entry point -->
-       <entry-point class="com.vaadin.demo.sampler.gwt.client.SamplerWidgetSet"/>
-  
 </module>
diff --git a/src/com/vaadin/demo/sampler/gwt/client/SamplerWidgetSet.java b/src/com/vaadin/demo/sampler/gwt/client/SamplerWidgetSet.java
deleted file mode 100644 (file)
index 69942f6..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.vaadin.demo.sampler.gwt.client;
-
-import com.vaadin.demo.sampler.gwt.client.ui.VActiveLink;
-import com.vaadin.demo.sampler.gwt.client.ui.VCodeLabel;
-import com.vaadin.demo.sampler.gwt.client.ui.VGoogleAnalytics;
-import com.vaadin.terminal.gwt.client.DefaultWidgetSet;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class SamplerWidgetSet extends DefaultWidgetSet {
-
-    @Override
-    public Paintable createWidget(UIDL uidl) {
-        final Class<?> classType = resolveWidgetType(uidl);
-        if (VGoogleAnalytics.class == classType) {
-            return new VGoogleAnalytics();
-        } else if (VCodeLabel.class == classType) {
-            return new VCodeLabel();
-        } else if (VActiveLink.class == classType) {
-            return new VActiveLink();
-        } else {
-            return super.createWidget(uidl);
-        }
-    }
-
-    @Override
-    protected Class<?> resolveWidgetType(UIDL uidl) {
-        final String tag = uidl.getTag();
-        if ("googleanalytics".equals(tag)) {
-            return VGoogleAnalytics.class;
-        } else if ("codelabel".equals(tag)) {
-            return VCodeLabel.class;
-        } else if ("activelink".equals(tag)) {
-            return VActiveLink.class;
-        } else {
-            return super.resolveWidgetType(uidl);
-        }
-    }
-
-}
index 3e9527788d9e89a8599e71097c7ece4cb1faeb3c..096376003524c232f2edc6a65e7d1604808b888b 100644 (file)
@@ -1,8 +1,4 @@
 <module>
        <!-- Inherit the SamplerWidgetSet -->
        <inherits name="com.vaadin.demo.sampler.gwt.SamplerWidgetSet" />
-
-       <!-- Entry point -->
-       <entry-point class="com.vaadin.portal.gwt.client.PortalDefaultWidgetSet"/>
-       
 </module>
diff --git a/src/com/vaadin/portal/gwt/client/PortalDefaultWidgetSet.java b/src/com/vaadin/portal/gwt/client/PortalDefaultWidgetSet.java
deleted file mode 100644 (file)
index d28ddc9..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.vaadin.portal.gwt.client;\r
-\r
-import com.vaadin.demo.sampler.gwt.client.SamplerWidgetSet;\r
-\r
-public class PortalDefaultWidgetSet extends SamplerWidgetSet {\r
-\r
-}\r
index a457dd4d1d90c5233db04007ecc7b79e255623d2..725d82dcab9535281606e9bd51a98dff74df6add 100644 (file)
@@ -390,4 +390,11 @@ public interface PaintTarget extends Serializable {
     void addCharacterData(String text) throws PaintException;
 
     public void addAttribute(String string, Object[] keys);
+
+    /**
+     * @return the "tag" string used in communication to present given
+     *         {@link Paintable} type. Terminal may define how to present
+     *         paintable.
+     */
+    public String getTag(Paintable paintable);
 }
index 23b281dc4f442af3db986b94f81d1fc85285f75a..58d692e99fa2731d9af5c9bd3e46762371942f54 100644 (file)
@@ -22,7 +22,7 @@
        <inherits name="com.google.gwt.xml.XML" />
 
        <inherits name="com.google.gwt.json.JSON" />
-
+       
        <source path="client" />
        
        <!-- Use our own history impl for IE to workaround #2931.       --> 
                <when-property-is name="user.agent" value="ie6"/>
        </replace-with>
 
+       <generate-with class="com.vaadin.terminal.gwt.rebind.WidgetMapGenerator">
+               <when-type-is class="com.vaadin.terminal.gwt.client.WidgetMap"/>
+       </generate-with>
+       
        <entry-point class="com.vaadin.terminal.gwt.client.DefaultWidgetSet" />
+       
 </module>
diff --git a/src/com/vaadin/terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml b/src/com/vaadin/terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml
deleted file mode 100644 (file)
index d8d8607..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<module>
-       <!--
-               "NoEntry" -concept deprecated, inherit DefaultWidgetSet instead.
-       -->
-       <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" />
-</module>
\ No newline at end of file
index 945542729f07c6985932f1e201642274fb3f5373..1674196e9090ea60723fcd25801d9e91d4e2801b 100644 (file)
@@ -6,6 +6,8 @@ import java.util.List;
 
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.JsArrayString;
+import com.vaadin.terminal.gwt.client.ui.VUnknownComponent;
 
 public class ApplicationConfiguration {
 
@@ -23,6 +25,8 @@ public class ApplicationConfiguration {
     private String communicationErrorUrl;
     private boolean useDebugIdInDom = true;
 
+    private Class<? extends Paintable>[] classes = new Class[1024];
+
     private static ArrayList<ApplicationConnection> unstartedApplications = new ArrayList<ApplicationConnection>();
     private static ArrayList<ApplicationConnection> runningApplications = new ArrayList<ApplicationConnection>();
 
@@ -118,13 +122,13 @@ public class ApplicationConfiguration {
         int lastdot = module.lastIndexOf(".");
         String base = module.substring(0, lastdot);
         String simpleName = module.substring(lastdot + 1);
-        if (!wsname.startsWith(base) || !wsname.endsWith(simpleName)) {
-            // WidgetSet module name does not match implementation name;
-            // probably inherited WidgetSet with entry-point. Skip.
-            GWT.log("Ignored init for " + wsname + " when starting " + module,
-                    null);
-            return;
-        }
+        // if (!wsname.startsWith(base) || !wsname.endsWith(simpleName)) {
+        // // WidgetSet module name does not match implementation name;
+        // // probably inherited WidgetSet with entry-point. Skip.
+        // GWT.log("Ignored init for " + wsname + " when starting " + module,
+        // null);
+        // return;
+        // }
 
         if (initedWidgetSet != null) {
             // Something went wrong: multiple widgetsets inited
@@ -198,4 +202,24 @@ public class ApplicationConfiguration {
     public boolean useDebugIdInDOM() {
         return useDebugIdInDom;
     }
+
+    public Class<? extends Paintable> getWidgetClassByEncodedTag(String tag) {
+        try {
+            int parseInt = Integer.parseInt(tag);
+            return classes[parseInt];
+        } catch (Exception e) {
+            // component was not present in mappings
+            return VUnknownComponent.class;
+        }
+    }
+
+    public void addComponentMappings(ValueMap valueMap, WidgetSet widgetSet) {
+        JsArrayString keyArray = valueMap.getKeyArray();
+        for (int i = 0; i < keyArray.length(); i++) {
+            String key = keyArray.get(i);
+            int value = valueMap.getInt(key);
+            classes[value] = widgetSet.getImplementationByClassName(key);
+        }
+    }
+
 }
index 0e1270901f637cb315a5d760cf07026466d6ebaf..72cefddf2dea1e7c532774ec3f7420aa4b9b0ed2 100755 (executable)
@@ -20,7 +20,6 @@ import com.google.gwt.http.client.RequestBuilder;
 import com.google.gwt.http.client.RequestCallback;
 import com.google.gwt.http.client.RequestException;
 import com.google.gwt.http.client.Response;
-import com.google.gwt.json.client.JSONArray;
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.DeferredCommand;
@@ -607,7 +606,11 @@ public class ApplicationConnection {
 
     private static native ValueMap parseJSONResponse(String jsonText)
     /*-{
-        return eval('(' + jsonText + ')');
+        if(JSON && JSON.parse) {
+            return JSON.parse(jsonText);
+        } else {
+            return eval('(' + jsonText + ')');
+        }
      }-*/;
 
     private void handleReceivedJSONMessage(Response response) {
@@ -618,12 +621,17 @@ public class ApplicationConnection {
         ValueMap json;
         try {
             json = parseJSONResponse(jsonText);
-        } catch (final com.google.gwt.json.client.JSONException e) {
+        } catch (final Exception e) {
             endRequest();
             showCommunicationError(e.getMessage() + " - Original JSON-text:");
             console.log(jsonText);
             return;
         }
+
+        ApplicationConnection.getConsole()
+                .log(
+                        "JSON parsing took "
+                                + (new Date().getTime() - start.getTime()));
         // Handle redirect
         if (json.containsKey("redirect")) {
             String url = json.getValueMap("redirect").getString("url");
@@ -642,6 +650,11 @@ public class ApplicationConnection {
             }
         }
 
+        if (json.containsKey("typeMappings")) {
+            configuration.addComponentMappings(
+                    json.getValueMap("typeMappings"), widgetSet);
+        }
+
         if (json.containsKey("locales")) {
             // Store locale data
             JsArray<ValueMap> valueMapArray = json
@@ -707,7 +720,7 @@ public class ApplicationConnection {
                     updatedWidgets.add(idToPaintableDetail.get(uidl.getId())
                             .getComponent());
                 } else {
-                    if (!uidl.getTag().equals("window")) {
+                    if (!uidl.getTag().equals("0")) {
                         ClientExceptionHandler
                                 .displayError("Received update for "
                                         + uidl.getTag()
@@ -790,10 +803,6 @@ public class ApplicationConnection {
         endRequest();
     }
 
-    private UIDL getUidl(JSONArray changes, int i) {
-        return (UIDL) changes.get(i).isArray().getJavaScriptObject();
-    }
-
     /**
      * This method assures that all pending variable changes are sent to server.
      * Method uses synchronized xmlhttprequest and does not return before the
@@ -1112,10 +1121,11 @@ public class ApplicationConnection {
         }
 
         // Switch to correct implementation if needed
-        if (!widgetSet.isCorrectImplementation(component, uidl)) {
+        if (!widgetSet.isCorrectImplementation(component, uidl, configuration)) {
             final Container parent = Util.getLayout(component);
             if (parent != null) {
-                final Widget w = (Widget) widgetSet.createWidget(uidl);
+                final Widget w = (Widget) widgetSet.createWidget(uidl,
+                        configuration);
                 parent.replaceChildComponent(component, w);
                 unregisterPaintable((Paintable) component);
                 registerPaintable(uidl.getId(), (Paintable) w);
@@ -1511,7 +1521,7 @@ public class ApplicationConnection {
         if (w != null) {
             return w;
         } else {
-            w = widgetSet.createWidget(uidl);
+            w = widgetSet.createWidget(uidl, configuration);
             registerPaintable(id, w);
             return w;
 
@@ -1750,4 +1760,8 @@ public class ApplicationConnection {
         componentDetail.putAdditionalTooltip(key, tooltip);
     }
 
+    public ApplicationConfiguration getConfiguration() {
+        return configuration;
+    }
+
 }
index 4c3f9c83d14c0d5f344844f6f5f0cf6fbce4ba57..9c54e4c5f25d06bcbda4dd221ca11b1ceda0d482 100644 (file)
 
 package com.vaadin.terminal.gwt.client;
 
+import com.google.gwt.core.client.GWT;
 import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout;
-import com.vaadin.terminal.gwt.client.ui.VAccordion;
 import com.vaadin.terminal.gwt.client.ui.VButton;
 import com.vaadin.terminal.gwt.client.ui.VCheckBox;
-import com.vaadin.terminal.gwt.client.ui.VCustomComponent;
-import com.vaadin.terminal.gwt.client.ui.VCustomLayout;
 import com.vaadin.terminal.gwt.client.ui.VDateFieldCalendar;
-import com.vaadin.terminal.gwt.client.ui.VEmbedded;
 import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
-import com.vaadin.terminal.gwt.client.ui.VCssLayout;
-import com.vaadin.terminal.gwt.client.ui.VForm;
-import com.vaadin.terminal.gwt.client.ui.VFormLayout;
-import com.vaadin.terminal.gwt.client.ui.VGridLayout;
-import com.vaadin.terminal.gwt.client.ui.VHorizontalLayout;
-import com.vaadin.terminal.gwt.client.ui.VLabel;
-import com.vaadin.terminal.gwt.client.ui.VLink;
 import com.vaadin.terminal.gwt.client.ui.VListSelect;
-import com.vaadin.terminal.gwt.client.ui.VMenuBar;
-import com.vaadin.terminal.gwt.client.ui.VNativeButton;
 import com.vaadin.terminal.gwt.client.ui.VNativeSelect;
 import com.vaadin.terminal.gwt.client.ui.VOptionGroup;
-import com.vaadin.terminal.gwt.client.ui.VOrderedLayout;
-import com.vaadin.terminal.gwt.client.ui.VPanel;
 import com.vaadin.terminal.gwt.client.ui.VPasswordField;
 import com.vaadin.terminal.gwt.client.ui.VPopupCalendar;
-import com.vaadin.terminal.gwt.client.ui.VPopupView;
-import com.vaadin.terminal.gwt.client.ui.VProgressIndicator;
-import com.vaadin.terminal.gwt.client.ui.VScrollTable;
-import com.vaadin.terminal.gwt.client.ui.VSlider;
 import com.vaadin.terminal.gwt.client.ui.VSplitPanelHorizontal;
 import com.vaadin.terminal.gwt.client.ui.VSplitPanelVertical;
-import com.vaadin.terminal.gwt.client.ui.VTablePaging;
-import com.vaadin.terminal.gwt.client.ui.VTabsheet;
 import com.vaadin.terminal.gwt.client.ui.VTextArea;
 import com.vaadin.terminal.gwt.client.ui.VTextField;
-import com.vaadin.terminal.gwt.client.ui.VTextualDate;
-import com.vaadin.terminal.gwt.client.ui.VTree;
 import com.vaadin.terminal.gwt.client.ui.VTwinColSelect;
 import com.vaadin.terminal.gwt.client.ui.VUnknownComponent;
-import com.vaadin.terminal.gwt.client.ui.VUpload;
-import com.vaadin.terminal.gwt.client.ui.VUriFragmentUtility;
-import com.vaadin.terminal.gwt.client.ui.VVerticalLayout;
+import com.vaadin.terminal.gwt.client.ui.VView;
 import com.vaadin.terminal.gwt.client.ui.VWindow;
-import com.vaadin.terminal.gwt.client.ui.richtextarea.VRichTextArea;
 
 public class DefaultWidgetSet implements WidgetSet {
 
+    /**
+     * DefaultWidgetSet (and its extensions) delegate instantiation of widgets
+     * and client-server mathing to WidgetMap. The actual implementations are
+     * generated with gwts deferred binding.
+     */
+    private WidgetMap map;
+
     /**
      * This is the entry point method. It will start the first
      */
     public void onModuleLoad() {
         ApplicationConfiguration.initConfigurations(this);
         ApplicationConfiguration.startNextApplication(); // start first app
+        map = GWT.create(WidgetMap.class);
     }
 
-    public Paintable createWidget(UIDL uidl) {
-        final Class classType = resolveWidgetType(uidl);
-        if (VCheckBox.class == classType) {
-            return new VCheckBox();
-        } else if (VButton.class == classType) {
-            return new VButton();
-        } else if (VNativeButton.class == classType) {
-            return new VNativeButton();
-        } else if (VWindow.class == classType) {
-            return new VWindow();
-        } else if (VOrderedLayout.class == classType) {
-            return new VOrderedLayout();
-        } else if (VVerticalLayout.class == classType) {
-            return new VVerticalLayout();
-        } else if (VHorizontalLayout.class == classType) {
-            return new VHorizontalLayout();
-        } else if (VLabel.class == classType) {
-            return new VLabel();
-        } else if (VLink.class == classType) {
-            return new VLink();
-        } else if (VGridLayout.class == classType) {
-            return new VGridLayout();
-        } else if (VTree.class == classType) {
-            return new VTree();
-        } else if (VOptionGroup.class == classType) {
-            return new VOptionGroup();
-        } else if (VTwinColSelect.class == classType) {
-            return new VTwinColSelect();
-        } else if (VNativeSelect.class == classType) {
-            return new VNativeSelect();
-        } else if (VListSelect.class == classType) {
-            return new VListSelect();
-        } else if (VPanel.class == classType) {
-            return new VPanel();
-        } else if (VTabsheet.class == classType) {
-            return new VTabsheet();
-        } else if (VEmbedded.class == classType) {
-            return new VEmbedded();
-        } else if (VCustomLayout.class == classType) {
-            return new VCustomLayout();
-        } else if (VCustomComponent.class == classType) {
-            return new VCustomComponent();
-        } else if (VTextArea.class == classType) {
-            return new VTextArea();
-        } else if (VPasswordField.class == classType) {
-            return new VPasswordField();
-        } else if (VTextField.class == classType) {
-            return new VTextField();
-        } else if (VTablePaging.class == classType) {
-            return new VTablePaging();
-        } else if (VScrollTable.class == classType) {
-            return new VScrollTable();
-        } else if (VDateFieldCalendar.class == classType) {
-            return new VDateFieldCalendar();
-        } else if (VTextualDate.class == classType) {
-            return new VTextualDate();
-        } else if (VPopupCalendar.class == classType) {
-            return new VPopupCalendar();
-        } else if (VSlider.class == classType) {
-            return new VSlider();
-        } else if (VForm.class == classType) {
-            return new VForm();
-        } else if (VFormLayout.class == classType) {
-            return new VFormLayout();
-        } else if (VUpload.class == classType) {
-            return new VUpload();
-        } else if (VSplitPanelHorizontal.class == classType) {
-            return new VSplitPanelHorizontal();
-        } else if (VSplitPanelVertical.class == classType) {
-            return new VSplitPanelVertical();
-        } else if (VFilterSelect.class == classType) {
-            return new VFilterSelect();
-        } else if (VProgressIndicator.class == classType) {
-            return new VProgressIndicator();
-        } else if (VRichTextArea.class == classType) {
-            return new VRichTextArea();
-        } else if (VAccordion.class == classType) {
-            return new VAccordion();
-        } else if (VMenuBar.class == classType) {
-            return new VMenuBar();
-        } else if (VPopupView.class == classType) {
-            return new VPopupView();
-        } else if (VUriFragmentUtility.class == classType) {
-            return new VUriFragmentUtility();
-        } else if (VAbsoluteLayout.class == classType) {
-            return new VAbsoluteLayout();
-        } else if (VCssLayout.class == classType) {
-            return new VCssLayout();
+    public Paintable createWidget(UIDL uidl, ApplicationConfiguration conf) {
+        final Class<? extends Paintable> classType = resolveWidgetType(uidl,
+                conf);
+        if (classType == null) {
+            return new VUnknownComponent();
         }
 
-        return new VUnknownComponent();
-
+        return map.instantiate(classType);
     }
 
-    protected Class resolveWidgetType(UIDL uidl) {
+    protected Class<? extends Paintable> resolveWidgetType(UIDL uidl,
+            ApplicationConfiguration conf) {
         final String tag = uidl.getTag();
-        if ("button".equals(tag) || "nativebutton".equals(tag)) {
-            if ("switch".equals(uidl.getStringAttribute("type"))) {
-                return VCheckBox.class;
-            } else if ("nativebutton".equals(tag)) {
-                return VNativeButton.class;
-            } else {
-                return VButton.class;
-            }
-        } else if ("window".equals(tag)) {
+
+        Class<? extends Paintable> widgetClass = conf
+                .getWidgetClassByEncodedTag(tag);
+
+        // TODO add our quirks
+
+        if (widgetClass == VButton.class && uidl.hasAttribute("type")) {
+            return VCheckBox.class;
+        } else if (widgetClass == VView.class && uidl.hasAttribute("sub")) {
             return VWindow.class;
-        } else if ("orderedlayout".equals(tag)) {
-            return VOrderedLayout.class;
-        } else if ("verticallayout".equals(tag)) {
-            return VVerticalLayout.class;
-        } else if ("horizontallayout".equals(tag)) {
-            return VHorizontalLayout.class;
-        } else if ("label".equals(tag)) {
-            return VLabel.class;
-        } else if ("link".equals(tag)) {
-            return VLink.class;
-        } else if ("gridlayout".equals(tag)) {
-            return VGridLayout.class;
-        } else if ("tree".equals(tag)) {
-            return VTree.class;
-        } else if ("select".equals(tag)) {
+        } else if (widgetClass == VFilterSelect.class) {
             if (uidl.hasAttribute("type")) {
-                final String type = uidl.getStringAttribute("type");
-                if (type.equals("twincol")) {
+                // TODO check if all type checks are really neede
+                final String type = uidl.getStringAttribute("type").intern();
+                if (type == "twincol") {
                     return VTwinColSelect.class;
-                }
-                if (type.equals("optiongroup")) {
+                } else if (type == "optiongroup") {
                     return VOptionGroup.class;
-                }
-                if (type.equals("native")) {
+                } else if (type == "native") {
                     return VNativeSelect.class;
-                }
-                if (type.equals("list")) {
+                } else if (type == "list") {
                     return VListSelect.class;
-                }
-            } else {
-                if (uidl.hasAttribute("selectmode")
+                } else if (uidl.hasAttribute("selectmode")
                         && uidl.getStringAttribute("selectmode")
                                 .equals("multi")) {
                     return VListSelect.class;
-                } else {
-                    return VFilterSelect.class;
                 }
             }
-        } else if ("panel".equals(tag)) {
-            return VPanel.class;
-        } else if ("tabsheet".equals(tag)) {
-            return VTabsheet.class;
-        } else if ("accordion".equals(tag)) {
-            return VAccordion.class;
-        } else if ("embedded".equals(tag)) {
-            return VEmbedded.class;
-        } else if ("customlayout".equals(tag)) {
-            return VCustomLayout.class;
-        } else if ("customcomponent".equals(tag)) {
-            return VCustomComponent.class;
-        } else if ("textfield".equals(tag)) {
-            if (uidl.getBooleanAttribute("richtext")) {
-                return VRichTextArea.class;
-            } else if (uidl.hasAttribute("multiline")) {
+        } else if (widgetClass == VTextField.class) {
+            if (uidl.hasAttribute("multiline")) {
                 return VTextArea.class;
-            } else if (uidl.getBooleanAttribute("secret")) {
+            } else if (uidl.hasAttribute("secret")) {
                 return VPasswordField.class;
-            } else {
-                return VTextField.class;
             }
-        } else if ("table".equals(tag)) {
-            return VScrollTable.class;
-        } else if ("pagingtable".equals(tag)) {
-            return VTablePaging.class;
-        } else if ("datefield".equals(tag)) {
-            if (uidl.hasAttribute("type")) {
-                if ("inline".equals(uidl.getStringAttribute("type"))) {
-                    return VDateFieldCalendar.class;
-                } else if ("popup".equals(uidl.getStringAttribute("type"))) {
-                    return VPopupCalendar.class;
-                }
+        } else if (widgetClass == VPopupCalendar.class) {
+            if (uidl.hasAttribute("type")
+                    && uidl.getStringAttribute("type").equals("inline")) {
+                return VDateFieldCalendar.class;
             }
-            // popup calendar is the default
-            return VPopupCalendar.class;
-        } else if ("slider".equals(tag)) {
-            return VSlider.class;
-        } else if ("form".equals(tag)) {
-            return VForm.class;
-        } else if ("formlayout".equals(tag)) {
-            return VFormLayout.class;
-        } else if ("upload".equals(tag)) {
-            return VUpload.class;
-        } else if ("hsplitpanel".equals(tag)) {
-            return VSplitPanelHorizontal.class;
-        } else if ("vsplitpanel".equals(tag)) {
+        } else if (widgetClass == VSplitPanelHorizontal.class
+                && uidl.hasAttribute("vertical")) {
             return VSplitPanelVertical.class;
-        } else if ("progressindicator".equals(tag)) {
-            return VProgressIndicator.class;
-        } else if ("menubar".equals(tag)) {
-            return VMenuBar.class;
-        } else if ("popupview".equals(tag)) {
-            return VPopupView.class;
-        } else if ("urifragment".equals(tag)) {
-            return VUriFragmentUtility.class;
-        } else if (VAbsoluteLayout.TAGNAME.equals(tag)) {
-            return VAbsoluteLayout.class;
-        } else if (VCssLayout.TAGNAME.equals(tag)) {
-            return VCssLayout.class;
         }
 
-        return VUnknownComponent.class;
-    }
+        return widgetClass;
 
-    /**
-     * Kept here to support 5.2 era widget sets
-     * 
-     * @deprecated use resolveWidgetType instead
-     */
-    @Deprecated
-    protected String resolveWidgetTypeName(UIDL uidl) {
-        Class type = resolveWidgetType(uidl);
-        return type.getName();
     }
 
-    public boolean isCorrectImplementation(Widget currentWidget, UIDL uidl) {
-        // TODO remove backwardscompatibility check
-        return currentWidget.getClass() == resolveWidgetType(uidl)
-                || currentWidget.getClass().getName().equals(
-                        resolveWidgetTypeName(uidl));
+    public boolean isCorrectImplementation(Widget currentWidget, UIDL uidl,
+            ApplicationConfiguration conf) {
+        return currentWidget.getClass() == resolveWidgetType(uidl, conf);
     }
 
+    public Class<? extends Paintable> getImplementationByClassName(
+            String fullyqualifiedName) {
+        Class<? extends Paintable> implementationByServerSideClassName = map
+                .getImplementationByServerSideClassName(fullyqualifiedName);
+        return implementationByServerSideClassName;
+
+    }
 }
index fb5a81a86cd283952d4654ec5aabce6a320b5ac7..f3a59460e05aaa1eb47aa838c5cf6c304d90d7b3 100755 (executable)
@@ -70,6 +70,8 @@ public final class VDebugConsole extends VOverlay implements Console {
 
     private ApplicationConnection client;
 
+    private ApplicationConfiguration conf;
+
     private static final String help = "Drag=move, shift-drag=resize, doubleclick=min/max."
             + "Use debug=quiet to log only to browser console.";
 
@@ -78,6 +80,7 @@ public final class VDebugConsole extends VOverlay implements Console {
         super(false, false);
 
         this.client = client;
+        conf = cnf;
 
         panel = new FlowPanel();
         if (showWindow) {
@@ -292,7 +295,7 @@ public final class VDebugConsole extends VOverlay implements Console {
 
     /*
      * (non-Javadoc)
-     *
+     * 
      * @see com.vaadin.terminal.gwt.client.Console#log(java.lang.String)
      */
     public void log(String msg) {
@@ -303,7 +306,7 @@ public final class VDebugConsole extends VOverlay implements Console {
 
     /*
      * (non-Javadoc)
-     *
+     * 
      * @see com.vaadin.terminal.gwt.client.Console#error(java.lang.String)
      */
     public void error(String msg) {
@@ -314,7 +317,7 @@ public final class VDebugConsole extends VOverlay implements Console {
 
     /*
      * (non-Javadoc)
-     *
+     * 
      * @see com.vaadin.terminal.gwt.client.Console#printObject(java.lang.
      * Object)
      */
@@ -325,13 +328,13 @@ public final class VDebugConsole extends VOverlay implements Console {
 
     /*
      * (non-Javadoc)
-     *
+     * 
      * @see com.vaadin.terminal.gwt.client.Console#dirUIDL(com.vaadin
      * .terminal.gwt.client.UIDL)
      */
     public void dirUIDL(UIDL u) {
         if (panel.isAttached()) {
-            panel.add(new VUIDLBrowser(u));
+            panel.add(new VUIDLBrowser(u, conf));
         }
         consoleDir(u);
         // consoleLog(u.getChildrenAsXML());
index 89d5caceed70cc1becaadc745c1e2dbcbc6851da..a8a5bea94da19e0297db6223e1b447bdf53ede26 100644 (file)
@@ -18,13 +18,14 @@ public class VUIDLBrowser extends Tree {
      * 
      */
     private final UIDL uidl;
+    private ApplicationConfiguration conf;
 
-    public VUIDLBrowser(final UIDL uidl) {
-
+    public VUIDLBrowser(final UIDL uidl, ApplicationConfiguration conf) {
+        this.conf = conf;
         this.uidl = uidl;
         DOM.setStyleAttribute(getElement(), "position", "");
 
-        final UIDLItem root = new UIDLItem(this.uidl);
+        final UIDLItem root = new UIDLItem(this.uidl, conf);
         addItem(root);
         addOpenHandler(new OpenHandler<TreeItem>() {
             public void onOpen(OpenEvent<TreeItem> event) {
@@ -46,10 +47,19 @@ public class VUIDLBrowser extends Tree {
 
         private UIDL uidl;
 
-        UIDLItem(UIDL uidl) {
+        UIDLItem(UIDL uidl, ApplicationConfiguration conf) {
             this.uidl = uidl;
             try {
-                setText(uidl.getTag());
+                String name = uidl.getTag();
+                try {
+                    Integer.parseInt(name);
+                    Class<? extends Paintable> widgetClassByDecodedTag = conf
+                            .getWidgetClassByEncodedTag(name);
+                    name = widgetClassByDecodedTag.getName();
+                } catch (Exception e) {
+                    // NOP
+                }
+                setText(name);
                 addItem("LOADING");
             } catch (Exception e) {
                 setText(uidl.toString());
@@ -61,6 +71,15 @@ public class VUIDLBrowser extends Tree {
             removeItem(temp);
 
             String nodeName = uidl.getTag();
+            try {
+                Integer.parseInt(nodeName);
+                Class<? extends Paintable> widgetClassByDecodedTag = conf
+                        .getWidgetClassByEncodedTag(nodeName);
+                nodeName = widgetClassByDecodedTag.getName();
+            } catch (Exception e) {
+                // NOP
+            }
+
             Set<String> attributeNames = uidl.getAttributeNames();
             for (String name : attributeNames) {
                 if (uidl.isMapAttribute(name)) {
@@ -121,7 +140,7 @@ public class VUIDLBrowser extends Tree {
                 final Object child = i.next();
                 try {
                     final UIDL c = (UIDL) child;
-                    final TreeItem childItem = new UIDLItem(c);
+                    final TreeItem childItem = new UIDLItem(c, conf);
                     addItem(childItem);
 
                 } catch (final Exception e) {
diff --git a/src/com/vaadin/terminal/gwt/client/WidgetMap.java b/src/com/vaadin/terminal/gwt/client/WidgetMap.java
new file mode 100644 (file)
index 0000000..f0b9e26
--- /dev/null
@@ -0,0 +1,38 @@
+package com.vaadin.terminal.gwt.client;
+
+import com.vaadin.terminal.gwt.client.ui.VDateFieldCalendar;
+import com.vaadin.terminal.gwt.client.ui.VPasswordField;
+import com.vaadin.terminal.gwt.client.ui.VSplitPanelVertical;
+import com.vaadin.terminal.gwt.client.ui.VTextArea;
+import com.vaadin.terminal.gwt.client.ui.VWindow;
+
+public abstract class WidgetMap {
+
+    public Paintable instantiate(Class<? extends Paintable> classType) {
+        /*
+         * Yes, this (including the generated) may look very odd code, but due
+         * the nature of GWT, we cannot do this with reflect. Luckily this is
+         * mostly written by WidgetSetGenerator, here are just some hacks. Extra
+         * instantiation code is needed if client side widget has no "native"
+         * counterpart on client side.
+         */
+        if (VSplitPanelVertical.class == classType) {
+            return new VSplitPanelVertical();
+        } else if (VTextArea.class == classType) {
+            return new VTextArea();
+
+        } else if (VDateFieldCalendar.class == classType) {
+            return new VDateFieldCalendar();
+        } else if (VPasswordField.class == classType) {
+            return new VPasswordField();
+        } else if (VWindow.class == classType) {
+            return new VWindow();
+        } else {
+            return null; // let generated type handle this
+        }
+    }
+
+    public abstract Class<? extends Paintable> getImplementationByServerSideClassName(
+            String fullyqualifiedName);
+
+}
index df005353c048f8b7f6845f5bd0125bff93a92175..832e985397808a6d6cc7f5fb2ecd698612da1797 100644 (file)
@@ -15,10 +15,13 @@ public interface WidgetSet extends EntryPoint {
      * 
      * @param uidl
      *            UIDL to be painted with returned component.
+     * @param client
+     *            the application connection that whishes to instantiate widget
+     * 
      * @return New uninitialized and unregistered component that can paint given
      *         UIDL.
      */
-    public Paintable createWidget(UIDL uidl);
+    public Paintable createWidget(UIDL uidl, ApplicationConfiguration conf);
 
     /**
      * Test if the given component implementation conforms to UIDL.
@@ -30,5 +33,18 @@ public interface WidgetSet extends EntryPoint {
      * @return true iff createWidget would return a new component of the same
      *         class than currentWidget
      */
-    public boolean isCorrectImplementation(Widget currentWidget, UIDL uidl);
+    public boolean isCorrectImplementation(Widget currentWidget, UIDL uidl,
+            ApplicationConfiguration conf);
+
+    /**
+     * Due its nature, GWT does not support dynamic classloading. To bypass this
+     * limitation, widgetset must have function that returns Class by its fully
+     * qualified name.
+     * 
+     * @param fullyQualifiedName
+     * @return
+     */
+    public Class<? extends Paintable> getImplementationByClassName(
+            String fullyQualifiedName);
+
 }
index fd87baf199db6b70df09ea94fa4a324dc8c53cf2..cd9d2cd40c90ebc3fc7964b8d4266a5bf365dd6c 100644 (file)
@@ -35,7 +35,7 @@ public class VUnknownComponent extends Composite implements Paintable {
             uidlTree.removeFromParent();
         }
 
-        uidlTree = new VUIDLBrowser(uidl);
+        uidlTree = new VUIDLBrowser(uidl, client.getConfiguration());
         panel.add(uidlTree);
     }
 
diff --git a/src/com/vaadin/terminal/gwt/rebind/ClassPathExplorer.java b/src/com/vaadin/terminal/gwt/rebind/ClassPathExplorer.java
new file mode 100644 (file)
index 0000000..6c81c36
--- /dev/null
@@ -0,0 +1,266 @@
+package com.vaadin.terminal.gwt.rebind;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import com.vaadin.terminal.Paintable;
+import com.vaadin.ui.ClientWidget;
+
+/**
+ * Utility class to find server side widgets with {@link ClientWidget}
+ * annotation. Used by WidgetMapGenerator to implement some monkey coding for
+ * you.
+ * <p>
+ * If you end up reading this comment, I guess you have faced a sluggish
+ * performance of widget compilation or unreliable detection of components in
+ * your classpaths. The thing you might be able to do is to use annotation
+ * processing tool like apt to generate the needed information. Then either use
+ * that information in {@link WidgetMapGenerator} or create the appropriate
+ * monkey code for gwt directly in annotation processor and get rid of
+ * {@link WidgetMapGenerator}. Using annotation processor might be a good idea
+ * when dropping Java 1.5 support (integrated to javac in 6).
+ * 
+ */
+public class ClassPathExplorer {
+    private final static FileFilter DIRECTORIES_ONLY = new FileFilter() {
+        public boolean accept(File f) {
+            if (f.exists() && f.isDirectory()) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    };
+
+    private static Map<URL, String> classpathLocations = getClasspathLocations();
+
+    private ClassPathExplorer() {
+    }
+
+    public static Collection<Class<? extends Paintable>> getPaintablesHavingWidgetAnnotation() {
+        Collection<Class<? extends Paintable>> paintables = new HashSet<Class<? extends Paintable>>();
+        Set<URL> keySet = classpathLocations.keySet();
+        for (URL url : keySet) {
+            searchForPaintables(url, classpathLocations.get(url), paintables);
+        }
+        return paintables;
+
+    }
+
+    /**
+     * Determine every URL location defined by the current classpath, and it's
+     * associated package name.
+     */
+    public final static Map<URL, String> getClasspathLocations() {
+        Map<URL, String> locations = new HashMap<URL, String>();
+
+        String pathSep = System.getProperty("path.separator");
+        String classpath = System.getProperty("java.class.path");
+
+        String[] split = classpath.split(pathSep);
+        for (int i = 0; i < split.length; i++) {
+            String classpathEntry = split[i];
+            if (acceptClassPathEntry(classpathEntry)) {
+                File file = new File(classpathEntry);
+                include(null, file, locations);
+            }
+        }
+
+        return locations;
+    }
+
+    private static boolean acceptClassPathEntry(String classpathEntry) {
+        if (!classpathEntry.endsWith(".jar")) {
+            // accept all non jars (practically directories)
+            return true;
+        } else {
+            // accepts jars that comply with vaadin-component packaging
+            // convention (.vaadin. or vaadin- as distribution packages),
+            if (classpathEntry.contains("vaadin-")
+                    || classpathEntry.contains(".vaadin.")) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Recursively add subdirectories and jar files to classpathlocations
+     * 
+     * @param name
+     * @param file
+     * @param locations
+     */
+    private final static void include(String name, File file,
+            Map<URL, String> locations) {
+        if (!file.exists()) {
+            return;
+        }
+        if (!file.isDirectory()) {
+            // could be a JAR file
+            includeJar(file, locations);
+            return;
+        }
+
+        if (file.isHidden() || file.getPath().contains(File.separator + ".")) {
+            return;
+        }
+
+        if (name == null) {
+            name = "";
+        } else {
+            name += ".";
+        }
+
+        // add all directories recursively
+        File[] dirs = file.listFiles(DIRECTORIES_ONLY);
+        for (int i = 0; i < dirs.length; i++) {
+            try {
+                // add the present directory
+                locations.put(new URL("file://" + dirs[i].getCanonicalPath()),
+                        name + dirs[i].getName());
+            } catch (Exception ioe) {
+                return;
+            }
+            include(name + dirs[i].getName(), dirs[i], locations);
+        }
+    }
+
+    private static void includeJar(File file, Map<URL, String> locations) {
+        try {
+            URL url = new URL("file:" + file.getCanonicalPath());
+            url = new URL("jar:" + url.toExternalForm() + "!/");
+            JarURLConnection conn = (JarURLConnection) url.openConnection();
+            JarFile jarFile = conn.getJarFile();
+            if (jarFile != null) {
+                locations.put(url, "");
+            }
+        } catch (Exception e) {
+            // e.printStackTrace();
+            return;
+        }
+
+    }
+
+    private static String packageNameFor(JarEntry entry) {
+        if (entry == null) {
+            return "";
+        }
+        String s = entry.getName();
+        if (s == null) {
+            return "";
+        }
+        if (s.length() == 0) {
+            return s;
+        }
+        if (s.startsWith("/")) {
+            s = s.substring(1, s.length());
+        }
+        if (s.endsWith("/")) {
+            s = s.substring(0, s.length() - 1);
+        }
+        return s.replace('/', '.');
+    }
+
+    private final static void searchForPaintables(URL location,
+            String packageName,
+            Collection<Class<? extends Paintable>> paintables) {
+
+        // Get a File object for the package
+        File directory = new File(location.getFile());
+
+        if (directory.exists() && !directory.isHidden()) {
+            // Get the list of the files contained in the directory
+            String[] files = directory.list();
+            for (int i = 0; i < files.length; i++) {
+                // we are only interested in .class files
+                if (files[i].endsWith(".class")) {
+                    // remove the .class extension
+                    String classname = files[i].substring(0,
+                            files[i].length() - 6);
+                    classname = packageName + "." + classname;
+                    tryToAdd(classname, paintables);
+                }
+            }
+        } else {
+            try {
+                // check files in jar file, entries will list all directories
+                // and files in jar
+
+                URLConnection openConnection = location.openConnection();
+
+                if (openConnection instanceof JarURLConnection) {
+                    JarURLConnection conn = (JarURLConnection) openConnection;
+
+                    JarFile jarFile = conn.getJarFile();
+
+                    Enumeration<JarEntry> e = jarFile.entries();
+                    while (e.hasMoreElements()) {
+                        JarEntry entry = e.nextElement();
+                        String entryname = entry.getName();
+                        if (!entry.isDirectory()
+                                && entryname.endsWith(".class")
+                                && !entryname.contains("$")) {
+                            String classname = entryname.substring(0, entryname
+                                    .length() - 6);
+                            if (classname.startsWith("/")) {
+                                classname = classname.substring(1);
+                            }
+                            classname = classname.replace('/', '.');
+                            tryToAdd(classname, paintables);
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                System.err.println(e);
+            }
+        }
+
+    }
+
+    private static void tryToAdd(final String fullclassName,
+            Collection<Class<? extends Paintable>> paintables) {
+        try {
+            Class<?> c = Class.forName(fullclassName);
+            if (c.getAnnotation(ClientWidget.class) != null) {
+                paintables.add((Class<? extends Paintable>) c);
+                System.out.println("Found paintable " + fullclassName);
+            }
+        } catch (ExceptionInInitializerError e) {
+            // e.printStackTrace();
+        } catch (ClassNotFoundException e) {
+            // e.printStackTrace();
+        } catch (NoClassDefFoundError e) {
+            // NOP
+        } catch (UnsatisfiedLinkError e) {
+            // NOP
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Test method for helper tool
+     */
+    public static void main(String[] args) {
+        Collection<Class<? extends Paintable>> paintables = ClassPathExplorer
+                .getPaintablesHavingWidgetAnnotation();
+        System.out.println("Found annotated paintables:");
+        for (Class<? extends Paintable> cls : paintables) {
+            System.out.println(cls.getCanonicalName());
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/rebind/WidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/rebind/WidgetMapGenerator.java
new file mode 100644 (file)
index 0000000..73494ad
--- /dev/null
@@ -0,0 +1,192 @@
+package com.vaadin.terminal.gwt.rebind;
+
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+
+import com.google.gwt.core.ext.Generator;
+import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.TreeLogger.Type;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
+import com.google.gwt.user.rebind.SourceWriter;
+import com.vaadin.terminal.Paintable;
+import com.vaadin.terminal.gwt.client.ui.VView;
+import com.vaadin.ui.ClientWidget;
+
+/**
+ * GWT generator to build WidgetMapImpl dynamically based on
+ * {@link ClientWidget} annotations available in workspace.
+ * 
+ */
+public class WidgetMapGenerator extends Generator {
+
+    private String packageName;
+    private String className;
+
+    @Override
+    public String generate(TreeLogger logger, GeneratorContext context,
+            String typeName) throws UnableToCompleteException {
+
+        try {
+            TypeOracle typeOracle = context.getTypeOracle();
+
+            // get classType and save instance variables
+            JClassType classType = typeOracle.getType(typeName);
+            packageName = classType.getPackage().getName();
+            className = classType.getSimpleSourceName() + "Impl";
+            // Generate class source code
+            generateClass(logger, context);
+        } catch (Exception e) {
+            logger.log(TreeLogger.ERROR, "WidgetMap creation failed", e);
+        }
+        // return the fully qualifed name of the class generated
+        return packageName + "." + className;
+    }
+
+    /**
+     * Generate source code for WidgetMapImpl
+     * 
+     * @param logger
+     *            Logger object
+     * @param context
+     *            Generator context
+     */
+    private void generateClass(TreeLogger logger, GeneratorContext context) {
+        // get print writer that receives the source code
+        PrintWriter printWriter = null;
+        printWriter = context.tryCreate(logger, packageName, className);
+        // print writer if null, source code has ALREADY been generated, return
+        if (printWriter == null) {
+            return;
+        }
+        logger
+                .log(Type.INFO,
+                        "Detecting vaading components in classpath to generate WidgetMapImpl.java ...");
+        Date date = new Date();
+
+        // init composer, set class properties, create source writer
+        ClassSourceFileComposerFactory composer = null;
+        composer = new ClassSourceFileComposerFactory(packageName, className);
+        composer.setSuperclass("com.vaadin.terminal.gwt.client.WidgetMap");
+        SourceWriter sourceWriter = composer.createSourceWriter(context,
+                printWriter);
+
+        /*
+         * TODO we need som sort of mechanims to exclude/include components from
+         * widgetset. Properties in gwt.xml is one option. Now only possible by
+         * extending this class, overriding getUsedPaintables() method and
+         * redefining deferred binding rule.
+         */
+
+        Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation = getUsedPaintables();
+
+        TypeOracle typeOracle = context.getTypeOracle();
+
+        for (Iterator iterator = paintablesHavingWidgetAnnotation.iterator(); iterator
+                .hasNext();) {
+            Class<? extends Paintable> class1 = (Class<? extends Paintable>) iterator
+                    .next();
+
+            ClientWidget annotation = class1.getAnnotation(ClientWidget.class);
+
+            if (typeOracle.findType(annotation.value().getName()) == null) {
+                // GWT widget not inherited
+                logger
+                        .log(
+                                Type.WARN,
+                                "Widget implementation for "
+                                        + class1.getName()
+                                        + " not available for GWT compiler. If this is not "
+                                        + "intentional, check your gwt module definition file.");
+                iterator.remove();
+            }
+
+        }
+
+        // generator constructor source code
+        generateImplementationDetector(sourceWriter,
+                paintablesHavingWidgetAnnotation);
+        generateInstantiatorMethod(sourceWriter,
+                paintablesHavingWidgetAnnotation);
+        // close generated class
+        sourceWriter.outdent();
+        sourceWriter.println("}");
+        // commit generated class
+        context.commit(logger, printWriter);
+        logger.log(Type.INFO, "Done. ("
+                + (new Date().getTime() - date.getTime()) / 1000 + "seconds)");
+
+    }
+
+    protected Collection<Class<? extends Paintable>> getUsedPaintables() {
+        return ClassPathExplorer.getPaintablesHavingWidgetAnnotation();
+    }
+
+    private void generateInstantiatorMethod(
+            SourceWriter sourceWriter,
+            Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation) {
+        sourceWriter
+                .println("public Paintable instantiate(Class<? extends Paintable> classType) {");
+        sourceWriter.indent();
+
+        sourceWriter
+                .println("Paintable p = super.instantiate(classType); if(p!= null) return p;");
+
+        for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) {
+            ClientWidget annotation = class1.getAnnotation(ClientWidget.class);
+            Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = annotation
+                    .value();
+            if (clientClass == VView.class) {
+                // VView's are not instantiated by widgetset
+                continue;
+            }
+            sourceWriter.print("if (");
+            sourceWriter.print(clientClass.getName());
+            sourceWriter.print(".class == classType) return new ");
+            sourceWriter.print(clientClass.getName());
+            sourceWriter.println("();");
+            sourceWriter.print(" else ");
+        }
+        sourceWriter
+                .println("return new com.vaadin.terminal.gwt.client.ui.VUnknownComponent();");
+        sourceWriter.println("}");
+    }
+
+    /**
+     * 
+     * @param sourceWriter
+     *            Source writer to output source code
+     * @param paintablesHavingWidgetAnnotation
+     */
+    private void generateImplementationDetector(
+            SourceWriter sourceWriter,
+            Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation) {
+        sourceWriter
+                .println("public Class<? extends Paintable> getImplementationByServerSideClassName(String fullyQualifiedName) {");
+        sourceWriter.indent();
+        sourceWriter
+                .println("fullyQualifiedName = fullyQualifiedName.intern();");
+
+        for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) {
+            ClientWidget annotation = class1.getAnnotation(ClientWidget.class);
+            Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = annotation
+                    .value();
+            sourceWriter.print("if ( fullyQualifiedName == \"");
+            sourceWriter.print(class1.getName());
+            sourceWriter.print("\") return ");
+            sourceWriter.print(clientClass.getName());
+            sourceWriter.println(".class;");
+            sourceWriter.print(" else ");
+        }
+        sourceWriter
+                .println("return com.vaadin.terminal.gwt.client.ui.VUnknownComponent.class;");
+        sourceWriter.println("}");
+
+    }
+
+}
index ee5a22c3f3b0eaa55bb60b81a2cdb9f93204cfa0..11aec9ed282b4ee709d8b081b9e0a2829f0560e6 100644 (file)
@@ -92,7 +92,7 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
 
     public static final String VAR_ARRAYITEM_SEPARATOR = "\u001c";
 
-    private final HashSet<String> currentlyOpenWindowsInClient = new HashSet<String>();
+    private final HashMap<String, OpenWindowCache> currentlyOpenWindowsInClient = new HashMap<String, OpenWindowCache>();
 
     private static final int MAX_BUFFER_SIZE = 64 * 1024;
 
@@ -302,8 +302,6 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
             paintAfterVariablechanges(request, response, applicationServlet,
                     repaintAll, outWriter, window, analyzeLayouts);
 
-            // Mark this window to be open on client
-            currentlyOpenWindowsInClient.add(window.getName());
             if (closingWindowName != null) {
                 currentlyOpenWindowsInClient.remove(closingWindowName);
                 closingWindowName = null;
@@ -322,7 +320,7 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
 
         // If repaint is requested, clean all ids in this root window
         if (repaintAll) {
-            for (final Iterator it = idPaintableMap.keySet().iterator(); it
+            for (final Iterator<String> it = idPaintableMap.keySet().iterator(); it
                     .hasNext();) {
                 final Component c = (Component) idPaintableMap.get(it.next());
                 if (isChildOf(window, c)) {
@@ -363,6 +361,12 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
 
             JsonPaintTarget paintTarget = new JsonPaintTarget(this, outWriter,
                     !repaintAll);
+            OpenWindowCache windowCache = currentlyOpenWindowsInClient
+                    .get(window.getName());
+            if (windowCache == null) {
+                windowCache = new OpenWindowCache();
+                currentlyOpenWindowsInClient.put(window.getName(), windowCache);
+            }
 
             // Paints components
             if (repaintAll) {
@@ -376,8 +380,8 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
             } else {
                 // remove detached components from paintableIdMap so they
                 // can be GC'ed
-                for (Iterator it = paintableIdMap.keySet().iterator(); it
-                        .hasNext();) {
+                for (Iterator<Paintable> it = paintableIdMap.keySet()
+                        .iterator(); it.hasNext();) {
                     Component p = (Component) it.next();
                     if (p.getApplication() == null) {
                         idPaintableMap.remove(paintableIdMap.get(p));
@@ -548,10 +552,10 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
             }
 
             // TODO We should only precache the layouts that are not
-            // cached already
+            // cached already (plagiate from usedPaintableTypes)
             int resourceIndex = 0;
-            for (final Iterator i = paintTarget.getPreCachedResources()
-                    .iterator(); i.hasNext();) {
+            for (final Iterator i = paintTarget.getUsedResources().iterator(); i
+                    .hasNext();) {
                 final String resource = (String) i.next();
                 InputStream is = null;
                 try {
@@ -598,6 +602,30 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
             }
             outWriter.print("}");
 
+            Collection<Class<? extends Paintable>> usedPaintableTypes = paintTarget
+                    .getUsedPaintableTypes();
+            boolean typeMappingsOpen = false;
+            for (Class<? extends Paintable> class1 : usedPaintableTypes) {
+                if (windowCache.cache(class1)) {
+                    // client does not know the mapping key for this type, send
+                    // mapping to client
+                    if (!typeMappingsOpen) {
+                        typeMappingsOpen = true;
+                        outWriter.print(", \"typeMappings\" : { ");
+                    } else {
+                        outWriter.print(" , ");
+                    }
+                    String canonicalName = class1.getCanonicalName();
+                    outWriter.print("\"");
+                    outWriter.print(canonicalName);
+                    outWriter.print("\" : ");
+                    outWriter.print(getTagForType(class1));
+                }
+            }
+            if (typeMappingsOpen) {
+                outWriter.print(" }");
+            }
+
             printLocaleDeclarations(outWriter);
 
             outWriter.print("}]");
@@ -774,6 +802,7 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
                         paintAfterVariablechanges(request, response,
                                 applicationServlet, true, outWriter, window,
                                 false);
+
                     } catch (ServletException e) {
                         // We will ignore all servlet exceptions
                     }
@@ -1093,9 +1122,9 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
         }
 
         // If the requested window is already open, resolve conflict
-        if (currentlyOpenWindowsInClient.contains(window.getName())) {
+        if (currentlyOpenWindowsInClient.containsKey(window.getName())) {
             String newWindowName = window.getName();
-            while (currentlyOpenWindowsInClient.contains(newWindowName)) {
+            while (currentlyOpenWindowsInClient.containsKey(newWindowName)) {
                 newWindowName = window.getName() + "_"
                         + ((int) (Math.random() * 100000000));
             }
@@ -1210,8 +1239,9 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
         // list. The result is that each component should be painted exactly
         // once and any unmodified components will be painted as "cached=true".
 
-        for (final Iterator i = dirtyPaintabletSet.iterator(); i.hasNext();) {
-            final Paintable p = (Paintable) i.next();
+        for (final Iterator<Paintable> i = dirtyPaintabletSet.iterator(); i
+                .hasNext();) {
+            final Paintable p = i.next();
             if (p instanceof Component) {
                 final Component component = (Component) p;
                 if (component.getApplication() == null) {
@@ -1528,4 +1558,37 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
             return null;
         }
     }
+
+    private static HashMap<Class<? extends Paintable>, Integer> typeToKey = new HashMap<Class<? extends Paintable>, Integer>();
+    private static int nextTypeKey = 0;
+
+    static String getTagForType(Class<? extends Paintable> class1) {
+        synchronized (typeToKey) {
+            Integer object = typeToKey.get(class1);
+            if (object == null) {
+                object = nextTypeKey++;
+                typeToKey.put(class1, object);
+            }
+            return object.toString();
+        }
+    }
+
+    /**
+     * Helper class for terminal to keep track of data that client is expected
+     * to know.
+     */
+    class OpenWindowCache {
+
+        private Set<Object> res = new HashSet<Object>();
+
+        /**
+         * 
+         * @param paintable
+         * @return true if the given class was added to cache
+         */
+        boolean cache(Object object) {
+            return res.add(object);
+        }
+
+    }
 }
index 4bb382d13dc6dec4bfc4ca20252d5237ce04fb31..3bd547ba9db5d9644d2521271b9fd9dab9ee96db 100644 (file)
@@ -9,6 +9,7 @@ import java.io.Serializable;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.Map;
 import java.util.Set;
 import java.util.Stack;
@@ -24,6 +25,7 @@ import com.vaadin.terminal.Resource;
 import com.vaadin.terminal.ThemeResource;
 import com.vaadin.terminal.VariableOwner;
 import com.vaadin.ui.Alignment;
+import com.vaadin.ui.ClientWidget;
 import com.vaadin.ui.Component;
 
 /**
@@ -53,7 +55,7 @@ public class JsonPaintTarget implements PaintTarget {
 
     private int changes = 0;
 
-    Set preCachedResources = new HashSet();
+    private Set<Object> usedResources = new HashSet<Object>();
 
     private boolean customLayoutArgumentsOpen = false;
 
@@ -67,6 +69,8 @@ public class JsonPaintTarget implements PaintTarget {
 
     private Collection<Paintable> identifiersCreatedDueRefPaint;
 
+    private Collection<Class<? extends Paintable>> usedPaintableTypes = new LinkedList<Class<? extends Paintable>>();
+
     /**
      * Creates a new XMLPrintWriter, without automatic line flushing.
      * 
@@ -472,7 +476,7 @@ public class JsonPaintTarget implements PaintTarget {
         tag.addAttribute("\"" + name + "\": \"" + escapeJSON(value) + "\"");
 
         if (customLayoutArgumentsOpen && "template".equals(name)) {
-            getPreCachedResources().add("layouts/" + value + ".html");
+            getUsedResources().add("layouts/" + value + ".html");
         }
 
         if (name.equals("locale")) {
@@ -1122,12 +1126,8 @@ public class JsonPaintTarget implements PaintTarget {
         }
     }
 
-    public Set getPreCachedResources() {
-        return preCachedResources;
-    }
-
-    public void setPreCachedResources(Set preCachedResources) {
-        throw new UnsupportedOperationException();
+    public Set<Object> getUsedResources() {
+        return usedResources;
     }
 
     /**
@@ -1146,4 +1146,36 @@ public class JsonPaintTarget implements PaintTarget {
             return true;
         }
     }
+
+    @SuppressWarnings("unchecked")
+    public String getTag(Paintable paintable) {
+        /*
+         * Client widget annotation is searched from component hierarchy to
+         * detect the component that presumably has client side implementation.
+         * The server side name is used in the transportation, but encoded into
+         * integer strings to optimized transferred data.
+         */
+        Class<? extends Paintable> class1 = paintable.getClass();
+        ClientWidget annotation = class1.getAnnotation(ClientWidget.class);
+        while (annotation == null) {
+            Class<?> superclass = class1.getSuperclass();
+            if (superclass != null
+                    && Paintable.class.isAssignableFrom(superclass)) {
+                class1 = (Class<? extends Paintable>) superclass;
+                annotation = class1.getAnnotation(ClientWidget.class);
+            } else {
+                System.out
+                        .append("Warning: no superclass of givent has ClientWidget"
+                                + " annotation. Component will not be mapped correctly on client side.");
+                break;
+            }
+        }
+        usedPaintableTypes.add(class1);
+        return CommunicationManager.getTagForType(class1);
+
+    }
+
+    Collection<Class<? extends Paintable>> getUsedPaintableTypes() {
+        return usedPaintableTypes;
+    }
 }
index d9f40d7253e598cd9e1e1e400e0ee958c70dec5b..678919ca0b45dcfe0853c40c1d1b2ab0c841e71c 100644 (file)
@@ -20,6 +20,7 @@ import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout;
  * 
  */
 @SuppressWarnings("serial")
+@ClientWidget(VAbsoluteLayout.class)
 public class AbsoluteLayout extends AbstractLayout {
 
     private Collection<Component> components = new LinkedHashSet<Component>();
index 39a0cf4f83151a0d4789348bd2339b17088d36f7..54dfccd60c514c0216e7aeb48d1860712293eb36 100644 (file)
@@ -146,8 +146,16 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * Gets the UIDL tag corresponding to the component.
      * 
      * @return the component's UIDL tag as <code>String</code>
+     * @deprecated tags are no more required for components. Instead of tags we
+     *             are now using {@link ClientWidget} annotations to map server
+     *             side components to client side counterparts. Generating
+     *             identifier for component type is delegated to terminal.
+     * @see ClientWidget
      */
-    public abstract String getTag();
+    @Deprecated
+    public String getTag() {
+        return "";
+    }
 
     public void setDebugId(String id) {
         testingId = id;
@@ -604,7 +612,8 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * here, we use the default documentation from implemented interface.
      */
     public final void paint(PaintTarget target) throws PaintException {
-        if (!target.startTag(this, getTag()) || repaintRequestListenersNotified) {
+        final String tag = target.getTag(this);
+        if (!target.startTag(this, tag) || repaintRequestListenersNotified) {
 
             // Paint the contents of the component
 
@@ -659,7 +668,7 @@ public abstract class AbstractComponent implements Component, MethodEventSource
             // Contents have not changed, only cached presentation can be used
             target.addAttribute("cached", true);
         }
-        target.endTag(getTag());
+        target.endTag(tag);
 
         repaintRequestListenersNotified = false;
     }
index 73b4c037434aa12b14543fd9da0c86c2c99d775b..a5db02dd8a0496691559b8fd6cca1a11adbfffe8 100644 (file)
@@ -1,6 +1,9 @@
 package com.vaadin.ui;
 
+import com.vaadin.terminal.gwt.client.ui.VAccordion;
+
 @SuppressWarnings("serial")
+@ClientWidget(VAccordion.class)
 public class Accordion extends TabSheet {
 
     @Override
index e4ca734d344767bff0346cfdf174fe5178024271..94337eded6c72c33436b2d791dfdea942812e98b 100644 (file)
@@ -12,6 +12,7 @@ import java.util.Map;
 import com.vaadin.data.Property;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VButton;
 
 /**
  * A generic button component.
@@ -22,6 +23,7 @@ import com.vaadin.terminal.PaintTarget;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VButton.class)
 public class Button extends AbstractField {
 
     /* Private members */
index 32b47412a39d2e025b5ac6ebaafd274029eb17e2..0ffafe3d02d47a4328cbc3becf5a3599cc937a49 100644 (file)
@@ -9,6 +9,7 @@ import java.lang.reflect.Method;
 import com.vaadin.data.Property;
 
 @SuppressWarnings("serial")
+@ClientWidget(com.vaadin.terminal.gwt.client.ui.VCheckBox.class)
 public class CheckBox extends Button {
     /**
      * Creates a new switch button.
@@ -47,8 +48,8 @@ public class CheckBox extends Button {
      * listening button clicks. Using this method is discouraged because it
      * cannot be checked during compilation. Use
      * {@link #addListener(Class, Object, Method)} or
-     * {@link #addListener(com.vaadin.ui.Component.Listener)} instead.
-     * The method must have either no parameters, or only one parameter of
+     * {@link #addListener(com.vaadin.ui.Component.Listener)} instead. The
+     * method must have either no parameters, or only one parameter of
      * Button.ClickEvent type.
      * 
      * @param caption
diff --git a/src/com/vaadin/ui/ClientWidget.java b/src/com/vaadin/ui/ClientWidget.java
new file mode 100644 (file)
index 0000000..2865c0d
--- /dev/null
@@ -0,0 +1,21 @@
+/**
+ * 
+ */
+package com.vaadin.ui;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.vaadin.terminal.gwt.client.Paintable;
+
+/**
+ * Annotation defining the default client side counterpart in GWT terminal for
+ * {@link Component}
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ClientWidget {
+    Class<? extends Paintable> value();
+}
index 65cfa36b28d21e445503bd53b86b31a7d07fde17..05d067d795a50cbc1d822e37ef8e86fca9341f56 100644 (file)
@@ -50,6 +50,7 @@ import com.vaadin.terminal.gwt.client.ui.VCssLayout;
  * @since 6.1 brought in from "FastLayouts" incubator project
  * 
  */
+@ClientWidget(VCssLayout.class)
 public class CssLayout extends AbstractLayout {
 
     private static final long serialVersionUID = -6408703812053460073L;
index 19fb0810477a290bc5094006372b1085dd64a149..e9ea19bf8a0abf713c645b73c643aba1d286ab32 100644 (file)
@@ -9,6 +9,7 @@ import java.util.Iterator;
 
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VCustomComponent;
 
 /**
  * Custom component provides simple implementation of Component interface for
@@ -25,6 +26,7 @@ import com.vaadin.terminal.PaintTarget;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VCustomComponent.class)
 public class CustomComponent extends AbstractComponentContainer {
 
     /**
index d0d70fcc162a84f24f7b950f6c116c748c24f8da..1dbd723759ab75fa485843b6011c40e8f42978d5 100644 (file)
@@ -12,6 +12,7 @@ import java.util.Iterator;
 
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VCustomLayout;
 
 /**
  * <p>
@@ -41,6 +42,7 @@ import com.vaadin.terminal.PaintTarget;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VCustomLayout.class)
 public class CustomLayout extends AbstractLayout {
 
     private static final int BUFFER_SIZE = 10000;
index dc062be66803f32fd13800c9805efec5522fe0d4..a0366258b9cc5c9bd1e2207437bd92153aff9644 100644 (file)
@@ -14,6 +14,7 @@ import java.util.Map;
 import com.vaadin.data.Property;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VPopupCalendar;
 
 /**
  * <p>
@@ -34,6 +35,7 @@ import com.vaadin.terminal.PaintTarget;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VPopupCalendar.class)
 public class DateField extends AbstractField {
 
     /* Private members */
index 3b0acfee5e7f22b2db4dafcfd765d6de0c939f51..c6d393922eea57638404e581cfe3b9b3da3f0115 100644 (file)
@@ -10,6 +10,7 @@ import java.util.Iterator;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
+import com.vaadin.terminal.gwt.client.ui.VEmbedded;
 
 /**
  * Component for embedding external objects.
@@ -20,6 +21,7 @@ import com.vaadin.terminal.Resource;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VEmbedded.class)
 public class Embedded extends AbstractComponent {
 
     /**
index 1741fe591f18c8a6a4b6ac2ef8e4085a6334ba94..5078c25fcc691c3dbcdb981441533ac39301e6b9 100644 (file)
@@ -21,6 +21,7 @@ import com.vaadin.terminal.CompositeErrorMessage;
 import com.vaadin.terminal.ErrorMessage;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VForm;
 
 /**
  * Form component provides easy way of creating and managing sets fields.
@@ -54,6 +55,7 @@ import com.vaadin.terminal.PaintTarget;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VForm.class)
 public class Form extends AbstractField implements Item.Editor, Buffered, Item,
         Validatable {
 
index 1fbfcf2ee4c92f5c928faf59c258b61e0c3c590c..fc6a8a21b95964579cd36d45b21a5594c55ce976 100644 (file)
@@ -4,6 +4,8 @@
 
 package com.vaadin.ui;
 
+import com.vaadin.terminal.gwt.client.ui.VFormLayout;
+
 /**
  * FormLayout is used by {@link Form} to layout fields. It may also be used
  * separately without {@link Form}.
@@ -20,6 +22,7 @@ package com.vaadin.ui;
  * 
  */
 @SuppressWarnings( { "deprecation", "serial" })
+@ClientWidget(VFormLayout.class)
 public class FormLayout extends OrderedLayout {
 
     public FormLayout() {
index 165b26491ef2370e52b9c33c8e8684513b35d4e8..1207944f12fcf342278272111ebce29db5355e8e 100644 (file)
@@ -14,6 +14,7 @@ import java.util.Map.Entry;
 
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VGridLayout;
 
 /**
  * <p>
@@ -36,6 +37,7 @@ import com.vaadin.terminal.PaintTarget;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VGridLayout.class)
 public class GridLayout extends AbstractLayout implements
         Layout.AlignmentHandler, Layout.SpacingHandler {
 
index 820b0c29de788fafb64deba2be46c086348ff2c1..16d677f6dc8c7b4baca4da2f618b07c651ef95c9 100644 (file)
@@ -1,5 +1,7 @@
 package com.vaadin.ui;
 
+import com.vaadin.terminal.gwt.client.ui.VHorizontalLayout;
+
 /**
  * Horizontal layout
  * 
@@ -12,6 +14,7 @@ package com.vaadin.ui;
  * @since 5.3
  */
 @SuppressWarnings("serial")
+@ClientWidget(VHorizontalLayout.class)
 public class HorizontalLayout extends AbstractOrderedLayout {
 
     public HorizontalLayout() {
index edd827d2a5ac21356774cb1053ae42db6a45da59..7c6727a1ba64c6c24ae1c77180c50bddbd1397db 100644 (file)
@@ -10,6 +10,7 @@ import com.vaadin.data.Property;
 import com.vaadin.data.util.ObjectProperty;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VLabel;
 
 /**
  * Label component for showing non-editable short texts.
@@ -37,6 +38,7 @@ import com.vaadin.terminal.PaintTarget;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VLabel.class)
 public class Label extends AbstractComponent implements Property,
         Property.Viewer, Property.ValueChangeListener,
         Property.ValueChangeNotifier, Comparable {
index 6deb05a99a1ed7d93d8df39fb20a3a8aa5b19747..3f8368593047ff192914c84b6fd203dfca3400e8 100644 (file)
@@ -7,6 +7,7 @@ package com.vaadin.ui;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
+import com.vaadin.terminal.gwt.client.ui.VLink;
 
 /**
  * Link is used to create external or internal URL links.
@@ -17,6 +18,7 @@ import com.vaadin.terminal.Resource;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VLink.class)
 public class Link extends AbstractComponent {
 
     /* Target window border type constant: No window border */
index 7860474433f3d74fdd2cf46a3878d7147346d48b..b2c4866b4a751695bf07c09359ee2b96a6417b17 100644 (file)
@@ -9,12 +9,14 @@ import java.util.Collection;
 import com.vaadin.data.Container;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VListSelect;
 
 /**
  * This is a simple list select without, for instance, support for new items,
  * lazyloading, and other advanced features.
  */
 @SuppressWarnings("serial")
+@ClientWidget(VListSelect.class)
 public class ListSelect extends AbstractSelect {
 
     private int columns = 0;
index 0ce6e725d98aa08832a66b4617cc1ff0c11fdf31..a77d57821a14699ae8386f973e1ef1da76289554 100644 (file)
@@ -10,6 +10,7 @@ import java.util.Stack;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
+import com.vaadin.terminal.gwt.client.ui.VMenuBar;
 
 /**
  * <p>
@@ -19,6 +20,7 @@ import com.vaadin.terminal.Resource;
  * </p>
  */
 @SuppressWarnings("serial")
+@ClientWidget(VMenuBar.class)
 public class MenuBar extends AbstractComponent {
 
     // Items of the top-level menu
@@ -340,10 +342,9 @@ public class MenuBar extends AbstractComponent {
 
     /**
      * This interface contains the layer for menu commands of the
-     * {@link com.vaadin.ui.MenuBar} class. It's method will fire when
-     * the user clicks on the containing
-     * {@link com.vaadin.ui.MenuBar.MenuItem}. The selected item is
-     * given as an argument.
+     * {@link com.vaadin.ui.MenuBar} class. It's method will fire when the user
+     * clicks on the containing {@link com.vaadin.ui.MenuBar.MenuItem}. The
+     * selected item is given as an argument.
      */
     public interface Command extends Serializable {
         public void menuSelected(MenuBar.MenuItem selectedItem);
@@ -498,8 +499,8 @@ public class MenuBar extends AbstractComponent {
          * For the containing item. This will return null if the item is in the
          * top-level menu bar.
          * 
-         * @return The containing {@link com.vaadin.ui.MenuBar.MenuItem}
-         *         , or null if there is none
+         * @return The containing {@link com.vaadin.ui.MenuBar.MenuItem} , or
+         *         null if there is none
          */
         public MenuBar.MenuItem getParent() {
             return itsParent;
index e178a39397df1e8b967c99f6c04d0ebdcb74f524..e57daeda559f185f7969f1263193d1c01a09f891 100644 (file)
@@ -9,6 +9,7 @@ import java.util.Collection;
 import com.vaadin.data.Container;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VNativeSelect;
 
 /**
  * This is a simple drop-down select without, for instance, support for
@@ -17,6 +18,7 @@ import com.vaadin.terminal.PaintTarget;
  * better choice.
  */
 @SuppressWarnings("serial")
+@ClientWidget(VNativeSelect.class)
 public class NativeSelect extends AbstractSelect {
 
     // width in characters, mimics TextField
index 861b57f5c6206c74f89270647b85a232ba188332..ab925f878589d6e8a80d261c595c4bce2e1f1c41 100644 (file)
@@ -9,11 +9,13 @@ import java.util.Collection;
 import com.vaadin.data.Container;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VOptionGroup;
 
 /**
  * Configures select to be used as an option group.
  */
 @SuppressWarnings("serial")
+@ClientWidget(VOptionGroup.class)
 public class OptionGroup extends AbstractSelect {
 
     public OptionGroup() {
index 572d6219192996a420c794a7bf290b9217a2528a..5689c76ed391b24dc27c6dcc5af1145a78da67d0 100644 (file)
@@ -2,6 +2,7 @@ package com.vaadin.ui;
 
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VOrderedLayout;
 
 /**
  * Ordered layout.
@@ -20,6 +21,7 @@ import com.vaadin.terminal.PaintTarget;
  */
 @SuppressWarnings("serial")
 @Deprecated
+@ClientWidget(VOrderedLayout.class)
 public class OrderedLayout extends AbstractOrderedLayout {
     /* Predefined orientations */
 
index b8c6b1f2227ac83eb8975783ced60b337f50909d..29d708a328c4197e7b1469ce7e8c013f5c034995 100644 (file)
@@ -15,6 +15,7 @@ import com.vaadin.terminal.KeyMapper;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Scrollable;
+import com.vaadin.terminal.gwt.client.ui.VPanel;
 
 /**
  * Panel - a simple single component container.
@@ -25,6 +26,7 @@ import com.vaadin.terminal.Scrollable;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VPanel.class)
 public class Panel extends AbstractComponentContainer implements Scrollable,
         ComponentContainer.ComponentAttachListener,
         ComponentContainer.ComponentDetachListener, Action.Container {
index f2d6259c75bfda71ee9d815a3df78630824d0a96..8184d60b65e81f82dab11ef468d208930a761629 100644 (file)
@@ -7,6 +7,7 @@ import java.util.Map;
 
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VPopupView;
 
 /**
  * 
@@ -18,6 +19,7 @@ import com.vaadin.terminal.PaintTarget;
  * @author IT Mill Ltd.
  */
 @SuppressWarnings("serial")
+@ClientWidget(VPopupView.class)
 public class PopupView extends AbstractComponentContainer {
 
     private Content content;
index 1ad5848dfbeb69936fd75a7b9b1297b1926d6494..bb346c26d5f5a76bf8746fc512179d0588e5d328 100644 (file)
@@ -8,6 +8,7 @@ import com.vaadin.data.Property;
 import com.vaadin.data.util.ObjectProperty;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VProgressIndicator;
 
 /**
  * <code>ProgressIndicator</code> is component that shows user state of a
@@ -24,6 +25,7 @@ import com.vaadin.terminal.PaintTarget;
  * @since 4
  */
 @SuppressWarnings("serial")
+@ClientWidget(VProgressIndicator.class)
 public class ProgressIndicator extends AbstractField implements Property,
         Property.Viewer, Property.ValueChangeListener {
 
index 4c1c281811134e11782f8ab2c606e07cbd5c32b6..49f329f586ef39767d3d0ebce706ae50919e70f1 100644 (file)
@@ -6,6 +6,7 @@ package com.vaadin.ui;
 
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.richtextarea.VRichTextArea;
 
 /**
  * A simple RichTextArea to edit HTML format text.
@@ -15,6 +16,7 @@ import com.vaadin.terminal.PaintTarget;
  * into length of field.
  */
 @SuppressWarnings("serial")
+@ClientWidget(VRichTextArea.class)
 public class RichTextArea extends TextField {
 
     @Override
index 6d07aff5b39629fd7f991a093719760ca64b21ce..899a9367659febfe48eacdeb1e8eee2e164a94d6 100644 (file)
@@ -16,6 +16,7 @@ import com.vaadin.data.Container;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
+import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
 
 /**
  * <p>
@@ -36,6 +37,7 @@ import com.vaadin.terminal.Resource;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VFilterSelect.class)
 public class Select extends AbstractSelect implements AbstractSelect.Filtering {
 
     /**
index ec9fc2c90bfb57b806adb67bb4dd8a1c62571b26..24dd520dddc39df466f541a258de8c97cf02cca4 100644 (file)
-/* \r
-@ITMillApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.ui;\r
-\r
-import java.util.Map;\r
-\r
-import com.vaadin.terminal.PaintException;\r
-import com.vaadin.terminal.PaintTarget;\r
-\r
-/**\r
- * A component for selecting a numerical value within a range.\r
- * \r
- * Example code: <code>\r
- *     class MyPlayer extends CustomComponent implements ValueChangeListener {\r
- *             \r
- *             Label volumeIndicator = new Label();\r
- *             Slider slider;\r
- *             \r
- *             public MyPlayer() {\r
- *                     VerticalLayout vl = new VerticalLayout();\r
- *                     setCompositionRoot(vl);\r
- *                     slider = new Slider("Volume", 0, 100);\r
- *                     slider.setImmediate(true);\r
- *                      slider.setValue(new Double(50));\r
- *                     vl.addComponent(slider);\r
- *                     vl.addComponent(volumeIndicator);\r
- *                     volumeIndicator.setValue("Current volume:" + 50.0);\r
- *                     slider.addListener(this);\r
- *                     \r
- *             }\r
- *             \r
- *             public void setVolume(double d) {\r
- *                     volumeIndicator.setValue("Current volume: " + d);\r
- *             }\r
- * \r
- *             public void valueChange(ValueChangeEvent event) {\r
- *                     Double d = (Double) event.getProperty().getValue();\r
- *                     setVolume(d.doubleValue());\r
- *             }\r
- *     }\r
- *\r
- * </code>\r
- * \r
- * @author IT Mill Ltd.\r
- */\r
-@SuppressWarnings("serial")\r
-public class Slider extends AbstractField {\r
-\r
-    public static final int ORIENTATION_HORIZONTAL = 0;\r
-\r
-    public static final int ORIENTATION_VERTICAL = 1;\r
-\r
-    /**\r
-     * Style constant representing a scrollbar styled slider. Use this with\r
-     * {@link #addStyleName(String)}. Default styling usually represents a\r
-     * common slider found e.g. in Adobe Photoshop. The client side\r
-     * implementation dictates how different styles will look.\r
-     */\r
-    @Deprecated\r
-    public static final String STYLE_SCROLLBAR = "scrollbar";\r
-\r
-    /** Minimum value of slider */\r
-    private double min = 0;\r
-\r
-    /** Maximum value of slider */\r
-    private double max = 100;\r
-\r
-    /**\r
-     * Resolution, how many digits are considered relevant after desimal point.\r
-     * Must be a non-negative value\r
-     */\r
-    private int resolution = 0;\r
-\r
-    /**\r
-     * Slider orientation (horizontal/vertical), defaults .\r
-     */\r
-    private int orientation = ORIENTATION_HORIZONTAL;\r
-\r
-    /**\r
-     * Slider size in pixels. In horizontal mode, if set to -1, allow 100% width\r
-     * of container. In vertical mode, if set to -1, default height is\r
-     * determined by the client-side implementation.\r
-     * \r
-     * @deprecated\r
-     */\r
-    @Deprecated\r
-    private int size = -1;\r
-\r
-    /**\r
-     * Handle (draggable control element) size in percents relative to base\r
-     * size. Must be a value between 1-99. Other values are converted to nearest\r
-     * bound. A negative value sets the width to auto (client-side\r
-     * implementation calculates).\r
-     * \r
-     * @deprecated The size is dictated by the current theme.\r
-     */\r
-    @Deprecated\r
-    private int handleSize = -1;\r
-\r
-    /**\r
-     * Show arrows that can be pressed to slide the handle in some increments\r
-     * (client-side implementation decides the increment, usually somewhere\r
-     * between 5-10% of slide range).\r
-     */\r
-    @Deprecated\r
-    private final boolean arrows = false;\r
-\r
-    /**\r
-     * Default Slider constructor. Sets all values to defaults and the slide\r
-     * handle at minimum value.\r
-     * \r
-     */\r
-    public Slider() {\r
-        super();\r
-        super.setValue(new Double(min));\r
-    }\r
-\r
-    /**\r
-     * Create a new slider with the caption given as parameter. All slider\r
-     * values set to defaults.\r
-     * \r
-     * @param caption\r
-     *            The caption for this Slider (e.g. "Volume").\r
-     */\r
-    public Slider(String caption) {\r
-        this();\r
-        setCaption(caption);\r
-    }\r
-\r
-    /**\r
-     * Create a new slider with given range and resolution\r
-     * \r
-     * @param min\r
-     * @param max\r
-     * @param resolution\r
-     */\r
-    public Slider(double min, double max, int resolution) {\r
-        this();\r
-        setMin(min);\r
-        setMax(max);\r
-        setResolution(resolution);\r
-    }\r
-\r
-    /**\r
-     * Create a new slider with given range\r
-     * \r
-     * @param min\r
-     * @param max\r
-     */\r
-    public Slider(int min, int max) {\r
-        this();\r
-        setMin(min);\r
-        setMax(max);\r
-        setResolution(0);\r
-    }\r
-\r
-    /**\r
-     * Create a new slider with given caption and range\r
-     * \r
-     * @param caption\r
-     * @param min\r
-     * @param max\r
-     */\r
-    public Slider(String caption, int min, int max) {\r
-        this(min, max);\r
-        setCaption(caption);\r
-    }\r
-\r
-    /**\r
-     * Gets the biggest possible value in Sliders range.\r
-     * \r
-     * @return the biggest value slider can have\r
-     */\r
-    public double getMax() {\r
-        return max;\r
-    }\r
-\r
-    /**\r
-     * Set the maximum value of the Slider. If the current value of the Slider\r
-     * is out of new bounds, the value is set to new minimum.\r
-     * \r
-     * @param max\r
-     *            New maximum value of the Slider.\r
-     */\r
-    public void setMax(double max) {\r
-        this.max = max;\r
-        try {\r
-            if ((new Double(getValue().toString())).doubleValue() > max) {\r
-                super.setValue(new Double(max));\r
-            }\r
-        } catch (final ClassCastException e) {\r
-            // FIXME: Handle exception\r
-            /*\r
-             * Where does ClassCastException come from? Can't see any casts\r
-             * above\r
-             */\r
-            super.setValue(new Double(max));\r
-        }\r
-        requestRepaint();\r
-    }\r
-\r
-    /**\r
-     * Gets the minimum value in Sliders range.\r
-     * \r
-     * @return the smalles value slider can have\r
-     */\r
-    public double getMin() {\r
-        return min;\r
-    }\r
-\r
-    /**\r
-     * Set the minimum value of the Slider. If the current value of the Slider\r
-     * is out of new bounds, the value is set to new minimum.\r
-     * \r
-     * @param min\r
-     *            New minimum value of the Slider.\r
-     */\r
-    public void setMin(double min) {\r
-        this.min = min;\r
-        try {\r
-            if ((new Double(getValue().toString())).doubleValue() < min) {\r
-                super.setValue(new Double(min));\r
-            }\r
-        } catch (final ClassCastException e) {\r
-            // FIXME: Handle exception\r
-            /*\r
-             * Where does ClassCastException come from? Can't see any casts\r
-             * above\r
-             */\r
-            super.setValue(new Double(min));\r
-        }\r
-        requestRepaint();\r
-    }\r
-\r
-    /**\r
-     * Get the current orientation of the Slider (horizontal or vertical).\r
-     * \r
-     * @return orientation\r
-     */\r
-    public int getOrientation() {\r
-        return orientation;\r
-    }\r
-\r
-    /**\r
-     * Set the orientation of the Slider.\r
-     * \r
-     * @param int new orientation\r
-     */\r
-    public void setOrientation(int orientation) {\r
-        this.orientation = orientation;\r
-        requestRepaint();\r
-    }\r
-\r
-    /**\r
-     * Get the current resolution of the Slider.\r
-     * \r
-     * @return resolution\r
-     */\r
-    public int getResolution() {\r
-        return resolution;\r
-    }\r
-\r
-    /**\r
-     * Set a new resolution for the Slider.\r
-     * \r
-     * @param resolution\r
-     */\r
-    public void setResolution(int resolution) {\r
-        if (resolution < 0) {\r
-            return;\r
-        }\r
-        this.resolution = resolution;\r
-        requestRepaint();\r
-    }\r
-\r
-    /**\r
-     * Set the value of this Slider.\r
-     * \r
-     * @param value\r
-     *            New value of Slider. Must be within Sliders range (min - max),\r
-     *            otherwise throws an exception.\r
-     * @param repaintIsNotNeeded\r
-     *            If true, client-side is not requested to repaint itself.\r
-     * @throws ValueOutOfBoundsException\r
-     */\r
-    public void setValue(Double value, boolean repaintIsNotNeeded)\r
-            throws ValueOutOfBoundsException {\r
-        final double v = value.doubleValue();\r
-        double newValue;\r
-        if (resolution > 0) {\r
-            // Round up to resolution\r
-            newValue = (int) (v * Math.pow(10, resolution));\r
-            newValue = newValue / Math.pow(10, resolution);\r
-            if (min > newValue || max < newValue) {\r
-                throw new ValueOutOfBoundsException(value);\r
-            }\r
-        } else {\r
-            newValue = (int) v;\r
-            if (min > newValue || max < newValue) {\r
-                throw new ValueOutOfBoundsException(value);\r
-            }\r
-        }\r
-        super.setValue(new Double(newValue), repaintIsNotNeeded);\r
-    }\r
-\r
-    /**\r
-     * Set the value of this Slider.\r
-     * \r
-     * @param value\r
-     *            New value of Slider. Must be within Sliders range (min - max),\r
-     *            otherwise throws an exception.\r
-     * @throws ValueOutOfBoundsException\r
-     */\r
-    public void setValue(Double value) throws ValueOutOfBoundsException {\r
-        setValue(value, false);\r
-    }\r
-\r
-    /**\r
-     * Set the value of this Slider.\r
-     * \r
-     * @param value\r
-     *            New value of Slider. Must be within Sliders range (min - max),\r
-     *            otherwise throws an exception.\r
-     * @throws ValueOutOfBoundsException\r
-     */\r
-    public void setValue(double value) throws ValueOutOfBoundsException {\r
-        setValue(new Double(value), false);\r
-    }\r
-\r
-    /**\r
-     * Get the current Slider size.\r
-     * \r
-     * @return size in pixels or -1 for auto sizing.\r
-     * @deprecated use standard getWidth/getHeight instead\r
-     */\r
-    @Deprecated\r
-    public int getSize() {\r
-        return size;\r
-    }\r
-\r
-    /**\r
-     * Set the size for this Slider.\r
-     * \r
-     * @param size\r
-     *            in pixels, or -1 auto sizing.\r
-     * @deprecated use standard setWidth/setHeight instead\r
-     */\r
-    @Deprecated\r
-    public void setSize(int size) {\r
-        this.size = size;\r
-        switch (orientation) {\r
-        case ORIENTATION_HORIZONTAL:\r
-            setWidth(size, UNITS_PIXELS);\r
-            break;\r
-        default:\r
-            setHeight(size, UNITS_PIXELS);\r
-            break;\r
-        }\r
-        requestRepaint();\r
-    }\r
-\r
-    /**\r
-     * Get the handle size of this Slider.\r
-     * \r
-     * @return handle size in percentages.\r
-     * @deprecated The size is dictated by the current theme.\r
-     */\r
-    @Deprecated\r
-    public int getHandleSize() {\r
-        return handleSize;\r
-    }\r
-\r
-    /**\r
-     * Set the handle size of this Slider.\r
-     * \r
-     * @param handleSize\r
-     *            in percentages relative to slider base size.\r
-     * @deprecated The size is dictated by the current theme.\r
-     */\r
-    @Deprecated\r
-    public void setHandleSize(int handleSize) {\r
-        if (handleSize < 0) {\r
-            this.handleSize = -1;\r
-        } else if (handleSize > 99) {\r
-            this.handleSize = 99;\r
-        } else if (handleSize < 1) {\r
-            this.handleSize = 1;\r
-        } else {\r
-            this.handleSize = handleSize;\r
-        }\r
-        requestRepaint();\r
-    }\r
-\r
-    @Override\r
-    public String getTag() {\r
-        return "slider";\r
-    }\r
-\r
-    @Override\r
-    public void paintContent(PaintTarget target) throws PaintException {\r
-        super.paintContent(target);\r
-\r
-        target.addAttribute("min", min);\r
-        if (max > min) {\r
-            target.addAttribute("max", max);\r
-        } else {\r
-            target.addAttribute("max", min);\r
-        }\r
-        target.addAttribute("resolution", resolution);\r
-\r
-        if (resolution > 0) {\r
-            target.addVariable(this, "value", ((Double) getValue())\r
-                    .doubleValue());\r
-        } else {\r
-            target.addVariable(this, "value", ((Double) getValue()).intValue());\r
-        }\r
-\r
-        if (orientation == ORIENTATION_VERTICAL) {\r
-            target.addAttribute("vertical", true);\r
-        }\r
-\r
-        if (arrows) {\r
-            target.addAttribute("arrows", true);\r
-        }\r
-\r
-        if (size > -1) {\r
-            target.addAttribute("size", size);\r
-        }\r
-\r
-        if (min != max && min < max) {\r
-            target.addAttribute("hsize", handleSize);\r
-        } else {\r
-            target.addAttribute("hsize", 100);\r
-        }\r
-\r
-    }\r
-\r
-    /**\r
-     * Invoked when the value of a variable has changed. Slider listeners are\r
-     * notified if the slider value has changed.\r
-     * \r
-     * @param source\r
-     * @param variables\r
-     */\r
-    @Override\r
-    public void changeVariables(Object source, Map variables) {\r
-        super.changeVariables(source, variables);\r
-        if (variables.containsKey("value")) {\r
-            final Object value = variables.get("value");\r
-            final Double newValue = new Double(value.toString());\r
-            if (newValue != null && newValue != getValue()\r
-                    && !newValue.equals(getValue())) {\r
-                try {\r
-                    setValue(newValue, true);\r
-                } catch (final ValueOutOfBoundsException e) {\r
-                    // Convert to nearest bound\r
-                    double out = e.getValue().doubleValue();\r
-                    if (out < min) {\r
-                        out = min;\r
-                    }\r
-                    if (out > max) {\r
-                        out = max;\r
-                    }\r
-                    super.setValue(new Double(out), false);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * ValueOutOfBoundsException\r
-     * \r
-     * @author IT Mill Ltd.\r
-     * \r
-     */\r
-    public class ValueOutOfBoundsException extends Exception {\r
-\r
-        private final Double value;\r
-\r
-        /**\r
-         * Constructs an <code>ValueOutOfBoundsException</code> with the\r
-         * specified detail message.\r
-         * \r
-         * @param valueOutOfBounds\r
-         */\r
-        public ValueOutOfBoundsException(Double valueOutOfBounds) {\r
-            value = valueOutOfBounds;\r
-        }\r
-\r
-        public Double getValue() {\r
-            return value;\r
-        }\r
-\r
-    }\r
-\r
-    @Override\r
-    public Class getType() {\r
-        return Double.class;\r
-    }\r
-\r
-}\r
+/* 
+@ITMillApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import java.util.Map;
+
+import com.vaadin.terminal.PaintException;
+import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VSlider;
+
+/**
+ * A component for selecting a numerical value within a range.
+ * 
+ * Example code: <code>
+ *     class MyPlayer extends CustomComponent implements ValueChangeListener {
+ *             
+ *             Label volumeIndicator = new Label();
+ *             Slider slider;
+ *             
+ *             public MyPlayer() {
+ *                     VerticalLayout vl = new VerticalLayout();
+ *                     setCompositionRoot(vl);
+ *                     slider = new Slider("Volume", 0, 100);
+ *                     slider.setImmediate(true);
+ *                      slider.setValue(new Double(50));
+ *                     vl.addComponent(slider);
+ *                     vl.addComponent(volumeIndicator);
+ *                     volumeIndicator.setValue("Current volume:" + 50.0);
+ *                     slider.addListener(this);
+ *                     
+ *             }
+ *             
+ *             public void setVolume(double d) {
+ *                     volumeIndicator.setValue("Current volume: " + d);
+ *             }
+ * 
+ *             public void valueChange(ValueChangeEvent event) {
+ *                     Double d = (Double) event.getProperty().getValue();
+ *                     setVolume(d.doubleValue());
+ *             }
+ *     }
+ *
+ * </code>
+ * 
+ * @author IT Mill Ltd.
+ */
+@SuppressWarnings("serial")
+@ClientWidget(VSlider.class)
+public class Slider extends AbstractField {
+
+    public static final int ORIENTATION_HORIZONTAL = 0;
+
+    public static final int ORIENTATION_VERTICAL = 1;
+
+    /**
+     * Style constant representing a scrollbar styled slider. Use this with
+     * {@link #addStyleName(String)}. Default styling usually represents a
+     * common slider found e.g. in Adobe Photoshop. The client side
+     * implementation dictates how different styles will look.
+     */
+    @Deprecated
+    public static final String STYLE_SCROLLBAR = "scrollbar";
+
+    /** Minimum value of slider */
+    private double min = 0;
+
+    /** Maximum value of slider */
+    private double max = 100;
+
+    /**
+     * Resolution, how many digits are considered relevant after desimal point.
+     * Must be a non-negative value
+     */
+    private int resolution = 0;
+
+    /**
+     * Slider orientation (horizontal/vertical), defaults .
+     */
+    private int orientation = ORIENTATION_HORIZONTAL;
+
+    /**
+     * Slider size in pixels. In horizontal mode, if set to -1, allow 100% width
+     * of container. In vertical mode, if set to -1, default height is
+     * determined by the client-side implementation.
+     * 
+     * @deprecated
+     */
+    @Deprecated
+    private int size = -1;
+
+    /**
+     * Handle (draggable control element) size in percents relative to base
+     * size. Must be a value between 1-99. Other values are converted to nearest
+     * bound. A negative value sets the width to auto (client-side
+     * implementation calculates).
+     * 
+     * @deprecated The size is dictated by the current theme.
+     */
+    @Deprecated
+    private int handleSize = -1;
+
+    /**
+     * Show arrows that can be pressed to slide the handle in some increments
+     * (client-side implementation decides the increment, usually somewhere
+     * between 5-10% of slide range).
+     */
+    @Deprecated
+    private final boolean arrows = false;
+
+    /**
+     * Default Slider constructor. Sets all values to defaults and the slide
+     * handle at minimum value.
+     * 
+     */
+    public Slider() {
+        super();
+        super.setValue(new Double(min));
+    }
+
+    /**
+     * Create a new slider with the caption given as parameter. All slider
+     * values set to defaults.
+     * 
+     * @param caption
+     *            The caption for this Slider (e.g. "Volume").
+     */
+    public Slider(String caption) {
+        this();
+        setCaption(caption);
+    }
+
+    /**
+     * Create a new slider with given range and resolution
+     * 
+     * @param min
+     * @param max
+     * @param resolution
+     */
+    public Slider(double min, double max, int resolution) {
+        this();
+        setMin(min);
+        setMax(max);
+        setResolution(resolution);
+    }
+
+    /**
+     * Create a new slider with given range
+     * 
+     * @param min
+     * @param max
+     */
+    public Slider(int min, int max) {
+        this();
+        setMin(min);
+        setMax(max);
+        setResolution(0);
+    }
+
+    /**
+     * Create a new slider with given caption and range
+     * 
+     * @param caption
+     * @param min
+     * @param max
+     */
+    public Slider(String caption, int min, int max) {
+        this(min, max);
+        setCaption(caption);
+    }
+
+    /**
+     * Gets the biggest possible value in Sliders range.
+     * 
+     * @return the biggest value slider can have
+     */
+    public double getMax() {
+        return max;
+    }
+
+    /**
+     * Set the maximum value of the Slider. If the current value of the Slider
+     * is out of new bounds, the value is set to new minimum.
+     * 
+     * @param max
+     *            New maximum value of the Slider.
+     */
+    public void setMax(double max) {
+        this.max = max;
+        try {
+            if ((new Double(getValue().toString())).doubleValue() > max) {
+                super.setValue(new Double(max));
+            }
+        } catch (final ClassCastException e) {
+            // FIXME: Handle exception
+            /*
+             * Where does ClassCastException come from? Can't see any casts
+             * above
+             */
+            super.setValue(new Double(max));
+        }
+        requestRepaint();
+    }
+
+    /**
+     * Gets the minimum value in Sliders range.
+     * 
+     * @return the smalles value slider can have
+     */
+    public double getMin() {
+        return min;
+    }
+
+    /**
+     * Set the minimum value of the Slider. If the current value of the Slider
+     * is out of new bounds, the value is set to new minimum.
+     * 
+     * @param min
+     *            New minimum value of the Slider.
+     */
+    public void setMin(double min) {
+        this.min = min;
+        try {
+            if ((new Double(getValue().toString())).doubleValue() < min) {
+                super.setValue(new Double(min));
+            }
+        } catch (final ClassCastException e) {
+            // FIXME: Handle exception
+            /*
+             * Where does ClassCastException come from? Can't see any casts
+             * above
+             */
+            super.setValue(new Double(min));
+        }
+        requestRepaint();
+    }
+
+    /**
+     * Get the current orientation of the Slider (horizontal or vertical).
+     * 
+     * @return orientation
+     */
+    public int getOrientation() {
+        return orientation;
+    }
+
+    /**
+     * Set the orientation of the Slider.
+     * 
+     * @param int new orientation
+     */
+    public void setOrientation(int orientation) {
+        this.orientation = orientation;
+        requestRepaint();
+    }
+
+    /**
+     * Get the current resolution of the Slider.
+     * 
+     * @return resolution
+     */
+    public int getResolution() {
+        return resolution;
+    }
+
+    /**
+     * Set a new resolution for the Slider.
+     * 
+     * @param resolution
+     */
+    public void setResolution(int resolution) {
+        if (resolution < 0) {
+            return;
+        }
+        this.resolution = resolution;
+        requestRepaint();
+    }
+
+    /**
+     * Set the value of this Slider.
+     * 
+     * @param value
+     *            New value of Slider. Must be within Sliders range (min - max),
+     *            otherwise throws an exception.
+     * @param repaintIsNotNeeded
+     *            If true, client-side is not requested to repaint itself.
+     * @throws ValueOutOfBoundsException
+     */
+    public void setValue(Double value, boolean repaintIsNotNeeded)
+            throws ValueOutOfBoundsException {
+        final double v = value.doubleValue();
+        double newValue;
+        if (resolution > 0) {
+            // Round up to resolution
+            newValue = (int) (v * Math.pow(10, resolution));
+            newValue = newValue / Math.pow(10, resolution);
+            if (min > newValue || max < newValue) {
+                throw new ValueOutOfBoundsException(value);
+            }
+        } else {
+            newValue = (int) v;
+            if (min > newValue || max < newValue) {
+                throw new ValueOutOfBoundsException(value);
+            }
+        }
+        super.setValue(new Double(newValue), repaintIsNotNeeded);
+    }
+
+    /**
+     * Set the value of this Slider.
+     * 
+     * @param value
+     *            New value of Slider. Must be within Sliders range (min - max),
+     *            otherwise throws an exception.
+     * @throws ValueOutOfBoundsException
+     */
+    public void setValue(Double value) throws ValueOutOfBoundsException {
+        setValue(value, false);
+    }
+
+    /**
+     * Set the value of this Slider.
+     * 
+     * @param value
+     *            New value of Slider. Must be within Sliders range (min - max),
+     *            otherwise throws an exception.
+     * @throws ValueOutOfBoundsException
+     */
+    public void setValue(double value) throws ValueOutOfBoundsException {
+        setValue(new Double(value), false);
+    }
+
+    /**
+     * Get the current Slider size.
+     * 
+     * @return size in pixels or -1 for auto sizing.
+     * @deprecated use standard getWidth/getHeight instead
+     */
+    @Deprecated
+    public int getSize() {
+        return size;
+    }
+
+    /**
+     * Set the size for this Slider.
+     * 
+     * @param size
+     *            in pixels, or -1 auto sizing.
+     * @deprecated use standard setWidth/setHeight instead
+     */
+    @Deprecated
+    public void setSize(int size) {
+        this.size = size;
+        switch (orientation) {
+        case ORIENTATION_HORIZONTAL:
+            setWidth(size, UNITS_PIXELS);
+            break;
+        default:
+            setHeight(size, UNITS_PIXELS);
+            break;
+        }
+        requestRepaint();
+    }
+
+    /**
+     * Get the handle size of this Slider.
+     * 
+     * @return handle size in percentages.
+     * @deprecated The size is dictated by the current theme.
+     */
+    @Deprecated
+    public int getHandleSize() {
+        return handleSize;
+    }
+
+    /**
+     * Set the handle size of this Slider.
+     * 
+     * @param handleSize
+     *            in percentages relative to slider base size.
+     * @deprecated The size is dictated by the current theme.
+     */
+    @Deprecated
+    public void setHandleSize(int handleSize) {
+        if (handleSize < 0) {
+            this.handleSize = -1;
+        } else if (handleSize > 99) {
+            this.handleSize = 99;
+        } else if (handleSize < 1) {
+            this.handleSize = 1;
+        } else {
+            this.handleSize = handleSize;
+        }
+        requestRepaint();
+    }
+
+    @Override
+    public String getTag() {
+        return "slider";
+    }
+
+    @Override
+    public void paintContent(PaintTarget target) throws PaintException {
+        super.paintContent(target);
+
+        target.addAttribute("min", min);
+        if (max > min) {
+            target.addAttribute("max", max);
+        } else {
+            target.addAttribute("max", min);
+        }
+        target.addAttribute("resolution", resolution);
+
+        if (resolution > 0) {
+            target.addVariable(this, "value", ((Double) getValue())
+                    .doubleValue());
+        } else {
+            target.addVariable(this, "value", ((Double) getValue()).intValue());
+        }
+
+        if (orientation == ORIENTATION_VERTICAL) {
+            target.addAttribute("vertical", true);
+        }
+
+        if (arrows) {
+            target.addAttribute("arrows", true);
+        }
+
+        if (size > -1) {
+            target.addAttribute("size", size);
+        }
+
+        if (min != max && min < max) {
+            target.addAttribute("hsize", handleSize);
+        } else {
+            target.addAttribute("hsize", 100);
+        }
+
+    }
+
+    /**
+     * Invoked when the value of a variable has changed. Slider listeners are
+     * notified if the slider value has changed.
+     * 
+     * @param source
+     * @param variables
+     */
+    @Override
+    public void changeVariables(Object source, Map variables) {
+        super.changeVariables(source, variables);
+        if (variables.containsKey("value")) {
+            final Object value = variables.get("value");
+            final Double newValue = new Double(value.toString());
+            if (newValue != null && newValue != getValue()
+                    && !newValue.equals(getValue())) {
+                try {
+                    setValue(newValue, true);
+                } catch (final ValueOutOfBoundsException e) {
+                    // Convert to nearest bound
+                    double out = e.getValue().doubleValue();
+                    if (out < min) {
+                        out = min;
+                    }
+                    if (out > max) {
+                        out = max;
+                    }
+                    super.setValue(new Double(out), false);
+                }
+            }
+        }
+    }
+
+    /**
+     * ValueOutOfBoundsException
+     * 
+     * @author IT Mill Ltd.
+     * 
+     */
+    public class ValueOutOfBoundsException extends Exception {
+
+        private final Double value;
+
+        /**
+         * Constructs an <code>ValueOutOfBoundsException</code> with the
+         * specified detail message.
+         * 
+         * @param valueOutOfBounds
+         */
+        public ValueOutOfBoundsException(Double valueOutOfBounds) {
+            value = valueOutOfBounds;
+        }
+
+        public Double getValue() {
+            return value;
+        }
+
+    }
+
+    @Override
+    public Class getType() {
+        return Double.class;
+    }
+
+}
index 8e67f9c41ac958822469eeaa9882f76559e60773..956eefc62b0a919dd9d83c36dbe22836c33dc720 100644 (file)
@@ -10,6 +10,7 @@ import java.util.Map;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Sizeable;
+import com.vaadin.terminal.gwt.client.ui.VSplitPanelHorizontal;
 
 /**
  * SplitPanel.
@@ -23,6 +24,7 @@ import com.vaadin.terminal.Sizeable;
  * @since 5.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VSplitPanelHorizontal.class)
 public class SplitPanel extends AbstractLayout {
 
     /* Predefined orientations */
@@ -80,11 +82,7 @@ public class SplitPanel extends AbstractLayout {
      */
     @Override
     public String getTag() {
-        if (orientation == ORIENTATION_HORIZONTAL) {
-            return "hsplitpanel";
-        } else {
-            return "vsplitpanel";
-        }
+        return "splitpanel";
     }
 
     /**
@@ -218,6 +216,10 @@ public class SplitPanel extends AbstractLayout {
 
         final String position = pos + UNIT_SYMBOLS[posUnit];
 
+        if (orientation == ORIENTATION_VERTICAL) {
+            target.addAttribute("vertical", true);
+        }
+
         target.addAttribute("position", position);
 
         if (isLocked()) {
index f86890237525f6a32fd8384948a82c0fadd59ddc..71a4ca8cf250146bcc5fbceb2b35d8195360e9ea 100644 (file)
@@ -17,6 +17,7 @@ import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
 import com.vaadin.terminal.Paintable.RepaintRequestListener;
+import com.vaadin.terminal.gwt.client.ui.VTabsheet;
 
 /**
  * Tabsheet component.
@@ -27,6 +28,7 @@ import com.vaadin.terminal.Paintable.RepaintRequestListener;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VTabsheet.class)
 public class TabSheet extends AbstractComponentContainer implements
         RepaintRequestListener {
 
index 4ba0a9cbc774697f32b1b5e5f01f39e7eee7124c..1a106becc12ff67cfd7129d03ba9f730eaefcd0c 100644 (file)
@@ -32,25 +32,27 @@ import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
+import com.vaadin.terminal.gwt.client.ui.VScrollTable;
 
 /**
  * <p>
  * <code>TableComponent</code> is used for representing data or components in
  * pageable and selectable table.
  * </p>
- *
+ * 
  * <p>
  * Note! Since version 5, components in Table will not have their caption nor
  * icon rendered. In order to workaround this limitation, wrap your component in
  * a Layout.
  * </p>
- *
+ * 
  * @author IT Mill Ltd.
  * @version
  * @VERSION@
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VScrollTable.class)
 public class Table extends AbstractSelect implements Action.Container,
         Container.Ordered, Container.Sortable, ItemClickSource {
 
@@ -338,7 +340,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Creates a new empty table with caption.
-     *
+     * 
      * @param caption
      */
     public Table(String caption) {
@@ -348,7 +350,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Creates a new table with caption and connect it to a Container.
-     *
+     * 
      * @param caption
      * @param dataSource
      */
@@ -362,11 +364,11 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the array of visible column id:s, including generated columns.
-     *
+     * 
      * <p>
      * The columns are show in the order of their appearance in this array.
      * </p>
-     *
+     * 
      * @return an array of currently visible propertyIds and generated column
      *         ids.
      */
@@ -379,11 +381,11 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the array of visible column property id:s.
-     *
+     * 
      * <p>
      * The columns are show in the order of their appearance in this array.
      * </p>
-     *
+     * 
      * @param visibleColumns
      *            the Array of shown property id:s.
      */
@@ -445,7 +447,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the headers of the columns.
-     *
+     * 
      * <p>
      * The headers match the property id:s given my the set visible column
      * headers. The table must be set in either
@@ -454,7 +456,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * headers. In the defaults mode any nulls in the headers array are replaced
      * with id.toString() outputs when rendering.
      * </p>
-     *
+     * 
      * @return the Array of column headers.
      */
     public String[] getColumnHeaders() {
@@ -472,7 +474,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the headers of the columns.
-     *
+     * 
      * <p>
      * The headers match the property id:s given my the set visible column
      * headers. The table must be set in either
@@ -481,7 +483,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * headers. In the defaults mode any nulls in the headers array are replaced
      * with id.toString() outputs when rendering.
      * </p>
-     *
+     * 
      * @param columnHeaders
      *            the Array of column headers that match the
      *            <code>getVisibleColumns</code> method.
@@ -508,7 +510,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the icons of the columns.
-     *
+     * 
      * <p>
      * The icons in headers match the property id:s given my the set visible
      * column headers. The table must be set in either
@@ -516,7 +518,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * <code>COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID</code> mode to show the
      * headers with icons.
      * </p>
-     *
+     * 
      * @return the Array of icons that match the <code>getVisibleColumns</code>.
      */
     public Resource[] getColumnIcons() {
@@ -535,7 +537,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the icons of the columns.
-     *
+     * 
      * <p>
      * The icons in headers match the property id:s given my the set visible
      * column headers. The table must be set in either
@@ -543,7 +545,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * <code>COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID</code> mode to show the
      * headers with icons.
      * </p>
-     *
+     * 
      * @param columnIcons
      *            the Array of icons that match the
      *            <code>getVisibleColumns</code>.
@@ -570,7 +572,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the array of column alignments.
-     *
+     * 
      * <p>
      * The items in the array must match the properties identified by
      * <code>getVisibleColumns()</code>. The possible values for the alignments
@@ -583,7 +585,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * The alignments default to <code>ALIGN_LEFT</code>: any null values are
      * rendered as align lefts.
      * </p>
-     *
+     * 
      * @return the Column alignments array.
      */
     public String[] getColumnAlignments() {
@@ -602,7 +604,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the column alignments.
-     *
+     * 
      * <p>
      * The items in the array must match the properties identified by
      * <code>getVisibleColumns()</code>. The possible values for the alignments
@@ -614,7 +616,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * </ul>
      * The alignments default to <code>ALIGN_LEFT</code>
      * </p>
-     *
+     * 
      * @param columnAlignments
      *            the Column alignments array.
      */
@@ -654,11 +656,11 @@ public class Table extends AbstractSelect implements Action.Container,
      * Sets columns width (in pixels). Theme may not necessary respect very
      * small or very big values. Setting width to -1 (default) means that theme
      * will make decision of width.
-     *
+     * 
      *<p>
      * Column can either have a fixed width or expand ratio. The latter one set
      * is used. See @link {@link #setColumnExpandRatio(Object, float)}.
-     *
+     * 
      * @param columnId
      *            colunmns property id
      * @param width
@@ -682,27 +684,27 @@ public class Table extends AbstractSelect implements Action.Container,
      * naturally. Excess space is the space that is not used by columns with
      * explicit width (see {@link #setColumnWidth(Object, int)}) or with natural
      * width (no width nor expand ratio).
-     *
+     * 
      * <p>
      * By default (without expand ratios) the excess space is divided
      * proportionally to columns natural widths.
-     *
+     * 
      * <p>
      * Only expand ratios of visible columns are used in final calculations.
-     *
+     * 
      * <p>
      * Column can either have a fixed width or expand ratio. The latter one set
      * is used.
-     *
+     * 
      * <p>
      * A column with expand ratio is considered to be minimum width by default
      * (if no excess space exists). The minimum width is defined by terminal
      * implementation.
-     *
+     * 
      * <p>
      * If terminal implementation supports re-sizeable columns the column
      * becomes fixed width column if users resizes the column.
-     *
+     * 
      * @param columnId
      *            colunmns property id
      * @param expandRatio
@@ -728,7 +730,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the pixel width of column
-     *
+     * 
      * @param propertyId
      * @return width of colun or -1 when value not set
      */
@@ -743,11 +745,11 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the page length.
-     *
+     * 
      * <p>
      * Setting page length 0 disables paging.
      * </p>
-     *
+     * 
      * @return the Length of one page.
      */
     public int getPageLength() {
@@ -756,16 +758,16 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the page length.
-     *
+     * 
      * <p>
      * Setting page length 0 disables paging. The page length defaults to 15.
      * </p>
-     *
+     * 
      * <p>
      * If Table has width set ({@link #setWidth(float, int)} ) the client side
      * may update the page length automatically the correct value.
      * </p>
-     *
+     * 
      * @param pageLength
      *            the length of one page.
      */
@@ -780,18 +782,18 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * This method adjusts a possible caching mechanism of table implementation.
-     *
+     * 
      * <p>
      * Table component may fetch and render some rows outside visible area. With
      * complex tables (for example containing layouts and components), the
      * client side may become unresponsive. Setting the value lower, UI will
      * become more responsive. With higher values scrolling in client will hit
      * server less frequently.
-     *
+     * 
      * <p>
      * The amount of cached rows will be cacheRate multiplied with pageLength (
      * {@link #setPageLength(int)} both below and above visible area..
-     *
+     * 
      * @param cacheRate
      *            a value over 0 (fastest rendering time). Higher value will
      *            cache more rows on server (smoother scrolling). Default value
@@ -810,7 +812,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * @see #setCacheRate(double)
-     *
+     * 
      * @return the current cache rate value
      */
     public double getCacheRate() {
@@ -819,7 +821,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Getter for property currentPageFirstItem.
-     *
+     * 
      * @return the Value of property currentPageFirstItem.
      */
     public Object getCurrentPageFirstItemId() {
@@ -846,7 +848,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Setter for property currentPageFirstItemId.
-     *
+     * 
      * @param currentPageFirstItemId
      *            the New value of property currentPageFirstItemId.
      */
@@ -899,7 +901,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the icon Resource for the specified column.
-     *
+     * 
      * @param propertyId
      *            the propertyId indentifying the column.
      * @return the icon for the specified column; null if the column has no icon
@@ -914,7 +916,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * <p>
      * Throws IllegalArgumentException if the specified column is not visible.
      * </p>
-     *
+     * 
      * @param propertyId
      *            the propertyId identifying the column.
      * @param icon
@@ -935,7 +937,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the header for the specified column.
-     *
+     * 
      * @param propertyId
      *            the propertyId indentifying the column.
      * @return the header for the specifed column if it has one.
@@ -956,7 +958,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the column header for the specified column;
-     *
+     * 
      * @param propertyId
      *            the propertyId indentifying the column.
      * @param header
@@ -976,7 +978,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the specified column's alignment.
-     *
+     * 
      * @param propertyId
      *            the propertyID identifying the column.
      * @return the specified column's alignment if it as one; null otherwise.
@@ -988,12 +990,12 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the specified column's alignment.
-     *
+     * 
      * <p>
      * Throws IllegalArgumentException if the alignment is not one of the
      * following: ALIGN_LEFT, ALIGN_CENTER or ALIGN_RIGHT
      * </p>
-     *
+     * 
      * @param propertyId
      *            the propertyID identifying the column.
      * @param alignment
@@ -1022,7 +1024,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Checks if the specified column is collapsed.
-     *
+     * 
      * @param propertyId
      *            the propertyID identifying the column.
      * @return true if the column is collapsed; false otherwise;
@@ -1034,8 +1036,8 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets whether the specified column is collapsed or not.
-     *
-     *
+     * 
+     * 
      * @param propertyId
      *            the propertyID identifying the column.
      * @param collapsed
@@ -1061,7 +1063,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Checks if column collapsing is allowed.
-     *
+     * 
      * @return true if columns can be collapsed; false otherwise.
      */
     public boolean isColumnCollapsingAllowed() {
@@ -1070,7 +1072,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets whether column collapsing is allowed or not.
-     *
+     * 
      * @param collapsingAllowed
      *            specifies whether column collapsing is allowed.
      */
@@ -1087,7 +1089,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Checks if column reordering is allowed.
-     *
+     * 
      * @return true if columns can be reordered; false otherwise.
      */
     public boolean isColumnReorderingAllowed() {
@@ -1096,7 +1098,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets whether column reordering is allowed or not.
-     *
+     * 
      * @param reorderingAllowed
      *            specifies whether column reordering is allowed.
      */
@@ -1141,7 +1143,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Getter for property currentPageFirstItem.
-     *
+     * 
      * @return the Value of property currentPageFirstItem.
      */
     public int getCurrentPageFirstItemIndex() {
@@ -1245,7 +1247,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Setter for property currentPageFirstItem.
-     *
+     * 
      * @param newIndex
      *            the New value of property currentPageFirstItem.
      */
@@ -1255,9 +1257,9 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Getter for property pageBuffering.
-     *
+     * 
      * @deprecated functionality is not needed in ajax rendering model
-     *
+     * 
      * @return the Value of property pageBuffering.
      */
     @Deprecated
@@ -1267,9 +1269,9 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Setter for property pageBuffering.
-     *
+     * 
      * @deprecated functionality is not needed in ajax rendering model
-     *
+     * 
      * @param pageBuffering
      *            the New value of property pageBuffering.
      */
@@ -1280,11 +1282,11 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Getter for property selectable.
-     *
+     * 
      * <p>
      * The table is not selectable by default.
      * </p>
-     *
+     * 
      * @return the Value of property selectable.
      */
     public boolean isSelectable() {
@@ -1293,11 +1295,11 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Setter for property selectable.
-     *
+     * 
      * <p>
      * The table is not selectable by default.
      * </p>
-     *
+     * 
      * @param selectable
      *            the New value of property selectable.
      */
@@ -1310,7 +1312,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Getter for property columnHeaderMode.
-     *
+     * 
      * @return the Value of property columnHeaderMode.
      */
     public int getColumnHeaderMode() {
@@ -1319,7 +1321,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Setter for property columnHeaderMode.
-     *
+     * 
      * @param columnHeaderMode
      *            the New value of property columnHeaderMode.
      */
@@ -1568,7 +1570,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * Helper method to remove listeners and maintain correct component
      * hierarchy. Detaches properties and components if those are no more
      * rendered in client.
-     *
+     * 
      * @param oldListenedProperties
      *            set of properties that where listened in last render
      * @param oldVisibleComponents
@@ -1600,7 +1602,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Refreshes the current page contents.
-     *
+     * 
      * @deprecated should not need to be used
      */
     @Deprecated
@@ -1631,7 +1633,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * </ul>
      * The default value is <code>ROW_HEADER_MODE_HIDDEN</code>
      * </p>
-     *
+     * 
      * @param mode
      *            the One of the modes listed above.
      */
@@ -1649,7 +1651,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the row header mode.
-     *
+     * 
      * @return the Row header mode.
      * @see #setRowHeaderMode(int)
      */
@@ -1661,7 +1663,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Adds the new row to table and fill the visible cells (except generated
      * columns) with given values.
-     *
+     * 
      * @param cells
      *            the Object array that is used for filling the visible cells
      *            new row. The types must be settable to visible column property
@@ -1729,10 +1731,10 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the Container that serves as the data source of the viewer.
-     *
+     * 
      * As a side-effect Table's value (selection) is set to null due old
      * selection not necessary exists in new Container.
-     *
+     * 
      * @see com.vaadin.data.Container.Viewer#setContainerDataSource(Container)
      */
     @Override
@@ -1792,7 +1794,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Invoked when the value of a variable has changed.
-     *
+     * 
      * @see com.vaadin.ui.Select#changeVariables(java.lang.Object,
      *      java.util.Map)
      */
@@ -1948,7 +1950,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Handles click event
-     *
+     * 
      * @param variables
      */
     private void handleClickEvent(Map variables) {
@@ -1977,7 +1979,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * Go to mode where content updates are not done. This is due we want to
      * bypass expensive content for some reason (like when we know we may have
      * other content changes on their way).
-     *
+     * 
      * @return true if content refresh flag was enabled prior this call
      */
     protected boolean disableContentRefreshing() {
@@ -1988,7 +1990,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Go to mode where content content refreshing has effect.
-     *
+     * 
      * @param refreshContent
      *            true if content refresh needs to be done
      */
@@ -2003,7 +2005,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /*
      * (non-Javadoc)
-     *
+     * 
      * @see com.vaadin.ui.AbstractSelect#paintContent(com.vaadin.
      * terminal.PaintTarget)
      */
@@ -2366,7 +2368,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /*
      * (non-Javadoc)
-     *
+     * 
      * @see com.vaadin.ui.AbstractSelect#getTag()
      */
     @Override
@@ -2376,7 +2378,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the cached visible table contents.
-     *
+     * 
      * @return the cached visible table contents.
      */
     private Object[][] getVisibleCells() {
@@ -2388,11 +2390,11 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the value of property.
-     *
+     * 
      * By default if the table is editable the fieldFactory is used to create
      * editors for table cells. Otherwise formatPropertyValue is used to format
      * the value representation.
-     *
+     * 
      * @param rowId
      *            the Id of the row (same as item Id).
      * @param colId
@@ -2419,7 +2421,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Formats table cell property values. By default the property.toString()
      * and return a empty string for null properties.
-     *
+     * 
      * @param rowId
      *            the Id of the row (same as item Id).
      * @param colId
@@ -2441,7 +2443,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Registers a new action handler for this container
-     *
+     * 
      * @see com.vaadin.event.Action.Container#addActionHandler(Action.Handler)
      */
     public void addActionHandler(Action.Handler actionHandler) {
@@ -2464,7 +2466,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Removes a previously registered action handler for the contents of this
      * container.
-     *
+     * 
      * @see com.vaadin.event.Action.Container#removeActionHandler(Action.Handler)
      */
     public void removeActionHandler(Action.Handler actionHandler) {
@@ -2486,9 +2488,9 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Notifies this listener that the Property's value has changed.
-     *
+     * 
      * Also listens changes in rendered items to refresh content area.
-     *
+     * 
      * @see com.vaadin.data.Property.ValueChangeListener#valueChange(Property.ValueChangeEvent)
      */
     @Override
@@ -2513,7 +2515,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Notifies the component that it is connected to an application.
-     *
+     * 
      * @see com.vaadin.ui.Component#attach()
      */
     @Override
@@ -2532,7 +2534,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Notifies the component that it is detached from the application
-     *
+     * 
      * @see com.vaadin.ui.Component#detach()
      */
     @Override
@@ -2549,7 +2551,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Removes all Items from the Container.
-     *
+     * 
      * @see com.vaadin.data.Container#removeAllItems()
      */
     @Override
@@ -2561,7 +2563,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Removes the Item identified by <code>ItemId</code> from the Container.
-     *
+     * 
      * @see com.vaadin.data.Container#removeItem(Object)
      */
     @Override
@@ -2581,7 +2583,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Removes a Property specified by the given Property ID from the Container.
-     *
+     * 
      * @see com.vaadin.data.Container#removeContainerProperty(Object)
      */
     @Override
@@ -2599,7 +2601,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Adds a new property to the table and show it as a visible column.
-     *
+     * 
      * @param propertyId
      *            the Id of the proprty.
      * @param type
@@ -2634,7 +2636,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Adds a new property to the table and show it as a visible column.
-     *
+     * 
      * @param propertyId
      *            the Id of the proprty
      * @param type
@@ -2683,7 +2685,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * Also note that getVisibleColumns() will return the generated columns,
      * while getContainerPropertyIds() will not.
      * </p>
-     *
+     * 
      * @param id
      *            the id of the column to be added
      * @param generatedColumn
@@ -2713,7 +2715,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Removes a generated column previously added with addGeneratedColumn.
-     *
+     * 
      * @param columnId
      *            id of the generated column to remove
      * @return true if the column could be removed (existed in the Table)
@@ -2736,7 +2738,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Returns the list of items on the current page
-     *
+     * 
      * @see com.vaadin.ui.Select#getVisibleItemIds()
      */
     @Override
@@ -2755,7 +2757,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Container datasource item set change. Table must flush its buffers on
      * change.
-     *
+     * 
      * @see com.vaadin.data.Container.ItemSetChangeListener#containerItemSetChange(com.vaadin.data.Container.ItemSetChangeEvent)
      */
     @Override
@@ -2783,7 +2785,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Container datasource property set change. Table must flush its buffers on
      * change.
-     *
+     * 
      * @see com.vaadin.data.Container.PropertySetChangeListener#containerPropertySetChange(com.vaadin.data.Container.PropertySetChangeEvent)
      */
     @Override
@@ -2797,7 +2799,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Adding new items is not supported.
-     *
+     * 
      * @throws UnsupportedOperationException
      *             if set to true.
      * @see com.vaadin.ui.Select#setNewItemsAllowed(boolean)
@@ -2812,7 +2814,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Focusing to this component is not supported.
-     *
+     * 
      * @throws UnsupportedOperationException
      *             if invoked.
      * @see com.vaadin.ui.AbstractField#focus()
@@ -2824,7 +2826,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the ID of the Item following the Item that corresponds to itemId.
-     *
+     * 
      * @see com.vaadin.data.Container.Ordered#nextItemId(java.lang.Object)
      */
     public Object nextItemId(Object itemId) {
@@ -2834,7 +2836,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Gets the ID of the Item preceding the Item that corresponds to the
      * itemId.
-     *
+     * 
      * @see com.vaadin.data.Container.Ordered#prevItemId(java.lang.Object)
      */
     public Object prevItemId(Object itemId) {
@@ -2843,7 +2845,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the ID of the first Item in the Container.
-     *
+     * 
      * @see com.vaadin.data.Container.Ordered#firstItemId()
      */
     public Object firstItemId() {
@@ -2852,7 +2854,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the ID of the last Item in the Container.
-     *
+     * 
      * @see com.vaadin.data.Container.Ordered#lastItemId()
      */
     public Object lastItemId() {
@@ -2862,7 +2864,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Tests if the Item corresponding to the given Item ID is the first Item in
      * the Container.
-     *
+     * 
      * @see com.vaadin.data.Container.Ordered#isFirstId(java.lang.Object)
      */
     public boolean isFirstId(Object itemId) {
@@ -2872,7 +2874,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Tests if the Item corresponding to the given Item ID is the last Item in
      * the Container.
-     *
+     * 
      * @see com.vaadin.data.Container.Ordered#isLastId(java.lang.Object)
      */
     public boolean isLastId(Object itemId) {
@@ -2881,7 +2883,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Adds new item after the given item.
-     *
+     * 
      * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object)
      */
     public Object addItemAfter(Object previousItemId)
@@ -2897,7 +2899,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Adds new item after the given item.
-     *
+     * 
      * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object,
      *      java.lang.Object)
      */
@@ -2914,10 +2916,10 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the TableFieldFactory that is used to create editor for table cells.
-     *
+     * 
      * The TableFieldFactory is only used if the Table is editable. By default
      * the DefaultFieldFactory is used.
-     *
+     * 
      * @param fieldFactory
      *            the field factory to set.
      * @see #isEditable
@@ -2929,9 +2931,9 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the TableFieldFactory that is used to create editor for table cells.
-     *
+     * 
      * The FieldFactory is only used if the Table is editable.
-     *
+     * 
      * @return TableFieldFactory used to create the Field instances.
      * @see #isEditable
      */
@@ -2941,9 +2943,9 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the FieldFactory that is used to create editor for table cells.
-     *
+     * 
      * The FieldFactory is only used if the Table is editable.
-     *
+     * 
      * @return FieldFactory used to create the Field instances.
      * @see #isEditable
      * @deprecated use {@link #getTableFieldFactory()} instead
@@ -2959,10 +2961,10 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the FieldFactory that is used to create editor for table cells.
-     *
+     * 
      * The FieldFactory is only used if the Table is editable. By default the
      * BaseFieldFactory is used.
-     *
+     * 
      * @param fieldFactory
      *            the field factory to set.
      * @see #isEditable
@@ -2980,18 +2982,18 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Is table editable.
-     *
+     * 
      * If table is editable a editor of type Field is created for each table
      * cell. The assigned FieldFactory is used to create the instances.
-     *
+     * 
      * To provide custom editors for table cells create a class implementins the
      * FieldFactory interface, and assign it to table, and set the editable
      * property to true.
-     *
+     * 
      * @return true if table is editable, false oterwise.
      * @see Field
      * @see FieldFactory
-     *
+     * 
      */
     public boolean isEditable() {
         return editable;
@@ -2999,19 +3001,19 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the editable property.
-     *
+     * 
      * If table is editable a editor of type Field is created for each table
      * cell. The assigned FieldFactory is used to create the instances.
-     *
+     * 
      * To provide custom editors for table cells create a class implementins the
      * FieldFactory interface, and assign it to table, and set the editable
      * property to true.
-     *
+     * 
      * @param editable
      *            true if table should be editable by user.
      * @see Field
      * @see FieldFactory
-     *
+     * 
      */
     public void setEditable(boolean editable) {
         this.editable = editable;
@@ -3023,13 +3025,13 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sorts the table.
-     *
+     * 
      * @throws UnsupportedOperationException
      *             if the container data source does not implement
      *             Container.Sortable
      * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[],
      *      boolean[])
-     *
+     * 
      */
     public void sort(Object[] propertyId, boolean[] ascending)
             throws UnsupportedOperationException {
@@ -3049,7 +3051,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sorts the table by currently selected sorting column.
-     *
+     * 
      * @throws UnsupportedOperationException
      *             if the container data source does not implement
      *             Container.Sortable
@@ -3064,7 +3066,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the container property IDs, which can be used to sort the item.
-     *
+     * 
      * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds()
      */
     public Collection getSortableContainerPropertyIds() {
@@ -3078,7 +3080,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Gets the currently sorted column property ID.
-     *
+     * 
      * @return the Container property id of the currently sorted column.
      */
     public Object getSortContainerPropertyId() {
@@ -3087,7 +3089,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the currently sorted column property id.
-     *
+     * 
      * @param propertyId
      *            the Container property id of the currently sorted column.
      */
@@ -3098,7 +3100,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Internal method to set currently sorted column property id. With doSort
      * flag actual sorting may be bypassed.
-     *
+     * 
      * @param propertyId
      * @param doSort
      */
@@ -3118,7 +3120,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Is the table currently sorted in ascending order.
-     *
+     * 
      * @return <code>true</code> if ascending, <code>false</code> if descending.
      */
     public boolean isSortAscending() {
@@ -3127,7 +3129,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Sets the table in ascending order.
-     *
+     * 
      * @param ascending
      *            <code>true</code> if ascending, <code>false</code> if
      *            descending.
@@ -3139,7 +3141,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Internal method to set sort ascending. With doSort flag actual sort can
      * be bypassed.
-     *
+     * 
      * @param ascending
      * @param doSort
      */
@@ -3156,10 +3158,10 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Is sorting disabled altogether.
-     *
+     * 
      * True iff no sortable columns are given even in the case where data source
      * would support this.
-     *
+     * 
      * @return True iff sorting is disabled.
      */
     public boolean isSortDisabled() {
@@ -3168,10 +3170,10 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Disables the sorting altogether.
-     *
+     * 
      * To disable sorting altogether, set to true. In this case no sortable
      * columns are given even in the case where datasource would support this.
-     *
+     * 
      * @param sortDisabled
      *            True iff sorting is disabled.
      */
@@ -3185,7 +3187,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Table does not support lazy options loading mode. Setting this true will
      * throw UnsupportedOperationException.
-     *
+     * 
      * @see com.vaadin.ui.Select#setLazyLoading(boolean)
      */
     public void setLazyLoading(boolean useLazyLoading) {
@@ -3210,14 +3212,14 @@ public class Table extends AbstractSelect implements Action.Container,
      * Used to create "generated columns"; columns that exist only in the Table,
      * not in the underlying Container. Implement this interface and pass it to
      * Table.addGeneratedColumn along with an id for the column to be generated.
-     *
+     * 
      */
     public interface ColumnGenerator extends Serializable {
 
         /**
          * Called by Table when a cell in a generated column needs to be
          * generated.
-         *
+         * 
          * @param source
          *            the source Table
          * @param itemId
@@ -3233,7 +3235,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Set cell style generator for Table.
-     *
+     * 
      * @param cellStyleGenerator
      *            New cell style generator or null to remove generator.
      */
@@ -3244,7 +3246,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
     /**
      * Get the current cell style generator.
-     *
+     * 
      */
     public CellStyleGenerator getCellStyleGenerator() {
         return cellStyleGenerator;
@@ -3261,7 +3263,7 @@ public class Table extends AbstractSelect implements Action.Container,
 
         /**
          * Called by Table when a cell (and row) is painted.
-         *
+         * 
          * @param itemId
          *            The itemId of the painted cell
          * @param propertyId
index 5271c9bbed16f18cb63adc86a90944cda848ecc4..a43b2b1be8bedda24737f5b4b141ee48ac91d8bb 100644 (file)
@@ -10,6 +10,7 @@ import java.util.Map;
 import com.vaadin.data.Property;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VTextField;
 
 /**
  * <p>
@@ -32,6 +33,7 @@ import com.vaadin.terminal.PaintTarget;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VTextField.class)
 public class TextField extends AbstractField {
 
     /* Private members */
index cb3f667a4f4e4cf4d0a938a8e1ee1f00d64d45d0..67a036580bb8ca81cb47e9a58de5fae70773bef5 100644 (file)
@@ -31,6 +31,7 @@ import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
+import com.vaadin.terminal.gwt.client.ui.VTree;
 
 /**
  * Tree component. A Tree can be used to select an item (or multiple items) from
@@ -42,6 +43,7 @@ import com.vaadin.terminal.gwt.client.MouseEventDetails;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VTree.class)
 public class Tree extends AbstractSelect implements Container.Hierarchical,
         Action.Container, ItemClickSource {
 
index a619a5a0a90c8d013840ebb80fb97da332197852..bcbc86a2753ed7b683486f82f9c07663132dc36f 100644 (file)
@@ -9,12 +9,14 @@ import java.util.Collection;
 import com.vaadin.data.Container;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VTwinColSelect;
 
 /**
  * Multiselect component with two lists: left side for available items and right
  * side for selected items.
  */
 @SuppressWarnings("serial")
+@ClientWidget(VTwinColSelect.class)
 public class TwinColSelect extends AbstractSelect {
 
     private int columns = 0;
index cdea1e6ce3dbc68dd58d1df7c4b8752401fb5988..2ea347fc5655c71143a58cd8cf10302a3110f414 100644 (file)
@@ -1,5 +1,5 @@
-/* 
-@ITMillApache2LicenseForJavaFiles@
+/*
+ * @ITMillApache2LicenseForJavaFiles@
  */
 
 package com.vaadin.ui;
@@ -17,6 +17,7 @@ import com.vaadin.Application;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.UploadStream;
+import com.vaadin.terminal.gwt.client.ui.VUpload;
 
 /**
  * Component for uploading files from client to server.
@@ -54,6 +55,7 @@ import com.vaadin.terminal.UploadStream;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VUpload.class)
 public class Upload extends AbstractComponent implements Component.Focusable {
 
     private boolean delayedFocus;
@@ -200,12 +202,13 @@ public class Upload extends AbstractComponent implements Component.Focusable {
                 try {
                     // still try to close output stream
                     out.close();
-                } catch (IOException e1) {
-                    // NOP
+                } catch (IOException ignored) {
                 }
                 fireUploadInterrupted(filename, type, totalBytes, e);
                 endUpload();
                 interrupted = false;
+                // throw cause ahead
+                throw new IllegalStateException("Uploading failed", e);
             }
         }
     }
index eca646538f676eaf8f3049e81727184ffc4fd6d4..d6c0dc9f51ef3bf8e051ef3059ec95d21987a8f2 100644 (file)
@@ -6,6 +6,7 @@ import java.util.Map;
 
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VUriFragmentUtility;
 
 /**
  * Experimental web browser dependent component for URI fragment (part after
@@ -16,6 +17,7 @@ import com.vaadin.terminal.PaintTarget;
  * 
  */
 @SuppressWarnings("serial")
+@ClientWidget(VUriFragmentUtility.class)
 public class UriFragmentUtility extends AbstractComponent {
 
     /**
index 55f70a740f58c20a1724b67449820ba7ca1aeb31..13f1422b6a387531ccbf47abb051671943e4d13c 100644 (file)
@@ -1,5 +1,7 @@
 package com.vaadin.ui;
 
+import com.vaadin.terminal.gwt.client.ui.VVerticalLayout;
+
 /**
  * Vertical layout
  * 
@@ -13,6 +15,7 @@ package com.vaadin.ui;
  * @since 5.3
  */
 @SuppressWarnings("serial")
+@ClientWidget(VVerticalLayout.class)
 public class VerticalLayout extends AbstractOrderedLayout {
 
     public VerticalLayout() {
index 663aabbd792860896fb3bc87de0c4bfb761f29c2..1912a434ef756f67c806f627183fd479365944a7 100644 (file)
@@ -24,6 +24,7 @@ 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;
 
 /**
  * Application window component.
@@ -34,6 +35,7 @@ import com.vaadin.terminal.URIHandler;
  * @since 3.0
  */
 @SuppressWarnings("serial")
+@ClientWidget(VView.class)
 public class Window extends Panel implements URIHandler, ParameterHandler {
 
     /**
@@ -535,10 +537,15 @@ public class Window extends Panel implements URIHandler, ParameterHandler {
         // Window closing
         target.addVariable(this, "close", false);
 
-        // Paint subwindows
-        for (final Iterator<Window> i = subwindows.iterator(); i.hasNext();) {
-            final Window w = i.next();
-            w.paint(target);
+        if (getParent() == null) {
+            // Paint subwindows
+            for (final Iterator<Window> i = subwindows.iterator(); i.hasNext();) {
+                final Window w = i.next();
+                w.paint(target);
+            }
+        } else {
+            // mark subwindows
+            target.addAttribute("sub", true);
         }
 
         // Paint notifications