From 5ef5da15a7903262494d7e3fd7867dde7ed746c4 Mon Sep 17 00:00:00 2001
From: Matti Tahvonen
Date: Fri, 25 Sep 2009 12:07:09 +0000
Subject: steps toward simpler widgetset creation. Still needs a lot of
cleaning and refining.
svn changeset:8930/svn branch:2009-09-widget-packaging_3332
---
src/com/vaadin/demo/colorpicker/ColorPicker.java | 3 +
.../colorpicker/gwt/ColorPickerWidgetSet.gwt.xml | 5 +-
.../gwt/client/ColorPickerWidgetSet.java | 36 -
src/com/vaadin/demo/coverflow/Coverflow.java | 3 +
.../demo/coverflow/gwt/CoverflowWidgetSet.gwt.xml | 5 +-
.../coverflow/gwt/client/CoverflowWidgetSet.java | 36 -
src/com/vaadin/demo/reservation/CalendarField.java | 3 +
src/com/vaadin/demo/reservation/GoogleMap.java | 3 +
.../reservation/gwt/ReservationWidgetSet.gwt.xml | 3 -
.../gwt/client/ReservationWidgetSet.java | 37 -
src/com/vaadin/demo/sampler/ActiveLink.java | 3 +
src/com/vaadin/demo/sampler/CodeLabel.java | 3 +
src/com/vaadin/demo/sampler/GoogleAnalytics.java | 3 +
.../demo/sampler/gwt/SamplerWidgetSet.gwt.xml | 3 -
.../demo/sampler/gwt/client/SamplerWidgetSet.java | 40 -
.../portal/gwt/PortalDefaultWidgetSet.gwt.xml | 4 -
.../portal/gwt/client/PortalDefaultWidgetSet.java | 7 -
src/com/vaadin/terminal/PaintTarget.java | 7 +
.../vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml | 7 +-
.../terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml | 6 -
.../gwt/client/ApplicationConfiguration.java | 38 +-
.../terminal/gwt/client/ApplicationConnection.java | 36 +-
.../terminal/gwt/client/DefaultWidgetSet.java | 282 ++----
.../vaadin/terminal/gwt/client/VDebugConsole.java | 13 +-
.../vaadin/terminal/gwt/client/VUIDLBrowser.java | 31 +-
src/com/vaadin/terminal/gwt/client/WidgetMap.java | 38 +
src/com/vaadin/terminal/gwt/client/WidgetSet.java | 20 +-
.../terminal/gwt/client/ui/VUnknownComponent.java | 2 +-
.../terminal/gwt/rebind/ClassPathExplorer.java | 266 ++++++
.../terminal/gwt/rebind/WidgetMapGenerator.java | 192 ++++
.../terminal/gwt/server/CommunicationManager.java | 89 +-
.../terminal/gwt/server/JsonPaintTarget.java | 48 +-
src/com/vaadin/ui/AbsoluteLayout.java | 1 +
src/com/vaadin/ui/AbstractComponent.java | 15 +-
src/com/vaadin/ui/Accordion.java | 3 +
src/com/vaadin/ui/Button.java | 2 +
src/com/vaadin/ui/CheckBox.java | 5 +-
src/com/vaadin/ui/ClientWidget.java | 21 +
src/com/vaadin/ui/CssLayout.java | 1 +
src/com/vaadin/ui/CustomComponent.java | 2 +
src/com/vaadin/ui/CustomLayout.java | 2 +
src/com/vaadin/ui/DateField.java | 2 +
src/com/vaadin/ui/Embedded.java | 2 +
src/com/vaadin/ui/Form.java | 2 +
src/com/vaadin/ui/FormLayout.java | 3 +
src/com/vaadin/ui/GridLayout.java | 2 +
src/com/vaadin/ui/HorizontalLayout.java | 3 +
src/com/vaadin/ui/Label.java | 2 +
src/com/vaadin/ui/Link.java | 2 +
src/com/vaadin/ui/ListSelect.java | 2 +
src/com/vaadin/ui/MenuBar.java | 13 +-
src/com/vaadin/ui/NativeSelect.java | 2 +
src/com/vaadin/ui/OptionGroup.java | 2 +
src/com/vaadin/ui/OrderedLayout.java | 2 +
src/com/vaadin/ui/Panel.java | 2 +
src/com/vaadin/ui/PopupView.java | 2 +
src/com/vaadin/ui/ProgressIndicator.java | 2 +
src/com/vaadin/ui/RichTextArea.java | 2 +
src/com/vaadin/ui/Select.java | 2 +
src/com/vaadin/ui/Slider.java | 1008 ++++++++++----------
src/com/vaadin/ui/SplitPanel.java | 12 +-
src/com/vaadin/ui/TabSheet.java | 2 +
src/com/vaadin/ui/Table.java | 292 +++---
src/com/vaadin/ui/TextField.java | 2 +
src/com/vaadin/ui/Tree.java | 2 +
src/com/vaadin/ui/TwinColSelect.java | 2 +
src/com/vaadin/ui/Upload.java | 11 +-
src/com/vaadin/ui/UriFragmentUtility.java | 2 +
src/com/vaadin/ui/VerticalLayout.java | 3 +
src/com/vaadin/ui/Window.java | 15 +-
70 files changed, 1591 insertions(+), 1133 deletions(-)
delete mode 100644 src/com/vaadin/demo/colorpicker/gwt/client/ColorPickerWidgetSet.java
delete mode 100644 src/com/vaadin/demo/coverflow/gwt/client/CoverflowWidgetSet.java
delete mode 100644 src/com/vaadin/demo/reservation/gwt/client/ReservationWidgetSet.java
delete mode 100644 src/com/vaadin/demo/sampler/gwt/client/SamplerWidgetSet.java
delete mode 100644 src/com/vaadin/portal/gwt/client/PortalDefaultWidgetSet.java
delete mode 100644 src/com/vaadin/terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml
create mode 100644 src/com/vaadin/terminal/gwt/client/WidgetMap.java
create mode 100644 src/com/vaadin/terminal/gwt/rebind/ClassPathExplorer.java
create mode 100644 src/com/vaadin/terminal/gwt/rebind/WidgetMapGenerator.java
create mode 100644 src/com/vaadin/ui/ClientWidget.java
(limited to 'src/com')
diff --git a/src/com/vaadin/demo/colorpicker/ColorPicker.java b/src/com/vaadin/demo/colorpicker/ColorPicker.java
index a811d7ac92..55de19b73c 100644
--- a/src/com/vaadin/demo/colorpicker/ColorPicker.java
+++ b/src/com/vaadin/demo/colorpicker/ColorPicker.java
@@ -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() {
diff --git a/src/com/vaadin/demo/colorpicker/gwt/ColorPickerWidgetSet.gwt.xml b/src/com/vaadin/demo/colorpicker/gwt/ColorPickerWidgetSet.gwt.xml
index 718ab9e2c6..27ddc1d60f 100644
--- a/src/com/vaadin/demo/colorpicker/gwt/ColorPickerWidgetSet.gwt.xml
+++ b/src/com/vaadin/demo/colorpicker/gwt/ColorPickerWidgetSet.gwt.xml
@@ -1,11 +1,8 @@
-
+
-
-
-
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
index 2c924c0239..0000000000
--- a/src/com/vaadin/demo/colorpicker/gwt/client/ColorPickerWidgetSet.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.demo.colorpicker.gwt.client;
-
-import com.vaadin.demo.colorpicker.gwt.client.ui.VColorPicker;
-import com.vaadin.terminal.gwt.client.DefaultWidgetSet;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class ColorPickerWidgetSet extends DefaultWidgetSet {
- /** Resolves UIDL tag name to widget class. */
- @Override
- protected Class> resolveWidgetType(UIDL uidl) {
- final String tag = uidl.getTag();
- if ("colorpicker".equals(tag)) {
- return VColorPicker.class;
- }
-
- // Let the DefaultWidgetSet handle resolution of default widgets
- return super.resolveWidgetType(uidl);
- }
-
- /** Creates a widget instance according to its class object. */
- @Override
- public Paintable createWidget(UIDL uidl) {
- final Class> type = resolveWidgetType(uidl);
- if (VColorPicker.class == type) {
- return new VColorPicker();
- }
-
- // Let the DefaultWidgetSet handle creation of default widgets
- return super.createWidget(uidl);
- }
-}
diff --git a/src/com/vaadin/demo/coverflow/Coverflow.java b/src/com/vaadin/demo/coverflow/Coverflow.java
index 149cf6e383..bd56261a38 100644
--- a/src/com/vaadin/demo/coverflow/Coverflow.java
+++ b/src/com/vaadin/demo/coverflow/Coverflow.java
@@ -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";
diff --git a/src/com/vaadin/demo/coverflow/gwt/CoverflowWidgetSet.gwt.xml b/src/com/vaadin/demo/coverflow/gwt/CoverflowWidgetSet.gwt.xml
index 36c016f131..a1987af121 100644
--- a/src/com/vaadin/demo/coverflow/gwt/CoverflowWidgetSet.gwt.xml
+++ b/src/com/vaadin/demo/coverflow/gwt/CoverflowWidgetSet.gwt.xml
@@ -1,8 +1,5 @@
-
-
-
-
+
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
index bbde252540..0000000000
--- a/src/com/vaadin/demo/coverflow/gwt/client/CoverflowWidgetSet.java
+++ /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
diff --git a/src/com/vaadin/demo/reservation/CalendarField.java b/src/com/vaadin/demo/reservation/CalendarField.java
index 2af0f1ed71..349c6b59a8 100644
--- a/src/com/vaadin/demo/reservation/CalendarField.java
+++ b/src/com/vaadin/demo/reservation/CalendarField.java
@@ -12,14 +12,17 @@ import java.util.Iterator;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
+import com.vaadin.demo.reservation.gwt.client.ui.VCalendarField;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
+import com.vaadin.ui.ClientWidget;
import com.vaadin.ui.DateField;
// TODO send one month at a time, do lazyLoading
// TODO check date limit when updating variables
// TODO Allow item selection
@SuppressWarnings("serial")
+@ClientWidget(VCalendarField.class)
public class CalendarField extends DateField implements Container.Viewer {
private static final String TAGNAME = "calendarfield";
diff --git a/src/com/vaadin/demo/reservation/GoogleMap.java b/src/com/vaadin/demo/reservation/GoogleMap.java
index e82f7c0f6a..19dee3aacf 100644
--- a/src/com/vaadin/demo/reservation/GoogleMap.java
+++ b/src/com/vaadin/demo/reservation/GoogleMap.java
@@ -12,12 +12,15 @@ import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.demo.reservation.gwt.client.ui.VGoogleMap;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.ClientWidget;
@SuppressWarnings("serial")
+@ClientWidget(VGoogleMap.class)
public class GoogleMap extends AbstractComponent implements Sizeable,
Container.Viewer {
private final String TAG_MARKERS = "markers";
diff --git a/src/com/vaadin/demo/reservation/gwt/ReservationWidgetSet.gwt.xml b/src/com/vaadin/demo/reservation/gwt/ReservationWidgetSet.gwt.xml
index 1b2991d51c..4f38e07f26 100644
--- a/src/com/vaadin/demo/reservation/gwt/ReservationWidgetSet.gwt.xml
+++ b/src/com/vaadin/demo/reservation/gwt/ReservationWidgetSet.gwt.xml
@@ -23,7 +23,4 @@
-
-
-
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
index 2520098aed..0000000000
--- a/src/com/vaadin/demo/reservation/gwt/client/ReservationWidgetSet.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.demo.reservation.gwt.client;
-
-import com.vaadin.demo.reservation.gwt.client.ui.VCalendarField;
-import com.vaadin.demo.reservation.gwt.client.ui.VGoogleMap;
-import com.vaadin.terminal.gwt.client.DefaultWidgetSet;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class ReservationWidgetSet extends DefaultWidgetSet {
- @Override
- public Paintable createWidget(UIDL uidl) {
- final Class> type = resolveWidgetType(uidl);
- if (VGoogleMap.class == type) {
- return new VGoogleMap();
- } else if (VCalendarField.class == type) {
- return new VCalendarField();
- }
-
- return super.createWidget(uidl);
- }
-
- @Override
- protected Class> resolveWidgetType(UIDL uidl) {
- final String tag = uidl.getTag();
- if ("googlemap".equals(tag)) {
- return VGoogleMap.class;
- } else if ("calendarfield".equals(tag)) {
- return VCalendarField.class;
- }
- return super.resolveWidgetType(uidl);
- }
-
-}
diff --git a/src/com/vaadin/demo/sampler/ActiveLink.java b/src/com/vaadin/demo/sampler/ActiveLink.java
index 9b6a47cb3b..53c2c1b2b9 100644
--- a/src/com/vaadin/demo/sampler/ActiveLink.java
+++ b/src/com/vaadin/demo/sampler/ActiveLink.java
@@ -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";
diff --git a/src/com/vaadin/demo/sampler/CodeLabel.java b/src/com/vaadin/demo/sampler/CodeLabel.java
index bfc96d30fe..3e4f985a65 100644
--- a/src/com/vaadin/demo/sampler/CodeLabel.java
+++ b/src/com/vaadin/demo/sampler/CodeLabel.java
@@ -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 {
diff --git a/src/com/vaadin/demo/sampler/GoogleAnalytics.java b/src/com/vaadin/demo/sampler/GoogleAnalytics.java
index c8009983c3..9c654bff59 100644
--- a/src/com/vaadin/demo/sampler/GoogleAnalytics.java
+++ b/src/com/vaadin/demo/sampler/GoogleAnalytics.java
@@ -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;
diff --git a/src/com/vaadin/demo/sampler/gwt/SamplerWidgetSet.gwt.xml b/src/com/vaadin/demo/sampler/gwt/SamplerWidgetSet.gwt.xml
index dc6d1b206c..f40e421fbb 100644
--- a/src/com/vaadin/demo/sampler/gwt/SamplerWidgetSet.gwt.xml
+++ b/src/com/vaadin/demo/sampler/gwt/SamplerWidgetSet.gwt.xml
@@ -9,7 +9,4 @@
-
-
-
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
index 69942f6e50..0000000000
--- a/src/com/vaadin/demo/sampler/gwt/client/SamplerWidgetSet.java
+++ /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);
- }
- }
-
-}
diff --git a/src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml b/src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml
index 3e9527788d..0963760035 100644
--- a/src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml
+++ b/src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml
@@ -1,8 +1,4 @@
-
-
-
-
diff --git a/src/com/vaadin/portal/gwt/client/PortalDefaultWidgetSet.java b/src/com/vaadin/portal/gwt/client/PortalDefaultWidgetSet.java
deleted file mode 100644
index d28ddc9aca..0000000000
--- a/src/com/vaadin/portal/gwt/client/PortalDefaultWidgetSet.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.vaadin.portal.gwt.client;
-
-import com.vaadin.demo.sampler.gwt.client.SamplerWidgetSet;
-
-public class PortalDefaultWidgetSet extends SamplerWidgetSet {
-
-}
diff --git a/src/com/vaadin/terminal/PaintTarget.java b/src/com/vaadin/terminal/PaintTarget.java
index a457dd4d1d..725d82dcab 100644
--- a/src/com/vaadin/terminal/PaintTarget.java
+++ b/src/com/vaadin/terminal/PaintTarget.java
@@ -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);
}
diff --git a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
index 23b281dc4f..58d692e99f 100644
--- a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
+++ b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
@@ -22,7 +22,7 @@
-
+
@@ -31,5 +31,10 @@
+
+
+
+
+
diff --git a/src/com/vaadin/terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml b/src/com/vaadin/terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml
deleted file mode 100644
index d8d8607213..0000000000
--- a/src/com/vaadin/terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
index 945542729f..1674196e90 100644
--- a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
+++ b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
@@ -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 unstartedApplications = new ArrayList();
private static ArrayList runningApplications = new ArrayList();
@@ -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);
+ }
+ }
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
index 0e1270901f..72cefddf2d 100755
--- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
@@ -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 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;
+ }
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java b/src/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java
index 4c3f9c83d1..9c54e4c5f2 100644
--- a/src/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java
+++ b/src/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java
@@ -4,287 +4,115 @@
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;
+
+ }
}
diff --git a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java
index fb5a81a86c..f3a59460e0 100755
--- a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java
+++ b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java
@@ -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());
diff --git a/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java b/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java
index 89d5caceed..a8a5bea94d 100644
--- a/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java
+++ b/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java
@@ -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() {
public void onOpen(OpenEvent 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 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
index 0000000000..f0b9e260b4
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/WidgetMap.java
@@ -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);
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/WidgetSet.java b/src/com/vaadin/terminal/gwt/client/WidgetSet.java
index df005353c0..832e985397 100644
--- a/src/com/vaadin/terminal/gwt/client/WidgetSet.java
+++ b/src/com/vaadin/terminal/gwt/client/WidgetSet.java
@@ -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);
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java b/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java
index fd87baf199..cd9d2cd40c 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java
@@ -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
index 0000000000..6c81c368c4
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/rebind/ClassPathExplorer.java
@@ -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.
+ *
+ * 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 classpathLocations = getClasspathLocations();
+
+ private ClassPathExplorer() {
+ }
+
+ public static Collection> getPaintablesHavingWidgetAnnotation() {
+ Collection> paintables = new HashSet>();
+ Set 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 getClasspathLocations() {
+ Map locations = new HashMap();
+
+ 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 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 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> 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 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> 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> 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
index 0000000000..73494ad785
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/rebind/WidgetMapGenerator.java
@@ -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> 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> getUsedPaintables() {
+ return ClassPathExplorer.getPaintablesHavingWidgetAnnotation();
+ }
+
+ private void generateInstantiatorMethod(
+ SourceWriter sourceWriter,
+ Collection> 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> 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("}");
+
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java
index ee5a22c3f3..11aec9ed28 100644
--- a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java
+++ b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java
@@ -92,7 +92,7 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
public static final String VAR_ARRAYITEM_SEPARATOR = "\u001c";
- private final HashSet currentlyOpenWindowsInClient = new HashSet();
+ private final HashMap currentlyOpenWindowsInClient = new HashMap();
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 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 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> 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 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, Integer> typeToKey = new HashMap, 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
- *
+ *
* @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 ItemId 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.
*
- *
+ *
* @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 true if ascending, false 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
* true if ascending, false 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
diff --git a/src/com/vaadin/ui/TextField.java b/src/com/vaadin/ui/TextField.java
index 5271c9bbed..a43b2b1be8 100644
--- a/src/com/vaadin/ui/TextField.java
+++ b/src/com/vaadin/ui/TextField.java
@@ -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;
/**
*
@@ -32,6 +33,7 @@ import com.vaadin.terminal.PaintTarget;
* @since 3.0
*/
@SuppressWarnings("serial")
+@ClientWidget(VTextField.class)
public class TextField extends AbstractField {
/* Private members */
diff --git a/src/com/vaadin/ui/Tree.java b/src/com/vaadin/ui/Tree.java
index cb3f667a4f..67a036580b 100644
--- a/src/com/vaadin/ui/Tree.java
+++ b/src/com/vaadin/ui/Tree.java
@@ -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 {
diff --git a/src/com/vaadin/ui/TwinColSelect.java b/src/com/vaadin/ui/TwinColSelect.java
index a619a5a0a9..bcbc86a275 100644
--- a/src/com/vaadin/ui/TwinColSelect.java
+++ b/src/com/vaadin/ui/TwinColSelect.java
@@ -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;
diff --git a/src/com/vaadin/ui/Upload.java b/src/com/vaadin/ui/Upload.java
index cdea1e6ce3..2ea347fc56 100644
--- a/src/com/vaadin/ui/Upload.java
+++ b/src/com/vaadin/ui/Upload.java
@@ -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);
}
}
}
diff --git a/src/com/vaadin/ui/UriFragmentUtility.java b/src/com/vaadin/ui/UriFragmentUtility.java
index eca646538f..d6c0dc9f51 100644
--- a/src/com/vaadin/ui/UriFragmentUtility.java
+++ b/src/com/vaadin/ui/UriFragmentUtility.java
@@ -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 {
/**
diff --git a/src/com/vaadin/ui/VerticalLayout.java b/src/com/vaadin/ui/VerticalLayout.java
index 55f70a740f..13f1422b6a 100644
--- a/src/com/vaadin/ui/VerticalLayout.java
+++ b/src/com/vaadin/ui/VerticalLayout.java
@@ -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() {
diff --git a/src/com/vaadin/ui/Window.java b/src/com/vaadin/ui/Window.java
index 663aabbd79..1912a434ef 100644
--- a/src/com/vaadin/ui/Window.java
+++ b/src/com/vaadin/ui/Window.java
@@ -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 i = subwindows.iterator(); i.hasNext();) {
- final Window w = i.next();
- w.paint(target);
+ if (getParent() == null) {
+ // Paint subwindows
+ for (final Iterator i = subwindows.iterator(); i.hasNext();) {
+ final Window w = i.next();
+ w.paint(target);
+ }
+ } else {
+ // mark subwindows
+ target.addAttribute("sub", true);
}
// Paint notifications
--
cgit v1.2.3