diff options
author | Matti Tahvonen <matti.tahvonen@itmill.com> | 2009-10-06 12:50:02 +0000 |
---|---|---|
committer | Matti Tahvonen <matti.tahvonen@itmill.com> | 2009-10-06 12:50:02 +0000 |
commit | 37b541b353779eb671e0e60125400b09fe879420 (patch) | |
tree | 60dee10fffb0ba96a7b008d6ffab1822df205c20 /src/com/vaadin | |
parent | 59ed7c4303ac47d3f815f028e1efe5af16c75037 (diff) | |
parent | 1b8d114fa789769dfb0e907ddd9ec9a9abb094eb (diff) | |
download | vaadin-framework-37b541b353779eb671e0e60125400b09fe879420.tar.gz vaadin-framework-37b541b353779eb671e0e60125400b09fe879420.zip |
merged 2009-09-widget-packaging_3332 branch to 6.2
svn changeset:9110/svn branch:6.2
Diffstat (limited to 'src/com/vaadin')
77 files changed, 2322 insertions, 1879 deletions
diff --git a/src/com/vaadin/demo/colorpicker/ColorPicker.java b/src/com/vaadin/demo/colorpicker/ColorPicker.java index a811d7ac92..f423815060 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() { @@ -24,12 +27,6 @@ public class ColorPicker extends AbstractField { return String.class; } - /** Tag is the UIDL element name for client-server communications. */ - @Override - public String getTag() { - return "colorpicker"; - } - /** Set the currently selected color. */ public void setColor(String newcolor) { // Sets the color name as the property of the component. 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 @@ <module> <!-- Inherit DefaultWidgetSet -->
- <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" />
+ <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" /> <!-- 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 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..6d274ca054 100644 --- a/src/com/vaadin/demo/coverflow/Coverflow.java +++ b/src/com/vaadin/demo/coverflow/Coverflow.java @@ -4,22 +4,20 @@ 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"; private String backgroundGradientEnd = "EEEEEE"; private boolean scrollbarVisibility = true; - @Override - public String getTag() { - return "cover"; - } - /** * Paints the uidl * diff --git a/src/com/vaadin/demo/coverflow/gwt/CoverflowWidgetSet.gwt.xml b/src/com/vaadin/demo/coverflow/gwt/CoverflowWidgetSet.gwt.xml index 36c016f131..21e8f26236 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 @@ <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.DefaultWidgetSet" /> </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 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..9676cd79ee 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";
@@ -60,15 +63,6 @@ public class CalendarField extends DateField implements Container.Viewer { init();
}
- /*
- * Gets the components UIDL tag string. Don't add a JavaDoc comment here, we
- * use the default documentation from implemented interface.
- */
- @Override
- public String getTag() {
- return TAGNAME;
- }
-
public void init() {
super.setResolution(RESOLUTION_HOUR);
diff --git a/src/com/vaadin/demo/reservation/GoogleMap.java b/src/com/vaadin/demo/reservation/GoogleMap.java index e82f7c0f6a..746982db9b 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";
@@ -31,11 +34,6 @@ public class GoogleMap extends AbstractComponent implements Sizeable, private Object itemMarkerYPropertyId = new Object();
@Override
- public String getTag() {
- return "googlemap";
- }
-
- @Override
public void paintContent(PaintTarget target) throws PaintException {
super.paintContent(target);
// Add size info as variables
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 @@ <!-- Using key for http://demo.vaadin.com: --> <script src="http://maps.google.com/maps?gwt=1&file=api&v=2.x&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 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..b92e8371a7 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"; @@ -34,11 +37,6 @@ public class ActiveLink extends Link { super(caption, resource); } - @Override - public String getTag() { - return TAG; - } - static { try { LINK_FOLLOWED_METHOD = LinkActivatedListener.class diff --git a/src/com/vaadin/demo/sampler/CodeLabel.java b/src/com/vaadin/demo/sampler/CodeLabel.java index bfc96d30fe..a135c230c0 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 { @@ -16,11 +19,6 @@ public class CodeLabel extends Label { } @Override - public String getTag() { - return TAG; - } - - @Override public void setContentMode(int contentMode) { if (contentMode != CONTENT_PREFORMATTED) { throw new UnsupportedOperationException( diff --git a/src/com/vaadin/demo/sampler/GoogleAnalytics.java b/src/com/vaadin/demo/sampler/GoogleAnalytics.java index c8009983c3..9e4e56ba5e 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; @@ -22,11 +25,6 @@ public class GoogleAnalytics extends AbstractComponent { this.domainName = domainName; } - @Override - public String getTag() { - return TAG; - } - public String getTrackerId() { return 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 @@ <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 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 @@ <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 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..0c139aabc4 100644 --- a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml +++ b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml @@ -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. --> @@ -31,5 +31,10 @@ <when-property-is name="user.agent" value="ie6"/> </replace-with> + <generate-with class="com.vaadin.terminal.gwt.widgetsetutils.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 index d8d8607213..0000000000 --- a/src/com/vaadin/terminal/gwt/DefaultWidgetSetNoEntry.gwt.xml +++ /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 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<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); + } + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index c65e787cce..958b2a781e 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; @@ -616,7 +615,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) { @@ -627,12 +630,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"); @@ -656,6 +664,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 @@ -721,7 +734,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() @@ -804,10 +817,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 @@ -1126,10 +1135,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); @@ -1525,7 +1535,7 @@ public class ApplicationConnection { if (w != null) { return w; } else { - w = widgetSet.createWidget(uidl); + w = widgetSet.createWidget(uidl, configuration); registerPaintable(id, w); return w; @@ -1764,4 +1774,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<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 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/server/CommunicationManager.java b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java index 737258a68d..2dfa6b1a19 100644 --- a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java @@ -96,7 +96,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; @@ -306,8 +306,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; @@ -324,9 +322,9 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, final PrintWriter outWriter, Window window, boolean analyzeLayouts) throws IOException, ServletException, PaintException { - // If repaint is requested, clean all ids in this root window if (repaintAll) { - for (final Iterator it = idPaintableMap.keySet().iterator(); it + // If repaint is requested, clean all ids in this root window + for (final Iterator<String> it = idPaintableMap.keySet().iterator(); it .hasNext();) { final Component c = (Component) idPaintableMap.get(it.next()); if (isChildOf(window, c)) { @@ -334,6 +332,12 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, paintableIdMap.remove(c); } } + // clean WindowCache + OpenWindowCache openWindowCache = currentlyOpenWindowsInClient + .get(window.getName()); + if (openWindowCache != null) { + openWindowCache.clear(); + } } // Removes application if it has stopped during variable changes @@ -382,6 +386,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) { @@ -395,8 +405,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)); @@ -567,10 +577,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 { @@ -617,6 +627,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("}]"); @@ -783,6 +817,7 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, paintAfterVariablechanges(request, response, applicationServlet, true, outWriter, window, false); + } catch (ServletException e) { // We will ignore all servlet exceptions } @@ -1102,9 +1137,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)); } @@ -1219,8 +1254,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) { @@ -1537,4 +1573,43 @@ 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. + * + * TODO make customlayout templates (from theme) to be cached here. + */ + 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); + } + + public void clear() { + res.clear(); + } + + } } diff --git a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java b/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java index 4bb382d13d..3bd547ba9d 100644 --- a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java +++ b/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java @@ -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; + } } diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java b/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java new file mode 100644 index 0000000000..1c6b3968c0 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java @@ -0,0 +1,360 @@ +package com.vaadin.terminal.gwt.widgetsetutils; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.net.JarURLConnection; +import java.net.MalformedURLException; +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.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +import com.vaadin.terminal.Paintable; +import com.vaadin.ui.ClientWidget; + +/** + * Utility class to collect widgetset related information from classpath. + * Utility will seek all directories from classpaths, and jar files having + * "Vaadin-Widgetsets" key in their manifest file. + * <p> + * Used by WidgetMapGenerator and ide tools to implement some monkey coding for + * you. + * <p> + * Developer notice: 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() { + } + + /** + * Finds server side widgets with {@link ClientWidget} annotation. + */ + 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; + + } + + /** + * Finds available widgetset names. + * + * @return + */ + public static Collection<String> getAvailableWidgetSets() { + Collection<String> widgetsets = new HashSet<String>(); + Set<URL> keySet = classpathLocations.keySet(); + for (URL url : keySet) { + searchForWidgetSets(url, widgetsets); + } + return widgetsets; + } + + private static void searchForWidgetSets(URL location, + Collection<String> widgetsets) { + + 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 .gwt.xml files + if (files[i].endsWith(".gwt.xml")) { + // remove the extension + String classname = files[i].substring(0, + files[i].length() - 8); + classname = classpathLocations.get(location) + "." + + classname; + widgetsets.add(classname); + } + } + } 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(); + + Manifest manifest = jarFile.getManifest(); + String value = manifest.getMainAttributes().getValue( + "Vaadin-Widgetsets"); + if (value != null) { + String[] widgetsetNames = value.split(","); + for (int i = 0; i < widgetsetNames.length; i++) { + String widgetsetname = widgetsetNames[i].trim() + .intern(); + widgetsets.add(widgetsetname); + } + } + } + } catch (IOException e) { + System.err.println(e); + } + + } + } + + /** + * Determine every URL location defined by the current classpath, and it's + * associated package name. + */ + private 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"); + + if (classpath.startsWith("\"")) { + classpath = classpath.substring(1); + } + if (classpath.endsWith("\"")) { + classpath = classpath.substring(0, classpath.length() - 1); + } + + System.err.println("Classpath: " + classpath); + + 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 { + URL url; + try { + url = new URL("file:" + + new File(classpathEntry).getCanonicalPath()); + url = new URL("jar:" + url.toExternalForm() + "!/"); + JarURLConnection conn = (JarURLConnection) url + .openConnection(); + System.out.println(url); + JarFile jarFile = conn.getJarFile(); + Manifest manifest = jarFile.getManifest(); + Attributes mainAttributes = manifest.getMainAttributes(); + if (mainAttributes.getValue("Vaadin-Widgetsets") != null) { + System.err.println("Accepted jar file" + url); + return true; + } + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + 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 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()); + } + + System.out.println(); + System.out.println("Searching available widgetsets..."); + + Collection<String> availableWidgetSets = ClassPathExplorer + .getAvailableWidgetSets(); + for (String string : availableWidgetSets) { + System.out.println(string); + } + } +}
\ No newline at end of file diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java new file mode 100644 index 0000000000..bc2e99732b --- /dev/null +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java @@ -0,0 +1,219 @@ +package com.vaadin.terminal.gwt.widgetsetutils; + +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 (WidgetMap is equal to all permutations atm) + 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.addImport("com.google.gwt.core.client.GWT"); + composer.setSuperclass("com.vaadin.terminal.gwt.client.WidgetMap"); + SourceWriter sourceWriter = composer.createSourceWriter(context, + printWriter); + + Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation = getUsedPaintables(); + + validatePaintables(logger, context, paintablesHavingWidgetAnnotation); + + // 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)"); + + } + + /** + * Verifies that all client side components are available for client side + * GWT module. + * + * @param logger + * @param context + * @param paintablesHavingWidgetAnnotation + */ + private void validatePaintables( + TreeLogger logger, + GeneratorContext context, + Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation) { + TypeOracle typeOracle = context.getTypeOracle(); + + for (Iterator<Class<? extends Paintable>> iterator = paintablesHavingWidgetAnnotation + .iterator(); iterator.hasNext();) { + Class<? extends Paintable> class1 = 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 (but mapped " + + "for component found in classpath). If this is not " + + "intentional, check your gwt module definition file."); + iterator.remove(); + } + + } + logger.log(Type.INFO, + "Widget set will contain implementations for following components: " + + paintablesHavingWidgetAnnotation.toString()); + } + + /** + * This method is protected to allow easy creation of optimized widgetsets. + * <p> + * TODO we need some sort of mechanism to easily 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. + * + * @return a collections of Vaadin components that will be added to + * widgetset + */ + 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 GWT.create("); + sourceWriter.print(clientClass.getName()); + sourceWriter.println(".class );"); + sourceWriter.print("else "); + } + sourceWriter + .println("return GWT.create( com.vaadin.terminal.gwt.client.ui.VUnknownComponent.class );"); + sourceWriter.outdent(); + 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.outdent(); + sourceWriter.println("}"); + + } + +} diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java new file mode 100644 index 0000000000..c2c888c4bb --- /dev/null +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java @@ -0,0 +1,134 @@ +package com.vaadin.terminal.gwt.widgetsetutils; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintStream; +import java.io.Reader; +import java.util.Collection; +import java.util.HashSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Helper class to update widgetsets GWT module configuration file. Can be used + * command line or via IDE tools. + */ +public class WidgetSetBuilder { + + public static void main(String[] args) throws IOException { + if (args.length == 0) { + printUsage(); + } else { + String widgetsetname = args[0]; + String sourcepath = args[1]; + updateWidgetSet(widgetsetname, sourcepath); + + } + } + + public static void updateWidgetSet(final String widgetset, String sourcepath) + throws IOException, FileNotFoundException { + String widgetsetfilename = sourcepath + "/" + + widgetset.replace(".", "/") + ".gwt.xml"; + File widgetsetFile = new File(widgetsetfilename); + if (!widgetsetFile.exists()) { + // create empty gwt module file + widgetsetFile.createNewFile(); + PrintStream printStream = new PrintStream(new FileOutputStream( + widgetsetFile)); + printStream.print("<module>\n\n</module>\n"); + printStream.close(); + } + + String content = readFile(widgetsetFile); + + Collection<String> oldInheritedWidgetsets = getCurrentWidgetSets(content); + + Collection<String> availableWidgetSets = ClassPathExplorer + .getAvailableWidgetSets(); + + // add widgetsets that do not exist + for (String ws : availableWidgetSets) { + if (ws.equals(widgetset)) { + // do not inherit the module itself + continue; + } + if (!oldInheritedWidgetsets.contains(ws)) { + content = addWidgetSet(ws, content); + } + } + + for (String ws : oldInheritedWidgetsets) { + if (!availableWidgetSets.contains(ws)) { + // widgetset not available in classpath + content = removeWidgetSet(ws, content); + } + } + + commitChanges(widgetsetfilename, content); + } + + private static String removeWidgetSet(String ws, String content) { + return content.replaceFirst("<inherits name=\"" + ws + "\"[^/]*/>", ""); + } + + private static void commitChanges(String widgetsetfilename, String content) + throws IOException { + BufferedWriter bufferedWriter = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(widgetsetfilename))); + bufferedWriter.write(content); + bufferedWriter.close(); + } + + private static String addWidgetSet(String ws, String content) { + return content.replace("</module>", "\n\t<inherits name=\"" + ws + + "\" />" + "\n</module>"); + } + + private static Collection<String> getCurrentWidgetSets(String content) { + HashSet<String> hashSet = new HashSet<String>(); + Pattern inheritsPattern = Pattern.compile(" name=\"([^\"]*)\""); + + Matcher matcher = inheritsPattern.matcher(content); + + while (matcher.find()) { + String possibleWidgetSet = matcher.group(1); + if (possibleWidgetSet.toLowerCase().contains("widgetset")) { + hashSet.add(possibleWidgetSet); + } + } + return hashSet; + } + + private static String readFile(File widgetsetFile) throws IOException { + Reader fi = new FileReader(widgetsetFile); + BufferedReader bufferedReader = new BufferedReader(fi); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = bufferedReader.readLine()) != null) { + sb.append(line); + sb.append("\n"); + } + return sb.toString(); + } + + private static void printUsage() { + PrintStream o = System.out; + o.println(WidgetSetBuilder.class.getSimpleName() + " usage:"); + o.println("\t1. Set the same classpath as you will " + + "have for the GWT compiler."); + o.println("\t2. Give the widgetsetname (to be created or updated)" + + " as first parameter, source path as a second parameter"); + o.println(); + o + .println("All found vaadin widgetsets will be inherited in given widgetset"); + + } + +} diff --git a/src/com/vaadin/tests/book/BookTestApplication.java b/src/com/vaadin/tests/book/BookTestApplication.java index a55a0769c1..6d3b653baf 100644 --- a/src/com/vaadin/tests/book/BookTestApplication.java +++ b/src/com/vaadin/tests/book/BookTestApplication.java @@ -612,12 +612,8 @@ public class BookTestApplication extends com.vaadin.Application { } main.addComponent(new SSNField()); } - + // TODO add ClientWidget annotation if test is in use class PagingTable extends Table { - @Override - public String getTag() { - return "pagingtable"; - } } void example_Table(Window main, String param) { diff --git a/src/com/vaadin/tools/WidgetsetCompiler.java b/src/com/vaadin/tools/WidgetsetCompiler.java index 0421164873..ce7ab37625 100644 --- a/src/com/vaadin/tools/WidgetsetCompiler.java +++ b/src/com/vaadin/tools/WidgetsetCompiler.java @@ -2,6 +2,8 @@ package com.vaadin.tools; import java.lang.reflect.Method;
+import com.vaadin.terminal.gwt.widgetsetutils.WidgetSetBuilder;
+
/**
* A wrapper for the GWT 1.6 compiler that runs the compiler in a new thread.
*
@@ -44,6 +46,13 @@ public class WidgetsetCompiler { try {
// GWTCompiler.main(args);
// avoid warnings
+
+ String wsname = args[args.length - 1];
+
+ // TODO expecting this is launched via eclipse WTP
+ // project
+ WidgetSetBuilder.updateWidgetSet(wsname, "src");
+
System.setProperty("gwt.nowarn.legacy.tools", "true");
Class<?> compilerClass = Class
.forName("com.google.gwt.dev.GWTCompiler");
diff --git a/src/com/vaadin/ui/AbsoluteLayout.java b/src/com/vaadin/ui/AbsoluteLayout.java index d9f40d7253..8e382622ca 100644 --- a/src/com/vaadin/ui/AbsoluteLayout.java +++ b/src/com/vaadin/ui/AbsoluteLayout.java @@ -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>(); @@ -29,11 +30,6 @@ public class AbsoluteLayout extends AbstractLayout { setSizeFull(); } - @Override - public String getTag() { - return VAbsoluteLayout.TAGNAME; - } - public Iterator<Component> getComponentIterator() { return components.iterator(); } diff --git a/src/com/vaadin/ui/AbstractComponent.java b/src/com/vaadin/ui/AbstractComponent.java index 39a0cf4f83..76fcd0ded3 100644 --- a/src/com/vaadin/ui/AbstractComponent.java +++ b/src/com/vaadin/ui/AbstractComponent.java @@ -145,9 +145,27 @@ public abstract class AbstractComponent implements Component, MethodEventSource /** * Gets the UIDL tag corresponding to the component. * + * <p> + * Note! In version 6.2 the method for mapping server side components to + * their client side counterparts was enhanced. This method was made final + * to intentionally "break" code where it is needed. If your code does not + * compile due overriding this method, it is very likely that you need to: + * <ul> + * <li>remove the implementation of getTag + * <li>add {@link ClientWidget} annotation to your component + * </ul> + * * @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 final String getTag() { + return ""; + } public void setDebugId(String id) { testingId = id; @@ -604,7 +622,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 +678,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; } diff --git a/src/com/vaadin/ui/AbstractLayout.java b/src/com/vaadin/ui/AbstractLayout.java index 3604e5ea1d..ce4b3e40c7 100644 --- a/src/com/vaadin/ui/AbstractLayout.java +++ b/src/com/vaadin/ui/AbstractLayout.java @@ -26,14 +26,6 @@ public abstract class AbstractLayout extends AbstractComponentContainer /* * (non-Javadoc) * - * @see com.vaadin.ui.AbstractComponent#getTag() - */ - @Override - public abstract String getTag(); - - /* - * (non-Javadoc) - * * @see com.vaadin.ui.Layout#setMargin(boolean) */ public void setMargin(boolean enabled) { @@ -63,8 +55,7 @@ public abstract class AbstractLayout extends AbstractComponentContainer /* * (non-Javadoc) * - * @see com.vaadin.ui.Layout#setMargin(boolean, boolean, boolean, - * boolean) + * @see com.vaadin.ui.Layout#setMargin(boolean, boolean, boolean, boolean) */ public void setMargin(boolean topEnabled, boolean rightEnabled, boolean bottomEnabled, boolean leftEnabled) { @@ -77,8 +68,7 @@ public abstract class AbstractLayout extends AbstractComponentContainer /* * (non-Javadoc) * - * @see - * com.vaadin.ui.AbstractComponent#paintContent(com.vaadin + * @see com.vaadin.ui.AbstractComponent#paintContent(com.vaadin * .terminal.PaintTarget) */ @Override diff --git a/src/com/vaadin/ui/AbstractOrderedLayout.java b/src/com/vaadin/ui/AbstractOrderedLayout.java index 762a447456..b43d155714 100644 --- a/src/com/vaadin/ui/AbstractOrderedLayout.java +++ b/src/com/vaadin/ui/AbstractOrderedLayout.java @@ -39,16 +39,6 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements private boolean spacing = false; /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "orderedlayout"; - } - - /** * Add a component into this container. The component is added to the right * or under the previous component. * diff --git a/src/com/vaadin/ui/AbstractSelect.java b/src/com/vaadin/ui/AbstractSelect.java index b2e52254f6..7df90c8ca6 100644 --- a/src/com/vaadin/ui/AbstractSelect.java +++ b/src/com/vaadin/ui/AbstractSelect.java @@ -512,16 +512,6 @@ public abstract class AbstractSelect extends AbstractField implements } /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "select"; - } - - /** * Gets the visible item ids. In Select, this returns list of all item ids, * but can be overriden in subclasses if they paint only part of the items * to the terminal or null if no items is visible. diff --git a/src/com/vaadin/ui/Accordion.java b/src/com/vaadin/ui/Accordion.java index 73b4c03743..dd481e7825 100644 --- a/src/com/vaadin/ui/Accordion.java +++ b/src/com/vaadin/ui/Accordion.java @@ -1,11 +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 - public String getTag() { - return "accordion"; - } - } diff --git a/src/com/vaadin/ui/Button.java b/src/com/vaadin/ui/Button.java index e4ca734d34..6801bfa176 100644 --- a/src/com/vaadin/ui/Button.java +++ b/src/com/vaadin/ui/Button.java @@ -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 */ @@ -112,16 +114,6 @@ public class Button extends AbstractField { } /** - * Gets component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "button"; - } - - /** * Paints the content of this component. * * @param event diff --git a/src/com/vaadin/ui/CheckBox.java b/src/com/vaadin/ui/CheckBox.java index 32b47412a3..0ffafe3d02 100644 --- a/src/com/vaadin/ui/CheckBox.java +++ b/src/com/vaadin/ui/CheckBox.java @@ -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 index 0000000000..af58e20da9 --- /dev/null +++ b/src/com/vaadin/ui/ClientWidget.java @@ -0,0 +1,35 @@ +/** + * + */ +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}. + * <p> + * With this annotation server side Vaadin component is marked to have a client + * side counterpart. The value of the annotation is the class of client side + * implementation. + * + * <p> + * Note, even though client side implementation is needed during development, + * one may safely remove them from classpath of the production server. + * + * + * @since 6.2 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ClientWidget { + /** + * @return the client side counterpart for the annotated component + */ + Class<? extends Paintable> value(); +} diff --git a/src/com/vaadin/ui/CssLayout.java b/src/com/vaadin/ui/CssLayout.java index 65cfa36b28..0b98ac7975 100644 --- a/src/com/vaadin/ui/CssLayout.java +++ b/src/com/vaadin/ui/CssLayout.java @@ -50,15 +50,11 @@ 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; - @Override - public String getTag() { - return VCssLayout.TAGNAME; - } - /** * Custom layout slots containing the components. */ diff --git a/src/com/vaadin/ui/CustomComponent.java b/src/com/vaadin/ui/CustomComponent.java index 19fb081047..5d086ddaf9 100644 --- a/src/com/vaadin/ui/CustomComponent.java +++ b/src/com/vaadin/ui/CustomComponent.java @@ -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 { /** @@ -143,11 +145,6 @@ public class CustomComponent extends AbstractComponentContainer { this.componentType = componentType; } - @Override - public String getTag() { - return "customcomponent"; - } - private class ComponentIterator implements Iterator, Serializable { boolean first = getCompositionRoot() != null; diff --git a/src/com/vaadin/ui/CustomLayout.java b/src/com/vaadin/ui/CustomLayout.java index d0d70fcc16..f0ad7514ea 100644 --- a/src/com/vaadin/ui/CustomLayout.java +++ b/src/com/vaadin/ui/CustomLayout.java @@ -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; @@ -96,16 +98,6 @@ public class CustomLayout extends AbstractLayout { } /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "customlayout"; - } - - /** * Adds the component into this container to given location. If the location * is already populated, the old component is removed. * diff --git a/src/com/vaadin/ui/DateField.java b/src/com/vaadin/ui/DateField.java index dc062be668..69d6108152 100644 --- a/src/com/vaadin/ui/DateField.java +++ b/src/com/vaadin/ui/DateField.java @@ -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 */ @@ -242,15 +244,6 @@ public class DateField extends AbstractField { } /* - * Gets the components UIDL tag string. Don't add a JavaDoc comment here, we - * use the default documentation from implemented interface. - */ - @Override - public String getTag() { - return "datefield"; - } - - /* * Invoked when a variable of the component changes. Don't add a JavaDoc * comment here, we use the default documentation from implemented * interface. diff --git a/src/com/vaadin/ui/Embedded.java b/src/com/vaadin/ui/Embedded.java index 3b0acfee5e..3b20641c5f 100644 --- a/src/com/vaadin/ui/Embedded.java +++ b/src/com/vaadin/ui/Embedded.java @@ -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 { /** @@ -100,16 +102,6 @@ public class Embedded extends AbstractComponent { } /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "embedded"; - } - - /** * Invoked when the component state should be painted. */ @Override diff --git a/src/com/vaadin/ui/Form.java b/src/com/vaadin/ui/Form.java index 1741fe591f..c6c9a5a738 100644 --- a/src/com/vaadin/ui/Form.java +++ b/src/com/vaadin/ui/Form.java @@ -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 { @@ -175,12 +177,6 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item, /* Documented in interface */ @Override - public String getTag() { - return "form"; - } - - /* Documented in interface */ - @Override public void paintContent(PaintTarget target) throws PaintException { super.paintContent(target); layout.paint(target); diff --git a/src/com/vaadin/ui/FormLayout.java b/src/com/vaadin/ui/FormLayout.java index 1fbfcf2ee4..4b42f0d8fb 100644 --- a/src/com/vaadin/ui/FormLayout.java +++ b/src/com/vaadin/ui/FormLayout.java @@ -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() { @@ -28,9 +31,4 @@ public class FormLayout extends OrderedLayout { setMargin(true, false, true, false); } - @Override - public String getTag() { - return "formlayout"; - } - } diff --git a/src/com/vaadin/ui/GridLayout.java b/src/com/vaadin/ui/GridLayout.java index 165b26491e..d07e232b1a 100644 --- a/src/com/vaadin/ui/GridLayout.java +++ b/src/com/vaadin/ui/GridLayout.java @@ -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 { @@ -637,17 +639,6 @@ public class GridLayout extends AbstractLayout implements } /** - * Gets the components UIDL tag. - * - * @return the Component UIDL tag as string. - * @see com.vaadin.ui.AbstractComponent#getTag() - */ - @Override - public String getTag() { - return "gridlayout"; - } - - /** * This class defines an area on a grid. An Area is defined by the cells of * its upper left corner (column1,row1) and lower right corner * (column2,row2). diff --git a/src/com/vaadin/ui/HorizontalLayout.java b/src/com/vaadin/ui/HorizontalLayout.java index 820b0c29de..31941f1024 100644 --- a/src/com/vaadin/ui/HorizontalLayout.java +++ b/src/com/vaadin/ui/HorizontalLayout.java @@ -1,5 +1,7 @@ package com.vaadin.ui; +import com.vaadin.terminal.gwt.client.ui.VHorizontalLayout; + /** * Horizontal layout * @@ -12,15 +14,11 @@ package com.vaadin.ui; * @since 5.3 */ @SuppressWarnings("serial") +@ClientWidget(VHorizontalLayout.class) public class HorizontalLayout extends AbstractOrderedLayout { public HorizontalLayout() { } - @Override - public String getTag() { - return "horizontallayout"; - } - } diff --git a/src/com/vaadin/ui/Label.java b/src/com/vaadin/ui/Label.java index edd827d2a5..22aa0514e1 100644 --- a/src/com/vaadin/ui/Label.java +++ b/src/com/vaadin/ui/Label.java @@ -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 { @@ -150,16 +152,6 @@ public class Label extends AbstractComponent implements Property, } /** - * Get the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "label"; - } - - /** * Set the component to read-only. Readonly is not used in label. * * @param readOnly diff --git a/src/com/vaadin/ui/Link.java b/src/com/vaadin/ui/Link.java index 6deb05a99a..551e6c19ea 100644 --- a/src/com/vaadin/ui/Link.java +++ b/src/com/vaadin/ui/Link.java @@ -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 */ @@ -85,16 +87,6 @@ public class Link extends AbstractComponent { } /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "link"; - } - - /** * Paints the content of this component. * * @param target diff --git a/src/com/vaadin/ui/ListSelect.java b/src/com/vaadin/ui/ListSelect.java index 7860474433..b2c4866b4a 100644 --- a/src/com/vaadin/ui/ListSelect.java +++ b/src/com/vaadin/ui/ListSelect.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.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; diff --git a/src/com/vaadin/ui/MenuBar.java b/src/com/vaadin/ui/MenuBar.java index 0ce6e725d9..30049431d3 100644 --- a/src/com/vaadin/ui/MenuBar.java +++ b/src/com/vaadin/ui/MenuBar.java @@ -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 @@ -31,12 +33,6 @@ public class MenuBar extends AbstractComponent { private Resource submenuIcon; private MenuItem moreItem; - /** Tag is the UIDL element name for client-server communications. */ - @Override - public java.lang.String getTag() { - return "menubar"; - } - /** Paint (serialise) the component for the client. */ @Override public void paintContent(PaintTarget target) throws PaintException { @@ -340,10 +336,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 +493,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; diff --git a/src/com/vaadin/ui/NativeButton.java b/src/com/vaadin/ui/NativeButton.java index 4df771d054..5a24db40ba 100644 --- a/src/com/vaadin/ui/NativeButton.java +++ b/src/com/vaadin/ui/NativeButton.java @@ -43,9 +43,4 @@ public class NativeButton extends Button { super(caption, dataSource); } - @Override - public String getTag() { - return "nativebutton"; - } - }
\ No newline at end of file diff --git a/src/com/vaadin/ui/NativeSelect.java b/src/com/vaadin/ui/NativeSelect.java index e178a39397..e57daeda55 100644 --- a/src/com/vaadin/ui/NativeSelect.java +++ b/src/com/vaadin/ui/NativeSelect.java @@ -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 diff --git a/src/com/vaadin/ui/OptionGroup.java b/src/com/vaadin/ui/OptionGroup.java index 861b57f5c6..ab925f8785 100644 --- a/src/com/vaadin/ui/OptionGroup.java +++ b/src/com/vaadin/ui/OptionGroup.java @@ -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() { diff --git a/src/com/vaadin/ui/OrderedLayout.java b/src/com/vaadin/ui/OrderedLayout.java index 572d621919..5689c76ed3 100644 --- a/src/com/vaadin/ui/OrderedLayout.java +++ b/src/com/vaadin/ui/OrderedLayout.java @@ -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 */ diff --git a/src/com/vaadin/ui/Panel.java b/src/com/vaadin/ui/Panel.java index b8c6b1f222..03f1857386 100644 --- a/src/com/vaadin/ui/Panel.java +++ b/src/com/vaadin/ui/Panel.java @@ -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 { @@ -275,16 +277,6 @@ public class Panel extends AbstractComponentContainer implements Scrollable, } /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "panel"; - } - - /** * Adds the component into this container. * * @param c diff --git a/src/com/vaadin/ui/PopupView.java b/src/com/vaadin/ui/PopupView.java index f2d6259c75..9d8144f78e 100644 --- a/src/com/vaadin/ui/PopupView.java +++ b/src/com/vaadin/ui/PopupView.java @@ -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; @@ -275,14 +277,6 @@ public class PopupView extends AbstractComponentContainer { */ /** - * @see com.vaadin.ui.AbstractComponent#getTag() - */ - @Override - public java.lang.String getTag() { - return "popupview"; - } - - /** * Paint (serialize) the component for the client. * * @see com.vaadin.ui.AbstractComponent#paintContent(com.vaadin.terminal.PaintTarget) diff --git a/src/com/vaadin/ui/ProgressIndicator.java b/src/com/vaadin/ui/ProgressIndicator.java index 1ad5848dfb..b896634cd9 100644 --- a/src/com/vaadin/ui/ProgressIndicator.java +++ b/src/com/vaadin/ui/ProgressIndicator.java @@ -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 { @@ -71,16 +73,6 @@ public class ProgressIndicator extends AbstractField implements Property, } /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "progressindicator"; - } - - /** * Sets the component to read-only. Readonly is not used in * ProgressIndicator. * diff --git a/src/com/vaadin/ui/RichTextArea.java b/src/com/vaadin/ui/RichTextArea.java index 4c1c281811..49f329f586 100644 --- a/src/com/vaadin/ui/RichTextArea.java +++ b/src/com/vaadin/ui/RichTextArea.java @@ -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 diff --git a/src/com/vaadin/ui/Select.java b/src/com/vaadin/ui/Select.java index ea8113ae42..ad9ffb01cd 100644 --- a/src/com/vaadin/ui/Select.java +++ b/src/com/vaadin/ui/Select.java @@ -23,13 +23,13 @@ import com.vaadin.terminal.Resource; * set of choices is presented as a set of {@link com.vaadin.data.Item}s in a * {@link com.vaadin.data.Container}. * </p> - * + * * <p> * A <code>Select</code> component may be in single- or multiselect mode. * Multiselect mode means that more than one item can be selected * simultaneously. * </p> - * + * * @author IT Mill Ltd. * @version * @VERSION@ @@ -38,441 +38,431 @@ import com.vaadin.terminal.Resource; @SuppressWarnings("serial") public class Select extends AbstractSelect implements AbstractSelect.Filtering { - /** - * Holds value of property pageLength. 0 disables paging. - */ - protected int pageLength = 10; - - private int columns = 0; - - // Current page when the user is 'paging' trough options - private int currentPage = -1; - - private int filteringMode = FILTERINGMODE_STARTSWITH; - - private String filterstring; - private String prevfilterstring; - private List filteredOptions; - - /** - * Flag to indicate that request repaint is called by filter request only - */ - private boolean optionRequest; - - /* Constructors */ - - /* Component methods */ - - public Select() { - super(); - } - - public Select(String caption, Collection options) { - super(caption, options); - } - - public Select(String caption, Container dataSource) { - super(caption, dataSource); - } - - public Select(String caption) { - super(caption); - } - - /** - * Paints the content of this component. - * - * @param target - * the Paint Event. - * @throws PaintException - * if the paint operation failed. - */ - @Override - public void paintContent(PaintTarget target) throws PaintException { - if (isMultiSelect()) { - // background compatibility hack. This object shouldn't be used for - // multiselect lists anymore (ListSelect instead). This fallbacks to - // a simpler paint method in super class. - super.paintContent(target); - return; - } - - // clear caption change listeners - getCaptionChangeListener().clear(); - - // The tab ordering number - if (getTabIndex() != 0) { - target.addAttribute("tabindex", getTabIndex()); - } - - // If the field is modified, but not committed, set modified attribute - if (isModified()) { - target.addAttribute("modified", true); - } - - // Adds the required attribute - if (isRequired()) { - target.addAttribute("required", true); - } - - if (isNewItemsAllowed()) { - target.addAttribute("allownewitem", true); - } - - boolean needNullSelectOption = false; - if (isNullSelectionAllowed()) { - target.addAttribute("nullselect", true); - needNullSelectOption = (getNullSelectionItemId() == null); - if (!needNullSelectOption) { - target.addAttribute("nullselectitem", true); - } - } - - // Constructs selected keys array - String[] selectedKeys; - if (isMultiSelect()) { - selectedKeys = new String[((Set) getValue()).size()]; - } else { - selectedKeys = new String[(getValue() == null - && getNullSelectionItemId() == null ? 0 : 1)]; - } - - target.addAttribute("pagelength", pageLength); - - target.addAttribute("filteringmode", getFilteringMode()); - - // Paints the options and create array of selected id keys - // TODO Also use conventional rendering if lazy loading is not supported - // by terminal - int keyIndex = 0; - - target.startTag("options"); - - if (currentPage < 0) { - optionRequest = false; - currentPage = 0; - filterstring = ""; - } - - List options = getFilteredOptions(); - options = sanitetizeList(options, needNullSelectOption); - - final boolean paintNullSelection = needNullSelectOption - && (currentPage == 0 && (getFilteringMode() == FILTERINGMODE_OFF - || filterstring == null || filterstring.equals(""))); - - if (paintNullSelection) { - target.startTag("so"); - target.addAttribute("caption", ""); - target.addAttribute("key", ""); - target.endTag("so"); - } - - final Iterator i = options.iterator(); - // Paints the available selection options from data source - - while (i.hasNext()) { - - final Object id = i.next(); - - if (!isNullSelectionAllowed() && id != null - && id.equals(getNullSelectionItemId()) && !isSelected(id)) { - continue; - } - - // Gets the option attribute values - final String key = itemIdMapper.key(id); - final String caption = getItemCaption(id); - final Resource icon = getItemIcon(id); - getCaptionChangeListener().addNotifierForItem(id); - - // Paints the option - target.startTag("so"); - if (icon != null) { - target.addAttribute("icon", icon); - } - target.addAttribute("caption", caption); - if (id != null && id.equals(getNullSelectionItemId())) { - target.addAttribute("nullselection", true); - } - target.addAttribute("key", key); - if (isSelected(id) && keyIndex < selectedKeys.length) { - target.addAttribute("selected", true); - selectedKeys[keyIndex++] = key; - } - target.endTag("so"); - } - target.endTag("options"); - - target.addAttribute("totalitems", size() - + (needNullSelectOption ? 1 : 0)); - if (filteredOptions != null) { - target.addAttribute("totalMatches", filteredOptions.size() - + (needNullSelectOption ? 1 : 0)); - } - - // Paint variables - target.addVariable(this, "selected", selectedKeys); - if (isNewItemsAllowed()) { - target.addVariable(this, "newitem", ""); - } - - target.addVariable(this, "filter", filterstring); - target.addVariable(this, "page", currentPage); - - currentPage = -1; // current page is always set by client - - optionRequest = true; - } - - /** - * Makes correct sublist of given list of options. - * - * If paint is not an option request (affected by page or filter change), - * page will be the one where possible selection exists. - * - * Detects proper first and last item in list to return right page of - * options. - * - * @param options - * @param needNullSelectOption - * flag to indicate if nullselect option needs to be taken into - * consideration - */ - private List sanitetizeList(List options, boolean needNullSelectOption) { - - if (options.size() > pageLength) { - int first = currentPage * pageLength; - int last = first + pageLength; - if (needNullSelectOption) { - if (currentPage > 0) { - first--; - } - last--; - } - if (options.size() < last) { - last = options.size(); - } - if (!optionRequest) { - // TODO ensure proper page - if (!isMultiSelect()) { - Object selection = getValue(); - if (selection != null) { - int index = options.indexOf(selection); - if (index != -1 && (index < first || index >= last)) { - int newPage = (index + (needNullSelectOption ? 1 - : 0)) - / pageLength; - currentPage = newPage; - return sanitetizeList(options, needNullSelectOption); - } - } - } - } - - return options.subList(first, last); - } else { - return options; - } - } - - protected List getFilteredOptions() { - if (filterstring == null || filterstring.equals("") - || filteringMode == FILTERINGMODE_OFF) { - prevfilterstring = null; - filteredOptions = new LinkedList(getItemIds()); - return filteredOptions; - } - - if (filterstring.equals(prevfilterstring)) { - return filteredOptions; - } - - Collection items; - if (prevfilterstring != null - && filterstring.startsWith(prevfilterstring)) { - items = filteredOptions; - } else { - items = getItemIds(); - } - prevfilterstring = filterstring; - - filteredOptions = new LinkedList(); - for (final Iterator it = items.iterator(); it.hasNext();) { - final Object itemId = it.next(); - String caption = getItemCaption(itemId); - if (caption == null || caption.equals("")) { - continue; - } else { - caption = caption.toLowerCase(); - } - switch (filteringMode) { - case FILTERINGMODE_CONTAINS: - if (caption.indexOf(filterstring) > -1) { - filteredOptions.add(itemId); - } - break; - case FILTERINGMODE_STARTSWITH: - default: - if (caption.startsWith(filterstring)) { - filteredOptions.add(itemId); - } - break; - } - } - - return filteredOptions; - } - - /** - * Invoked when the value of a variable has changed. - * - * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object, - * java.util.Map) - */ - @Override - public void changeVariables(Object source, Map variables) { - - // Selection change - if (variables.containsKey("selected")) { - final String[] ka = (String[]) variables.get("selected"); - - if (isMultiSelect()) { - // Multiselect mode - - // TODO Optimize by adding repaintNotNeeded whan applicaple - - // Converts the key-array to id-set - final LinkedList s = new LinkedList(); - for (int i = 0; i < ka.length; i++) { - final Object id = itemIdMapper.get(ka[i]); - if (id != null && containsId(id)) { - s.add(id); - } - } - - // Limits the deselection to the set of visible items - // (non-visible items can not be deselected) - final Collection visible = getVisibleItemIds(); - if (visible != null) { - Set newsel = (Set) getValue(); - if (newsel == null) { - newsel = new HashSet(); - } else { - newsel = new HashSet(newsel); - } - newsel.removeAll(visible); - newsel.addAll(s); - setValue(newsel, true); - } - } else { - // Single select mode - if (ka.length == 0) { - - // Allows deselection only if the deselected item is visible - final Object current = getValue(); - final Collection visible = getVisibleItemIds(); - if (visible != null && visible.contains(current)) { - setValue(null, true); - } - } else { - final Object id = itemIdMapper.get(ka[0]); - if (id != null && id.equals(getNullSelectionItemId())) { - setValue(null, true); - } else { - setValue(id, true); - } - } - } - } - - String newFilter; - if ((newFilter = (String) variables.get("filter")) != null) { - // this is a filter request - currentPage = ((Integer) variables.get("page")).intValue(); - filterstring = newFilter; - if (filterstring != null) { - filterstring = filterstring.toLowerCase(); - } - optionRepaint(); - return; - } - - // New option entered (and it is allowed) - if (isNewItemsAllowed()) { - final String newitem = (String) variables.get("newitem"); - if (newitem != null && newitem.length() > 0) { - getNewItemHandler().addNewItem(newitem); - // rebuild list - filterstring = null; - prevfilterstring = null; - } - } - - } - - @Override - public void requestRepaint() { - super.requestRepaint(); - optionRequest = false; - prevfilterstring = filterstring; - filterstring = null; - } - - private void optionRepaint() { - super.requestRepaint(); - } - - /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "select"; - } - - public void setFilteringMode(int filteringMode) { - this.filteringMode = filteringMode; - } - - public int getFilteringMode() { - return filteringMode; - } - - /** - * Note, one should use more generic setWidth(String) method instead of - * this. This now days actually converts columns to width with em css unit. - * - * Sets the number of columns in the editor. If the number of columns is set - * 0, the actual number of displayed columns is determined implicitly by the - * adapter. - * - * @deprecated - * - * @param columns - * the number of columns to set. - */ - @Deprecated - public void setColumns(int columns) { - if (columns < 0) { - columns = 0; - } - if (this.columns != columns) { - this.columns = columns; - setWidth(columns, Select.UNITS_EM); - requestRepaint(); - } - } - - /** - * @deprecated see setter function - * @return - */ - @Deprecated - public int getColumns() { - return columns; - } + /** + * Holds value of property pageLength. 0 disables paging. + */ + protected int pageLength = 10; + + private int columns = 0; + + // Current page when the user is 'paging' trough options + private int currentPage = -1; + + private int filteringMode = FILTERINGMODE_STARTSWITH; + + private String filterstring; + private String prevfilterstring; + private List filteredOptions; + + /** + * Flag to indicate that request repaint is called by filter request only + */ + private boolean optionRequest; + + /* Constructors */ + + /* Component methods */ + + public Select() { + super(); + } + + public Select(String caption, Collection options) { + super(caption, options); + } + + public Select(String caption, Container dataSource) { + super(caption, dataSource); + } + + public Select(String caption) { + super(caption); + } + + /** + * Paints the content of this component. + * + * @param target + * the Paint Event. + * @throws PaintException + * if the paint operation failed. + */ + @Override + public void paintContent(PaintTarget target) throws PaintException { + if (isMultiSelect()) { + // background compatibility hack. This object shouldn't be used for + // multiselect lists anymore (ListSelect instead). This fallbacks to + // a simpler paint method in super class. + super.paintContent(target); + return; + } + + // clear caption change listeners + getCaptionChangeListener().clear(); + + // The tab ordering number + if (getTabIndex() != 0) { + target.addAttribute("tabindex", getTabIndex()); + } + + // If the field is modified, but not committed, set modified attribute + if (isModified()) { + target.addAttribute("modified", true); + } + + // Adds the required attribute + if (isRequired()) { + target.addAttribute("required", true); + } + + if (isNewItemsAllowed()) { + target.addAttribute("allownewitem", true); + } + + boolean needNullSelectOption = false; + if (isNullSelectionAllowed()) { + target.addAttribute("nullselect", true); + needNullSelectOption = (getNullSelectionItemId() == null); + if (!needNullSelectOption) { + target.addAttribute("nullselectitem", true); + } + } + + // Constructs selected keys array + String[] selectedKeys; + if (isMultiSelect()) { + selectedKeys = new String[((Set) getValue()).size()]; + } else { + selectedKeys = new String[(getValue() == null + && getNullSelectionItemId() == null ? 0 : 1)]; + } + + target.addAttribute("pagelength", pageLength); + + target.addAttribute("filteringmode", getFilteringMode()); + + // Paints the options and create array of selected id keys + // TODO Also use conventional rendering if lazy loading is not supported + // by terminal + int keyIndex = 0; + + target.startTag("options"); + + if (currentPage < 0) { + optionRequest = false; + currentPage = 0; + filterstring = ""; + } + + List options = getFilteredOptions(); + options = sanitetizeList(options, needNullSelectOption); + + final boolean paintNullSelection = needNullSelectOption + && (currentPage == 0 && (getFilteringMode() == FILTERINGMODE_OFF + || filterstring == null || filterstring.equals(""))); + + if (paintNullSelection) { + target.startTag("so"); + target.addAttribute("caption", ""); + target.addAttribute("key", ""); + target.endTag("so"); + } + + final Iterator i = options.iterator(); + // Paints the available selection options from data source + + while (i.hasNext()) { + + final Object id = i.next(); + + if (!isNullSelectionAllowed() && id != null + && id.equals(getNullSelectionItemId()) && !isSelected(id)) { + continue; + } + + // Gets the option attribute values + final String key = itemIdMapper.key(id); + final String caption = getItemCaption(id); + final Resource icon = getItemIcon(id); + getCaptionChangeListener().addNotifierForItem(id); + + // Paints the option + target.startTag("so"); + if (icon != null) { + target.addAttribute("icon", icon); + } + target.addAttribute("caption", caption); + if (id != null && id.equals(getNullSelectionItemId())) { + target.addAttribute("nullselection", true); + } + target.addAttribute("key", key); + if (isSelected(id) && keyIndex < selectedKeys.length) { + target.addAttribute("selected", true); + selectedKeys[keyIndex++] = key; + } + target.endTag("so"); + } + target.endTag("options"); + + target.addAttribute("totalitems", size() + + (needNullSelectOption ? 1 : 0)); + if (filteredOptions != null) { + target.addAttribute("totalMatches", filteredOptions.size() + + (needNullSelectOption ? 1 : 0)); + } + + // Paint variables + target.addVariable(this, "selected", selectedKeys); + if (isNewItemsAllowed()) { + target.addVariable(this, "newitem", ""); + } + + target.addVariable(this, "filter", filterstring); + target.addVariable(this, "page", currentPage); + + currentPage = -1; // current page is always set by client + + optionRequest = true; + } + + /** + * Makes correct sublist of given list of options. + * + * If paint is not an option request (affected by page or filter change), + * page will be the one where possible selection exists. + * + * Detects proper first and last item in list to return right page of + * options. + * + * @param options + * @param needNullSelectOption + * flag to indicate if nullselect option needs to be taken into + * consideration + */ + private List sanitetizeList(List options, boolean needNullSelectOption) { + + if (options.size() > pageLength) { + int first = currentPage * pageLength; + int last = first + pageLength; + if (needNullSelectOption) { + if (currentPage > 0) { + first--; + } + last--; + } + if (options.size() < last) { + last = options.size(); + } + if (!optionRequest) { + // TODO ensure proper page + if (!isMultiSelect()) { + Object selection = getValue(); + if (selection != null) { + int index = options.indexOf(selection); + if (index != -1 && (index < first || index >= last)) { + int newPage = (index + (needNullSelectOption ? 1 + : 0)) + / pageLength; + currentPage = newPage; + return sanitetizeList(options, needNullSelectOption); + } + } + } + } + + return options.subList(first, last); + } else { + return options; + } + } + + protected List getFilteredOptions() { + if (filterstring == null || filterstring.equals("") + || filteringMode == FILTERINGMODE_OFF) { + prevfilterstring = null; + filteredOptions = new LinkedList(getItemIds()); + return filteredOptions; + } + + if (filterstring.equals(prevfilterstring)) { + return filteredOptions; + } + + Collection items; + if (prevfilterstring != null + && filterstring.startsWith(prevfilterstring)) { + items = filteredOptions; + } else { + items = getItemIds(); + } + prevfilterstring = filterstring; + + filteredOptions = new LinkedList(); + for (final Iterator it = items.iterator(); it.hasNext();) { + final Object itemId = it.next(); + String caption = getItemCaption(itemId); + if (caption == null || caption.equals("")) { + continue; + } else { + caption = caption.toLowerCase(); + } + switch (filteringMode) { + case FILTERINGMODE_CONTAINS: + if (caption.indexOf(filterstring) > -1) { + filteredOptions.add(itemId); + } + break; + case FILTERINGMODE_STARTSWITH: + default: + if (caption.startsWith(filterstring)) { + filteredOptions.add(itemId); + } + break; + } + } + + return filteredOptions; + } + + /** + * Invoked when the value of a variable has changed. + * + * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object, + * java.util.Map) + */ + @Override + public void changeVariables(Object source, Map variables) { + + // Selection change + if (variables.containsKey("selected")) { + final String[] ka = (String[]) variables.get("selected"); + + if (isMultiSelect()) { + // Multiselect mode + + // TODO Optimize by adding repaintNotNeeded whan applicaple + + // Converts the key-array to id-set + final LinkedList s = new LinkedList(); + for (int i = 0; i < ka.length; i++) { + final Object id = itemIdMapper.get(ka[i]); + if (id != null && containsId(id)) { + s.add(id); + } + } + + // Limits the deselection to the set of visible items + // (non-visible items can not be deselected) + final Collection visible = getVisibleItemIds(); + if (visible != null) { + Set newsel = (Set) getValue(); + if (newsel == null) { + newsel = new HashSet(); + } else { + newsel = new HashSet(newsel); + } + newsel.removeAll(visible); + newsel.addAll(s); + setValue(newsel, true); + } + } else { + // Single select mode + if (ka.length == 0) { + + // Allows deselection only if the deselected item is visible + final Object current = getValue(); + final Collection visible = getVisibleItemIds(); + if (visible != null && visible.contains(current)) { + setValue(null, true); + } + } else { + final Object id = itemIdMapper.get(ka[0]); + if (id != null && id.equals(getNullSelectionItemId())) { + setValue(null, true); + } else { + setValue(id, true); + } + } + } + } + + String newFilter; + if ((newFilter = (String) variables.get("filter")) != null) { + // this is a filter request + currentPage = ((Integer) variables.get("page")).intValue(); + filterstring = newFilter; + if (filterstring != null) { + filterstring = filterstring.toLowerCase(); + } + optionRepaint(); + return; + } + + // New option entered (and it is allowed) + if (isNewItemsAllowed()) { + final String newitem = (String) variables.get("newitem"); + if (newitem != null && newitem.length() > 0) { + getNewItemHandler().addNewItem(newitem); + // rebuild list + filterstring = null; + prevfilterstring = null; + } + } + + } + + @Override + public void requestRepaint() { + super.requestRepaint(); + optionRequest = false; + prevfilterstring = filterstring; + filterstring = null; + } + + private void optionRepaint() { + super.requestRepaint(); + } + + public void setFilteringMode(int filteringMode) { + this.filteringMode = filteringMode; + } + + public int getFilteringMode() { + return filteringMode; + } + + /** + * Note, one should use more generic setWidth(String) method instead of + * this. This now days actually converts columns to width with em css unit. + * + * Sets the number of columns in the editor. If the number of columns is set + * 0, the actual number of displayed columns is determined implicitly by the + * adapter. + * + * @deprecated + * + * @param columns + * the number of columns to set. + */ + @Deprecated + public void setColumns(int columns) { + if (columns < 0) { + columns = 0; + } + if (this.columns != columns) { + this.columns = columns; + setWidth(columns, Select.UNITS_EM); + requestRepaint(); + } + } + + /** + * @deprecated see setter function + * @return + */ + @Deprecated + public int getColumns() { + return columns; + } } diff --git a/src/com/vaadin/ui/Slider.java b/src/com/vaadin/ui/Slider.java index ec9fc2c90b..7d06b8075a 100644 --- a/src/com/vaadin/ui/Slider.java +++ b/src/com/vaadin/ui/Slider.java @@ -1,503 +1,500 @@ -/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Map;
-
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * 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")
-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;
- }
-
-}
+/* +@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 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; + } + +} diff --git a/src/com/vaadin/ui/SplitPanel.java b/src/com/vaadin/ui/SplitPanel.java index 8e67f9c41a..7d510239e9 100644 --- a/src/com/vaadin/ui/SplitPanel.java +++ b/src/com/vaadin/ui/SplitPanel.java @@ -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 */ @@ -74,20 +76,6 @@ public class SplitPanel extends AbstractLayout { } /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - if (orientation == ORIENTATION_HORIZONTAL) { - return "hsplitpanel"; - } else { - return "vsplitpanel"; - } - } - - /** * Add a component into this container. The component is added to the right * or under the previous component. * @@ -218,6 +206,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()) { diff --git a/src/com/vaadin/ui/TabSheet.java b/src/com/vaadin/ui/TabSheet.java index f868902375..ed81fdb655 100644 --- a/src/com/vaadin/ui/TabSheet.java +++ b/src/com/vaadin/ui/TabSheet.java @@ -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 { @@ -158,16 +160,6 @@ public class TabSheet extends AbstractComponentContainer implements } /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "tabsheet"; - } - - /** * Moves all components from another container to this container. The * components are removed from the other container. * diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java index 33af634941..d2b255a1d3 100644 --- a/src/com/vaadin/ui/Table.java +++ b/src/com/vaadin/ui/Table.java @@ -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) */ @@ -2364,19 +2366,9 @@ public class Table extends AbstractSelect implements Action.Container, target.endTag("visiblecolumns"); } - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.AbstractSelect#getTag() - */ - @Override - public String getTag() { - return "table"; - } - /** * Gets the cached visible table contents. - * + * * @return the cached visible table contents. */ private Object[][] getVisibleCells() { @@ -2388,11 +2380,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 +2411,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 +2433,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 +2456,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 +2478,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 +2505,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 +2524,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 +2541,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes all Items from the Container. - * + * * @see com.vaadin.data.Container#removeAllItems() */ @Override @@ -2561,7 +2553,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 +2573,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 +2591,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 +2626,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 +2675,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 +2705,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 +2728,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 +2747,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 +2775,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 +2789,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 +2804,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 +2816,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 +2826,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 +2835,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 +2844,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 +2854,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 +2864,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 +2873,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 +2889,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 +2906,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 +2921,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 +2933,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 +2951,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 +2972,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 +2991,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 +3015,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 +3041,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 +3056,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 +3070,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 +3079,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 +3090,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 +3110,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 +3119,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 +3131,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 +3148,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 +3160,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 +3177,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 +3202,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 +3225,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 +3236,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Get the current cell style generator. - * + * */ public CellStyleGenerator getCellStyleGenerator() { return cellStyleGenerator; @@ -3261,7 +3253,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..a773617265 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; /** * <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 */ @@ -229,18 +231,10 @@ public class TextField extends AbstractField { } /* - * Gets the components UIDL tag string. Don't add a JavaDoc comment here, we - * use the default documentation from implemented interface. - */ - @Override - public String getTag() { - return "textfield"; - } - - /* - * Invoked when a variable of the component changes. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. + * (non-Javadoc) + * + * @see com.vaadin.ui.AbstractField#changeVariables(java.lang.Object, + * java.util.Map) */ @Override public void changeVariables(Object source, Map variables) { diff --git a/src/com/vaadin/ui/Tree.java b/src/com/vaadin/ui/Tree.java index cb3f667a4f..082b9f4624 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 { @@ -317,22 +319,11 @@ public class Tree extends AbstractSelect implements Container.Hierarchical, /* Component API */ - /** - * Gets the UIDL tag corresponding to the component. - * - * @see com.vaadin.ui.AbstractComponent#getTag() - */ - @Override - public String getTag() { - return "tree"; - } - - /** - * Called when one or more variables handled by the implementing class are - * changed. + /* + * (non-Javadoc) * - * @see com.vaadin.terminal.VariableOwner#changeVariables(Object source, Map - * variables) + * @see com.vaadin.ui.AbstractSelect#changeVariables(java.lang.Object, + * java.util.Map) */ @Override public void changeVariables(Object source, Map variables) { 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..4789641193 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; @@ -113,16 +115,6 @@ public class Upload extends AbstractComponent implements Component.Focusable { } /** - * Gets the component type. - * - * @return Component type as string. - */ - @Override - public String getTag() { - return "upload"; - } - - /** * This method is called by terminal when upload is received. * * Note, this method is called outside synchronized (Application) block, so @@ -200,12 +192,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..703e581733 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 { /** @@ -84,11 +86,6 @@ public class UriFragmentUtility extends AbstractComponent { } @Override - public String getTag() { - return "urifragment"; - } - - @Override public void paintContent(PaintTarget target) throws PaintException { super.paintContent(target); target.addVariable(this, "fragment", fragment); diff --git a/src/com/vaadin/ui/VerticalLayout.java b/src/com/vaadin/ui/VerticalLayout.java index 55f70a740f..d67f33e3e6 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,15 +15,11 @@ package com.vaadin.ui; * @since 5.3 */ @SuppressWarnings("serial") +@ClientWidget(VVerticalLayout.class) public class VerticalLayout extends AbstractOrderedLayout { public VerticalLayout() { setWidth("100%"); } - @Override - public String getTag() { - return "verticallayout"; - } - } diff --git a/src/com/vaadin/ui/Window.java b/src/com/vaadin/ui/Window.java index 663aabbd79..e80f588b87 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 { /** @@ -255,16 +257,6 @@ public class Window extends Panel implements URIHandler, ParameterHandler { super.setParent(parent); } - /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - @Override - public String getTag() { - return "window"; - } - /* ********************************************************************* */ /** @@ -535,10 +527,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 |