svn changeset:8930/svn branch:2009-09-widget-packaging_3332tags/6.7.0.beta1
@@ -793,6 +793,7 @@ | |||
<classpath> | |||
<pathelement location="${gwt-dir}/${platform}/gwt-user.jar" /> | |||
<pathelement location="${gwt-dir}/${platform}/${lib-gwt-dev}" /> | |||
<pathelement location="build/classes" /> | |||
<pathelement location="${result-path}/src" /> | |||
</classpath> | |||
</java> | |||
@@ -815,6 +816,7 @@ | |||
<pathelement location="${gwt-dir}/${platform}/gwt-user.jar" /> | |||
<pathelement location="${gwt-dir}/${platform}/${lib-gwt-dev}" /> | |||
<pathelement location="${result-path}/src" /> | |||
<pathelement location="build/classes" /> | |||
</classpath> | |||
</java> | |||
<antcall target="remove-widgetset-gwt-tmp"/> | |||
@@ -845,6 +847,7 @@ | |||
<pathelement location="${googlemaps-jar}" /> | |||
<!-- demo widgetset sources --> | |||
<pathelement path="${output-dir}/WebContent/WEB-INF/src" /> | |||
<pathelement location="build/classes" /> | |||
</classpath> | |||
</java> | |||
<antcall target="remove-widgetset-gwt-tmp"/> | |||
@@ -868,6 +871,7 @@ | |||
<pathelement location="${result-path}/src" /> | |||
<!-- demo widgetset sources --> | |||
<pathelement path="${output-dir}/WebContent/WEB-INF/src" /> | |||
<pathelement location="build/classes" /> | |||
</classpath> | |||
</java> | |||
<antcall target="remove-widgetset-gwt-tmp"/> | |||
@@ -890,6 +894,7 @@ | |||
<pathelement location="${result-path}/src" /> | |||
<!-- demo widgetset sources --> | |||
<pathelement path="${output-dir}/WebContent/WEB-INF/src" /> | |||
<pathelement location="build/classes" /> | |||
</classpath> | |||
</java> | |||
<antcall target="remove-widgetset-gwt-tmp"/> | |||
@@ -912,6 +917,7 @@ | |||
<pathelement location="${result-path}/src" /> | |||
<!-- demo widgetset sources --> | |||
<pathelement path="${output-dir}/WebContent/WEB-INF/src" /> | |||
<pathelement location="build/classes" /> | |||
</classpath> | |||
</java> | |||
<antcall target="remove-widgetset-gwt-tmp"/> |
@@ -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() { |
@@ -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> |
@@ -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); | |||
} | |||
} |
@@ -4,11 +4,14 @@ | |||
package com.vaadin.demo.coverflow; | |||
import com.vaadin.demo.coverflow.gwt.client.ui.VCoverflow; | |||
import com.vaadin.terminal.PaintException; | |||
import com.vaadin.terminal.PaintTarget; | |||
import com.vaadin.ui.AbstractSelect; | |||
import com.vaadin.ui.ClientWidget; | |||
@SuppressWarnings( { "serial", "unchecked" }) | |||
@ClientWidget(VCoverflow.class) | |||
public class Coverflow extends AbstractSelect { | |||
private String backgroundGradientStart = "FFFFFF"; |
@@ -1,8 +1,5 @@ | |||
<module> | |||
<!-- Inherit the NoEntry version to avoid multiple entrypoints --> | |||
<inherits name="com.vaadin.terminal.gwt.DefaultWidgetSetNoEntry" /> | |||
<!-- Entry point --> | |||
<entry-point class="com.vaadin.demo.coverflow.gwt.client.CoverflowWidgetSet"/> | |||
<inherits name="com.vaadin.terminal.gwt.DefaultWidget" /> | |||
</module> |
@@ -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); | |||
} | |||
} |
@@ -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"; |
@@ -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"; |
@@ -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> |
@@ -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); | |||
} | |||
} |
@@ -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"; |
@@ -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 { | |||
@@ -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; |
@@ -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> |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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> |
@@ -1,7 +0,0 @@ | |||
package com.vaadin.portal.gwt.client; | |||
import com.vaadin.demo.sampler.gwt.client.SamplerWidgetSet; | |||
public class PortalDefaultWidgetSet extends SamplerWidgetSet { | |||
} |
@@ -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); | |||
} |
@@ -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.rebind.WidgetMapGenerator"> | |||
<when-type-is class="com.vaadin.terminal.gwt.client.WidgetMap"/> | |||
</generate-with> | |||
<entry-point class="com.vaadin.terminal.gwt.client.DefaultWidgetSet" /> | |||
</module> |
@@ -1,6 +0,0 @@ | |||
<module> | |||
<!-- | |||
"NoEntry" -concept deprecated, inherit DefaultWidgetSet instead. | |||
--> | |||
<inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" /> | |||
</module> |
@@ -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); | |||
} | |||
} | |||
} |
@@ -20,7 +20,6 @@ import com.google.gwt.http.client.RequestBuilder; | |||
import com.google.gwt.http.client.RequestCallback; | |||
import com.google.gwt.http.client.RequestException; | |||
import com.google.gwt.http.client.Response; | |||
import com.google.gwt.json.client.JSONArray; | |||
import com.google.gwt.user.client.Command; | |||
import com.google.gwt.user.client.DOM; | |||
import com.google.gwt.user.client.DeferredCommand; | |||
@@ -607,7 +606,11 @@ public class ApplicationConnection { | |||
private static native ValueMap parseJSONResponse(String jsonText) | |||
/*-{ | |||
return eval('(' + jsonText + ')'); | |||
if(JSON && JSON.parse) { | |||
return JSON.parse(jsonText); | |||
} else { | |||
return eval('(' + jsonText + ')'); | |||
} | |||
}-*/; | |||
private void handleReceivedJSONMessage(Response response) { | |||
@@ -618,12 +621,17 @@ public class ApplicationConnection { | |||
ValueMap json; | |||
try { | |||
json = parseJSONResponse(jsonText); | |||
} catch (final com.google.gwt.json.client.JSONException e) { | |||
} catch (final Exception e) { | |||
endRequest(); | |||
showCommunicationError(e.getMessage() + " - Original JSON-text:"); | |||
console.log(jsonText); | |||
return; | |||
} | |||
ApplicationConnection.getConsole() | |||
.log( | |||
"JSON parsing took " | |||
+ (new Date().getTime() - start.getTime())); | |||
// Handle redirect | |||
if (json.containsKey("redirect")) { | |||
String url = json.getValueMap("redirect").getString("url"); | |||
@@ -642,6 +650,11 @@ public class ApplicationConnection { | |||
} | |||
} | |||
if (json.containsKey("typeMappings")) { | |||
configuration.addComponentMappings( | |||
json.getValueMap("typeMappings"), widgetSet); | |||
} | |||
if (json.containsKey("locales")) { | |||
// Store locale data | |||
JsArray<ValueMap> valueMapArray = json | |||
@@ -707,7 +720,7 @@ public class ApplicationConnection { | |||
updatedWidgets.add(idToPaintableDetail.get(uidl.getId()) | |||
.getComponent()); | |||
} else { | |||
if (!uidl.getTag().equals("window")) { | |||
if (!uidl.getTag().equals("0")) { | |||
ClientExceptionHandler | |||
.displayError("Received update for " | |||
+ uidl.getTag() | |||
@@ -790,10 +803,6 @@ public class ApplicationConnection { | |||
endRequest(); | |||
} | |||
private UIDL getUidl(JSONArray changes, int i) { | |||
return (UIDL) changes.get(i).isArray().getJavaScriptObject(); | |||
} | |||
/** | |||
* This method assures that all pending variable changes are sent to server. | |||
* Method uses synchronized xmlhttprequest and does not return before the | |||
@@ -1112,10 +1121,11 @@ public class ApplicationConnection { | |||
} | |||
// Switch to correct implementation if needed | |||
if (!widgetSet.isCorrectImplementation(component, uidl)) { | |||
if (!widgetSet.isCorrectImplementation(component, uidl, configuration)) { | |||
final Container parent = Util.getLayout(component); | |||
if (parent != null) { | |||
final Widget w = (Widget) widgetSet.createWidget(uidl); | |||
final Widget w = (Widget) widgetSet.createWidget(uidl, | |||
configuration); | |||
parent.replaceChildComponent(component, w); | |||
unregisterPaintable((Paintable) component); | |||
registerPaintable(uidl.getId(), (Paintable) w); | |||
@@ -1511,7 +1521,7 @@ public class ApplicationConnection { | |||
if (w != null) { | |||
return w; | |||
} else { | |||
w = widgetSet.createWidget(uidl); | |||
w = widgetSet.createWidget(uidl, configuration); | |||
registerPaintable(id, w); | |||
return w; | |||
@@ -1750,4 +1760,8 @@ public class ApplicationConnection { | |||
componentDetail.putAdditionalTooltip(key, tooltip); | |||
} | |||
public ApplicationConfiguration getConfiguration() { | |||
return configuration; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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()); |
@@ -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) { |
@@ -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); | |||
} |
@@ -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); | |||
} |
@@ -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); | |||
} | |||
@@ -0,0 +1,266 @@ | |||
package com.vaadin.terminal.gwt.rebind; | |||
import java.io.File; | |||
import java.io.FileFilter; | |||
import java.io.IOException; | |||
import java.net.JarURLConnection; | |||
import java.net.URL; | |||
import java.net.URLConnection; | |||
import java.util.Collection; | |||
import java.util.Enumeration; | |||
import java.util.HashMap; | |||
import java.util.HashSet; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import java.util.jar.JarEntry; | |||
import java.util.jar.JarFile; | |||
import com.vaadin.terminal.Paintable; | |||
import com.vaadin.ui.ClientWidget; | |||
/** | |||
* Utility class to find server side widgets with {@link ClientWidget} | |||
* annotation. Used by WidgetMapGenerator to implement some monkey coding for | |||
* you. | |||
* <p> | |||
* If you end up reading this comment, I guess you have faced a sluggish | |||
* performance of widget compilation or unreliable detection of components in | |||
* your classpaths. The thing you might be able to do is to use annotation | |||
* processing tool like apt to generate the needed information. Then either use | |||
* that information in {@link WidgetMapGenerator} or create the appropriate | |||
* monkey code for gwt directly in annotation processor and get rid of | |||
* {@link WidgetMapGenerator}. Using annotation processor might be a good idea | |||
* when dropping Java 1.5 support (integrated to javac in 6). | |||
* | |||
*/ | |||
public class ClassPathExplorer { | |||
private final static FileFilter DIRECTORIES_ONLY = new FileFilter() { | |||
public boolean accept(File f) { | |||
if (f.exists() && f.isDirectory()) { | |||
return true; | |||
} else { | |||
return false; | |||
} | |||
} | |||
}; | |||
private static Map<URL, String> classpathLocations = getClasspathLocations(); | |||
private ClassPathExplorer() { | |||
} | |||
public static Collection<Class<? extends Paintable>> getPaintablesHavingWidgetAnnotation() { | |||
Collection<Class<? extends Paintable>> paintables = new HashSet<Class<? extends Paintable>>(); | |||
Set<URL> keySet = classpathLocations.keySet(); | |||
for (URL url : keySet) { | |||
searchForPaintables(url, classpathLocations.get(url), paintables); | |||
} | |||
return paintables; | |||
} | |||
/** | |||
* Determine every URL location defined by the current classpath, and it's | |||
* associated package name. | |||
*/ | |||
public final static Map<URL, String> getClasspathLocations() { | |||
Map<URL, String> locations = new HashMap<URL, String>(); | |||
String pathSep = System.getProperty("path.separator"); | |||
String classpath = System.getProperty("java.class.path"); | |||
String[] split = classpath.split(pathSep); | |||
for (int i = 0; i < split.length; i++) { | |||
String classpathEntry = split[i]; | |||
if (acceptClassPathEntry(classpathEntry)) { | |||
File file = new File(classpathEntry); | |||
include(null, file, locations); | |||
} | |||
} | |||
return locations; | |||
} | |||
private static boolean acceptClassPathEntry(String classpathEntry) { | |||
if (!classpathEntry.endsWith(".jar")) { | |||
// accept all non jars (practically directories) | |||
return true; | |||
} else { | |||
// accepts jars that comply with vaadin-component packaging | |||
// convention (.vaadin. or vaadin- as distribution packages), | |||
if (classpathEntry.contains("vaadin-") | |||
|| classpathEntry.contains(".vaadin.")) { | |||
return true; | |||
} else { | |||
return false; | |||
} | |||
} | |||
} | |||
/** | |||
* Recursively add subdirectories and jar files to classpathlocations | |||
* | |||
* @param name | |||
* @param file | |||
* @param locations | |||
*/ | |||
private final static void include(String name, File file, | |||
Map<URL, String> locations) { | |||
if (!file.exists()) { | |||
return; | |||
} | |||
if (!file.isDirectory()) { | |||
// could be a JAR file | |||
includeJar(file, locations); | |||
return; | |||
} | |||
if (file.isHidden() || file.getPath().contains(File.separator + ".")) { | |||
return; | |||
} | |||
if (name == null) { | |||
name = ""; | |||
} else { | |||
name += "."; | |||
} | |||
// add all directories recursively | |||
File[] dirs = file.listFiles(DIRECTORIES_ONLY); | |||
for (int i = 0; i < dirs.length; i++) { | |||
try { | |||
// add the present directory | |||
locations.put(new URL("file://" + dirs[i].getCanonicalPath()), | |||
name + dirs[i].getName()); | |||
} catch (Exception ioe) { | |||
return; | |||
} | |||
include(name + dirs[i].getName(), dirs[i], locations); | |||
} | |||
} | |||
private static void includeJar(File file, Map<URL, String> locations) { | |||
try { | |||
URL url = new URL("file:" + file.getCanonicalPath()); | |||
url = new URL("jar:" + url.toExternalForm() + "!/"); | |||
JarURLConnection conn = (JarURLConnection) url.openConnection(); | |||
JarFile jarFile = conn.getJarFile(); | |||
if (jarFile != null) { | |||
locations.put(url, ""); | |||
} | |||
} catch (Exception e) { | |||
// e.printStackTrace(); | |||
return; | |||
} | |||
} | |||
private static String packageNameFor(JarEntry entry) { | |||
if (entry == null) { | |||
return ""; | |||
} | |||
String s = entry.getName(); | |||
if (s == null) { | |||
return ""; | |||
} | |||
if (s.length() == 0) { | |||
return s; | |||
} | |||
if (s.startsWith("/")) { | |||
s = s.substring(1, s.length()); | |||
} | |||
if (s.endsWith("/")) { | |||
s = s.substring(0, s.length() - 1); | |||
} | |||
return s.replace('/', '.'); | |||
} | |||
private final static void searchForPaintables(URL location, | |||
String packageName, | |||
Collection<Class<? extends Paintable>> paintables) { | |||
// Get a File object for the package | |||
File directory = new File(location.getFile()); | |||
if (directory.exists() && !directory.isHidden()) { | |||
// Get the list of the files contained in the directory | |||
String[] files = directory.list(); | |||
for (int i = 0; i < files.length; i++) { | |||
// we are only interested in .class files | |||
if (files[i].endsWith(".class")) { | |||
// remove the .class extension | |||
String classname = files[i].substring(0, | |||
files[i].length() - 6); | |||
classname = packageName + "." + classname; | |||
tryToAdd(classname, paintables); | |||
} | |||
} | |||
} else { | |||
try { | |||
// check files in jar file, entries will list all directories | |||
// and files in jar | |||
URLConnection openConnection = location.openConnection(); | |||
if (openConnection instanceof JarURLConnection) { | |||
JarURLConnection conn = (JarURLConnection) openConnection; | |||
JarFile jarFile = conn.getJarFile(); | |||
Enumeration<JarEntry> e = jarFile.entries(); | |||
while (e.hasMoreElements()) { | |||
JarEntry entry = e.nextElement(); | |||
String entryname = entry.getName(); | |||
if (!entry.isDirectory() | |||
&& entryname.endsWith(".class") | |||
&& !entryname.contains("$")) { | |||
String classname = entryname.substring(0, entryname | |||
.length() - 6); | |||
if (classname.startsWith("/")) { | |||
classname = classname.substring(1); | |||
} | |||
classname = classname.replace('/', '.'); | |||
tryToAdd(classname, paintables); | |||
} | |||
} | |||
} | |||
} catch (IOException e) { | |||
System.err.println(e); | |||
} | |||
} | |||
} | |||
private static void tryToAdd(final String fullclassName, | |||
Collection<Class<? extends Paintable>> paintables) { | |||
try { | |||
Class<?> c = Class.forName(fullclassName); | |||
if (c.getAnnotation(ClientWidget.class) != null) { | |||
paintables.add((Class<? extends Paintable>) c); | |||
System.out.println("Found paintable " + fullclassName); | |||
} | |||
} catch (ExceptionInInitializerError e) { | |||
// e.printStackTrace(); | |||
} catch (ClassNotFoundException e) { | |||
// e.printStackTrace(); | |||
} catch (NoClassDefFoundError e) { | |||
// NOP | |||
} catch (UnsatisfiedLinkError e) { | |||
// NOP | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
/** | |||
* Test method for helper tool | |||
*/ | |||
public static void main(String[] args) { | |||
Collection<Class<? extends Paintable>> paintables = ClassPathExplorer | |||
.getPaintablesHavingWidgetAnnotation(); | |||
System.out.println("Found annotated paintables:"); | |||
for (Class<? extends Paintable> cls : paintables) { | |||
System.out.println(cls.getCanonicalName()); | |||
} | |||
} | |||
} |
@@ -0,0 +1,192 @@ | |||
package com.vaadin.terminal.gwt.rebind; | |||
import java.io.PrintWriter; | |||
import java.util.Collection; | |||
import java.util.Date; | |||
import java.util.Iterator; | |||
import com.google.gwt.core.ext.Generator; | |||
import com.google.gwt.core.ext.GeneratorContext; | |||
import com.google.gwt.core.ext.TreeLogger; | |||
import com.google.gwt.core.ext.UnableToCompleteException; | |||
import com.google.gwt.core.ext.TreeLogger.Type; | |||
import com.google.gwt.core.ext.typeinfo.JClassType; | |||
import com.google.gwt.core.ext.typeinfo.TypeOracle; | |||
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; | |||
import com.google.gwt.user.rebind.SourceWriter; | |||
import com.vaadin.terminal.Paintable; | |||
import com.vaadin.terminal.gwt.client.ui.VView; | |||
import com.vaadin.ui.ClientWidget; | |||
/** | |||
* GWT generator to build WidgetMapImpl dynamically based on | |||
* {@link ClientWidget} annotations available in workspace. | |||
* | |||
*/ | |||
public class WidgetMapGenerator extends Generator { | |||
private String packageName; | |||
private String className; | |||
@Override | |||
public String generate(TreeLogger logger, GeneratorContext context, | |||
String typeName) throws UnableToCompleteException { | |||
try { | |||
TypeOracle typeOracle = context.getTypeOracle(); | |||
// get classType and save instance variables | |||
JClassType classType = typeOracle.getType(typeName); | |||
packageName = classType.getPackage().getName(); | |||
className = classType.getSimpleSourceName() + "Impl"; | |||
// Generate class source code | |||
generateClass(logger, context); | |||
} catch (Exception e) { | |||
logger.log(TreeLogger.ERROR, "WidgetMap creation failed", e); | |||
} | |||
// return the fully qualifed name of the class generated | |||
return packageName + "." + className; | |||
} | |||
/** | |||
* Generate source code for WidgetMapImpl | |||
* | |||
* @param logger | |||
* Logger object | |||
* @param context | |||
* Generator context | |||
*/ | |||
private void generateClass(TreeLogger logger, GeneratorContext context) { | |||
// get print writer that receives the source code | |||
PrintWriter printWriter = null; | |||
printWriter = context.tryCreate(logger, packageName, className); | |||
// print writer if null, source code has ALREADY been generated, return | |||
if (printWriter == null) { | |||
return; | |||
} | |||
logger | |||
.log(Type.INFO, | |||
"Detecting vaading components in classpath to generate WidgetMapImpl.java ..."); | |||
Date date = new Date(); | |||
// init composer, set class properties, create source writer | |||
ClassSourceFileComposerFactory composer = null; | |||
composer = new ClassSourceFileComposerFactory(packageName, className); | |||
composer.setSuperclass("com.vaadin.terminal.gwt.client.WidgetMap"); | |||
SourceWriter sourceWriter = composer.createSourceWriter(context, | |||
printWriter); | |||
/* | |||
* TODO we need som sort of mechanims to exclude/include components from | |||
* widgetset. Properties in gwt.xml is one option. Now only possible by | |||
* extending this class, overriding getUsedPaintables() method and | |||
* redefining deferred binding rule. | |||
*/ | |||
Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation = getUsedPaintables(); | |||
TypeOracle typeOracle = context.getTypeOracle(); | |||
for (Iterator iterator = paintablesHavingWidgetAnnotation.iterator(); iterator | |||
.hasNext();) { | |||
Class<? extends Paintable> class1 = (Class<? extends Paintable>) iterator | |||
.next(); | |||
ClientWidget annotation = class1.getAnnotation(ClientWidget.class); | |||
if (typeOracle.findType(annotation.value().getName()) == null) { | |||
// GWT widget not inherited | |||
logger | |||
.log( | |||
Type.WARN, | |||
"Widget implementation for " | |||
+ class1.getName() | |||
+ " not available for GWT compiler. If this is not " | |||
+ "intentional, check your gwt module definition file."); | |||
iterator.remove(); | |||
} | |||
} | |||
// generator constructor source code | |||
generateImplementationDetector(sourceWriter, | |||
paintablesHavingWidgetAnnotation); | |||
generateInstantiatorMethod(sourceWriter, | |||
paintablesHavingWidgetAnnotation); | |||
// close generated class | |||
sourceWriter.outdent(); | |||
sourceWriter.println("}"); | |||
// commit generated class | |||
context.commit(logger, printWriter); | |||
logger.log(Type.INFO, "Done. (" | |||
+ (new Date().getTime() - date.getTime()) / 1000 + "seconds)"); | |||
} | |||
protected Collection<Class<? extends Paintable>> getUsedPaintables() { | |||
return ClassPathExplorer.getPaintablesHavingWidgetAnnotation(); | |||
} | |||
private void generateInstantiatorMethod( | |||
SourceWriter sourceWriter, | |||
Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation) { | |||
sourceWriter | |||
.println("public Paintable instantiate(Class<? extends Paintable> classType) {"); | |||
sourceWriter.indent(); | |||
sourceWriter | |||
.println("Paintable p = super.instantiate(classType); if(p!= null) return p;"); | |||
for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) { | |||
ClientWidget annotation = class1.getAnnotation(ClientWidget.class); | |||
Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = annotation | |||
.value(); | |||
if (clientClass == VView.class) { | |||
// VView's are not instantiated by widgetset | |||
continue; | |||
} | |||
sourceWriter.print("if ("); | |||
sourceWriter.print(clientClass.getName()); | |||
sourceWriter.print(".class == classType) return new "); | |||
sourceWriter.print(clientClass.getName()); | |||
sourceWriter.println("();"); | |||
sourceWriter.print(" else "); | |||
} | |||
sourceWriter | |||
.println("return new com.vaadin.terminal.gwt.client.ui.VUnknownComponent();"); | |||
sourceWriter.println("}"); | |||
} | |||
/** | |||
* | |||
* @param sourceWriter | |||
* Source writer to output source code | |||
* @param paintablesHavingWidgetAnnotation | |||
*/ | |||
private void generateImplementationDetector( | |||
SourceWriter sourceWriter, | |||
Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation) { | |||
sourceWriter | |||
.println("public Class<? extends Paintable> getImplementationByServerSideClassName(String fullyQualifiedName) {"); | |||
sourceWriter.indent(); | |||
sourceWriter | |||
.println("fullyQualifiedName = fullyQualifiedName.intern();"); | |||
for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) { | |||
ClientWidget annotation = class1.getAnnotation(ClientWidget.class); | |||
Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = annotation | |||
.value(); | |||
sourceWriter.print("if ( fullyQualifiedName == \""); | |||
sourceWriter.print(class1.getName()); | |||
sourceWriter.print("\") return "); | |||
sourceWriter.print(clientClass.getName()); | |||
sourceWriter.println(".class;"); | |||
sourceWriter.print(" else "); | |||
} | |||
sourceWriter | |||
.println("return com.vaadin.terminal.gwt.client.ui.VUnknownComponent.class;"); | |||
sourceWriter.println("}"); | |||
} | |||
} |
@@ -92,7 +92,7 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, | |||
public static final String VAR_ARRAYITEM_SEPARATOR = "\u001c"; | |||
private final HashSet<String> currentlyOpenWindowsInClient = new HashSet<String>(); | |||
private final HashMap<String, OpenWindowCache> currentlyOpenWindowsInClient = new HashMap<String, OpenWindowCache>(); | |||
private static final int MAX_BUFFER_SIZE = 64 * 1024; | |||
@@ -302,8 +302,6 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, | |||
paintAfterVariablechanges(request, response, applicationServlet, | |||
repaintAll, outWriter, window, analyzeLayouts); | |||
// Mark this window to be open on client | |||
currentlyOpenWindowsInClient.add(window.getName()); | |||
if (closingWindowName != null) { | |||
currentlyOpenWindowsInClient.remove(closingWindowName); | |||
closingWindowName = null; | |||
@@ -322,7 +320,7 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, | |||
// If repaint is requested, clean all ids in this root window | |||
if (repaintAll) { | |||
for (final Iterator it = idPaintableMap.keySet().iterator(); it | |||
for (final Iterator<String> it = idPaintableMap.keySet().iterator(); it | |||
.hasNext();) { | |||
final Component c = (Component) idPaintableMap.get(it.next()); | |||
if (isChildOf(window, c)) { | |||
@@ -363,6 +361,12 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, | |||
JsonPaintTarget paintTarget = new JsonPaintTarget(this, outWriter, | |||
!repaintAll); | |||
OpenWindowCache windowCache = currentlyOpenWindowsInClient | |||
.get(window.getName()); | |||
if (windowCache == null) { | |||
windowCache = new OpenWindowCache(); | |||
currentlyOpenWindowsInClient.put(window.getName(), windowCache); | |||
} | |||
// Paints components | |||
if (repaintAll) { | |||
@@ -376,8 +380,8 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, | |||
} else { | |||
// remove detached components from paintableIdMap so they | |||
// can be GC'ed | |||
for (Iterator it = paintableIdMap.keySet().iterator(); it | |||
.hasNext();) { | |||
for (Iterator<Paintable> it = paintableIdMap.keySet() | |||
.iterator(); it.hasNext();) { | |||
Component p = (Component) it.next(); | |||
if (p.getApplication() == null) { | |||
idPaintableMap.remove(paintableIdMap.get(p)); | |||
@@ -548,10 +552,10 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, | |||
} | |||
// TODO We should only precache the layouts that are not | |||
// cached already | |||
// cached already (plagiate from usedPaintableTypes) | |||
int resourceIndex = 0; | |||
for (final Iterator i = paintTarget.getPreCachedResources() | |||
.iterator(); i.hasNext();) { | |||
for (final Iterator i = paintTarget.getUsedResources().iterator(); i | |||
.hasNext();) { | |||
final String resource = (String) i.next(); | |||
InputStream is = null; | |||
try { | |||
@@ -598,6 +602,30 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, | |||
} | |||
outWriter.print("}"); | |||
Collection<Class<? extends Paintable>> usedPaintableTypes = paintTarget | |||
.getUsedPaintableTypes(); | |||
boolean typeMappingsOpen = false; | |||
for (Class<? extends Paintable> class1 : usedPaintableTypes) { | |||
if (windowCache.cache(class1)) { | |||
// client does not know the mapping key for this type, send | |||
// mapping to client | |||
if (!typeMappingsOpen) { | |||
typeMappingsOpen = true; | |||
outWriter.print(", \"typeMappings\" : { "); | |||
} else { | |||
outWriter.print(" , "); | |||
} | |||
String canonicalName = class1.getCanonicalName(); | |||
outWriter.print("\""); | |||
outWriter.print(canonicalName); | |||
outWriter.print("\" : "); | |||
outWriter.print(getTagForType(class1)); | |||
} | |||
} | |||
if (typeMappingsOpen) { | |||
outWriter.print(" }"); | |||
} | |||
printLocaleDeclarations(outWriter); | |||
outWriter.print("}]"); | |||
@@ -774,6 +802,7 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, | |||
paintAfterVariablechanges(request, response, | |||
applicationServlet, true, outWriter, window, | |||
false); | |||
} catch (ServletException e) { | |||
// We will ignore all servlet exceptions | |||
} | |||
@@ -1093,9 +1122,9 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, | |||
} | |||
// If the requested window is already open, resolve conflict | |||
if (currentlyOpenWindowsInClient.contains(window.getName())) { | |||
if (currentlyOpenWindowsInClient.containsKey(window.getName())) { | |||
String newWindowName = window.getName(); | |||
while (currentlyOpenWindowsInClient.contains(newWindowName)) { | |||
while (currentlyOpenWindowsInClient.containsKey(newWindowName)) { | |||
newWindowName = window.getName() + "_" | |||
+ ((int) (Math.random() * 100000000)); | |||
} | |||
@@ -1210,8 +1239,9 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, | |||
// list. The result is that each component should be painted exactly | |||
// once and any unmodified components will be painted as "cached=true". | |||
for (final Iterator i = dirtyPaintabletSet.iterator(); i.hasNext();) { | |||
final Paintable p = (Paintable) i.next(); | |||
for (final Iterator<Paintable> i = dirtyPaintabletSet.iterator(); i | |||
.hasNext();) { | |||
final Paintable p = i.next(); | |||
if (p instanceof Component) { | |||
final Component component = (Component) p; | |||
if (component.getApplication() == null) { | |||
@@ -1528,4 +1558,37 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, | |||
return null; | |||
} | |||
} | |||
private static HashMap<Class<? extends Paintable>, Integer> typeToKey = new HashMap<Class<? extends Paintable>, Integer>(); | |||
private static int nextTypeKey = 0; | |||
static String getTagForType(Class<? extends Paintable> class1) { | |||
synchronized (typeToKey) { | |||
Integer object = typeToKey.get(class1); | |||
if (object == null) { | |||
object = nextTypeKey++; | |||
typeToKey.put(class1, object); | |||
} | |||
return object.toString(); | |||
} | |||
} | |||
/** | |||
* Helper class for terminal to keep track of data that client is expected | |||
* to know. | |||
*/ | |||
class OpenWindowCache { | |||
private Set<Object> res = new HashSet<Object>(); | |||
/** | |||
* | |||
* @param paintable | |||
* @return true if the given class was added to cache | |||
*/ | |||
boolean cache(Object object) { | |||
return res.add(object); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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>(); |
@@ -146,8 +146,16 @@ public abstract class AbstractComponent implements Component, MethodEventSource | |||
* Gets the UIDL tag corresponding to the component. | |||
* | |||
* @return the component's UIDL tag as <code>String</code> | |||
* @deprecated tags are no more required for components. Instead of tags we | |||
* are now using {@link ClientWidget} annotations to map server | |||
* side components to client side counterparts. Generating | |||
* identifier for component type is delegated to terminal. | |||
* @see ClientWidget | |||
*/ | |||
public abstract String getTag(); | |||
@Deprecated | |||
public String getTag() { | |||
return ""; | |||
} | |||
public void setDebugId(String id) { | |||
testingId = id; | |||
@@ -604,7 +612,8 @@ public abstract class AbstractComponent implements Component, MethodEventSource | |||
* here, we use the default documentation from implemented interface. | |||
*/ | |||
public final void paint(PaintTarget target) throws PaintException { | |||
if (!target.startTag(this, getTag()) || repaintRequestListenersNotified) { | |||
final String tag = target.getTag(this); | |||
if (!target.startTag(this, tag) || repaintRequestListenersNotified) { | |||
// Paint the contents of the component | |||
@@ -659,7 +668,7 @@ public abstract class AbstractComponent implements Component, MethodEventSource | |||
// Contents have not changed, only cached presentation can be used | |||
target.addAttribute("cached", true); | |||
} | |||
target.endTag(getTag()); | |||
target.endTag(tag); | |||
repaintRequestListenersNotified = false; | |||
} |
@@ -1,6 +1,9 @@ | |||
package com.vaadin.ui; | |||
import com.vaadin.terminal.gwt.client.ui.VAccordion; | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VAccordion.class) | |||
public class Accordion extends TabSheet { | |||
@Override |
@@ -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 */ |
@@ -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 |
@@ -0,0 +1,21 @@ | |||
/** | |||
* | |||
*/ | |||
package com.vaadin.ui; | |||
import java.lang.annotation.ElementType; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
import com.vaadin.terminal.gwt.client.Paintable; | |||
/** | |||
* Annotation defining the default client side counterpart in GWT terminal for | |||
* {@link Component} | |||
*/ | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Target(ElementType.TYPE) | |||
public @interface ClientWidget { | |||
Class<? extends Paintable> value(); | |||
} |
@@ -50,6 +50,7 @@ import com.vaadin.terminal.gwt.client.ui.VCssLayout; | |||
* @since 6.1 brought in from "FastLayouts" incubator project | |||
* | |||
*/ | |||
@ClientWidget(VCssLayout.class) | |||
public class CssLayout extends AbstractLayout { | |||
private static final long serialVersionUID = -6408703812053460073L; |
@@ -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 { | |||
/** |
@@ -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; |
@@ -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 */ |
@@ -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 { | |||
/** |
@@ -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 { | |||
@@ -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() { |
@@ -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 { | |||
@@ -1,5 +1,7 @@ | |||
package com.vaadin.ui; | |||
import com.vaadin.terminal.gwt.client.ui.VHorizontalLayout; | |||
/** | |||
* Horizontal layout | |||
* | |||
@@ -12,6 +14,7 @@ package com.vaadin.ui; | |||
* @since 5.3 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VHorizontalLayout.class) | |||
public class HorizontalLayout extends AbstractOrderedLayout { | |||
public HorizontalLayout() { |
@@ -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 { |
@@ -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 */ |
@@ -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; |
@@ -10,6 +10,7 @@ import java.util.Stack; | |||
import com.vaadin.terminal.PaintException; | |||
import com.vaadin.terminal.PaintTarget; | |||
import com.vaadin.terminal.Resource; | |||
import com.vaadin.terminal.gwt.client.ui.VMenuBar; | |||
/** | |||
* <p> | |||
@@ -19,6 +20,7 @@ import com.vaadin.terminal.Resource; | |||
* </p> | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VMenuBar.class) | |||
public class MenuBar extends AbstractComponent { | |||
// Items of the top-level menu | |||
@@ -340,10 +342,9 @@ public class MenuBar extends AbstractComponent { | |||
/** | |||
* This interface contains the layer for menu commands of the | |||
* {@link com.vaadin.ui.MenuBar} class. It's method will fire when | |||
* the user clicks on the containing | |||
* {@link com.vaadin.ui.MenuBar.MenuItem}. The selected item is | |||
* given as an argument. | |||
* {@link com.vaadin.ui.MenuBar} class. It's method will fire when the user | |||
* clicks on the containing {@link com.vaadin.ui.MenuBar.MenuItem}. The | |||
* selected item is given as an argument. | |||
*/ | |||
public interface Command extends Serializable { | |||
public void menuSelected(MenuBar.MenuItem selectedItem); | |||
@@ -498,8 +499,8 @@ public class MenuBar extends AbstractComponent { | |||
* For the containing item. This will return null if the item is in the | |||
* top-level menu bar. | |||
* | |||
* @return The containing {@link com.vaadin.ui.MenuBar.MenuItem} | |||
* , or null if there is none | |||
* @return The containing {@link com.vaadin.ui.MenuBar.MenuItem} , or | |||
* null if there is none | |||
*/ | |||
public MenuBar.MenuItem getParent() { | |||
return itsParent; |
@@ -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 |
@@ -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() { |
@@ -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 */ | |||
@@ -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 { |
@@ -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; |
@@ -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 { | |||
@@ -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 |
@@ -16,6 +16,7 @@ import com.vaadin.data.Container; | |||
import com.vaadin.terminal.PaintException; | |||
import com.vaadin.terminal.PaintTarget; | |||
import com.vaadin.terminal.Resource; | |||
import com.vaadin.terminal.gwt.client.ui.VFilterSelect; | |||
/** | |||
* <p> | |||
@@ -36,6 +37,7 @@ import com.vaadin.terminal.Resource; | |||
* @since 3.0 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VFilterSelect.class) | |||
public class Select extends AbstractSelect implements AbstractSelect.Filtering { | |||
/** |
@@ -10,6 +10,7 @@ import java.util.Map; | |||
import com.vaadin.terminal.PaintException; | |||
import com.vaadin.terminal.PaintTarget; | |||
import com.vaadin.terminal.Sizeable; | |||
import com.vaadin.terminal.gwt.client.ui.VSplitPanelHorizontal; | |||
/** | |||
* SplitPanel. | |||
@@ -23,6 +24,7 @@ import com.vaadin.terminal.Sizeable; | |||
* @since 5.0 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VSplitPanelHorizontal.class) | |||
public class SplitPanel extends AbstractLayout { | |||
/* Predefined orientations */ | |||
@@ -80,11 +82,7 @@ public class SplitPanel extends AbstractLayout { | |||
*/ | |||
@Override | |||
public String getTag() { | |||
if (orientation == ORIENTATION_HORIZONTAL) { | |||
return "hsplitpanel"; | |||
} else { | |||
return "vsplitpanel"; | |||
} | |||
return "splitpanel"; | |||
} | |||
/** | |||
@@ -218,6 +216,10 @@ public class SplitPanel extends AbstractLayout { | |||
final String position = pos + UNIT_SYMBOLS[posUnit]; | |||
if (orientation == ORIENTATION_VERTICAL) { | |||
target.addAttribute("vertical", true); | |||
} | |||
target.addAttribute("position", position); | |||
if (isLocked()) { |
@@ -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 { | |||
@@ -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 */ |
@@ -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 { | |||
@@ -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; |
@@ -1,5 +1,5 @@ | |||
/* | |||
@ITMillApache2LicenseForJavaFiles@ | |||
/* | |||
* @ITMillApache2LicenseForJavaFiles@ | |||
*/ | |||
package com.vaadin.ui; | |||
@@ -17,6 +17,7 @@ import com.vaadin.Application; | |||
import com.vaadin.terminal.PaintException; | |||
import com.vaadin.terminal.PaintTarget; | |||
import com.vaadin.terminal.UploadStream; | |||
import com.vaadin.terminal.gwt.client.ui.VUpload; | |||
/** | |||
* Component for uploading files from client to server. | |||
@@ -54,6 +55,7 @@ import com.vaadin.terminal.UploadStream; | |||
* @since 3.0 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VUpload.class) | |||
public class Upload extends AbstractComponent implements Component.Focusable { | |||
private boolean delayedFocus; | |||
@@ -200,12 +202,13 @@ public class Upload extends AbstractComponent implements Component.Focusable { | |||
try { | |||
// still try to close output stream | |||
out.close(); | |||
} catch (IOException e1) { | |||
// NOP | |||
} catch (IOException ignored) { | |||
} | |||
fireUploadInterrupted(filename, type, totalBytes, e); | |||
endUpload(); | |||
interrupted = false; | |||
// throw cause ahead | |||
throw new IllegalStateException("Uploading failed", e); | |||
} | |||
} | |||
} |
@@ -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 { | |||
/** |
@@ -1,5 +1,7 @@ | |||
package com.vaadin.ui; | |||
import com.vaadin.terminal.gwt.client.ui.VVerticalLayout; | |||
/** | |||
* Vertical layout | |||
* | |||
@@ -13,6 +15,7 @@ package com.vaadin.ui; | |||
* @since 5.3 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VVerticalLayout.class) | |||
public class VerticalLayout extends AbstractOrderedLayout { | |||
public VerticalLayout() { |
@@ -24,6 +24,7 @@ import com.vaadin.terminal.Resource; | |||
import com.vaadin.terminal.Sizeable; | |||
import com.vaadin.terminal.Terminal; | |||
import com.vaadin.terminal.URIHandler; | |||
import com.vaadin.terminal.gwt.client.ui.VView; | |||
/** | |||
* Application window component. | |||
@@ -34,6 +35,7 @@ import com.vaadin.terminal.URIHandler; | |||
* @since 3.0 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VView.class) | |||
public class Window extends Panel implements URIHandler, ParameterHandler { | |||
/** | |||
@@ -535,10 +537,15 @@ public class Window extends Panel implements URIHandler, ParameterHandler { | |||
// Window closing | |||
target.addVariable(this, "close", false); | |||
// Paint subwindows | |||
for (final Iterator<Window> i = subwindows.iterator(); i.hasNext();) { | |||
final Window w = i.next(); | |||
w.paint(target); | |||
if (getParent() == null) { | |||
// Paint subwindows | |||
for (final Iterator<Window> i = subwindows.iterator(); i.hasNext();) { | |||
final Window w = i.next(); | |||
w.paint(target); | |||
} | |||
} else { | |||
// mark subwindows | |||
target.addAttribute("sub", true); | |||
} | |||
// Paint notifications |