svn changeset:13561/svn branch:6.4tags/6.7.0.beta1
@@ -6,11 +6,12 @@ package com.vaadin.terminal.gwt.client; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.LinkedList; | |||
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.google.gwt.user.client.Command; | |||
import com.vaadin.terminal.gwt.client.ui.VUnknownComponent; | |||
public class ApplicationConfiguration { | |||
@@ -37,6 +38,11 @@ public class ApplicationConfiguration { | |||
private String windowId; | |||
// TODO consider to make this hashmap per application | |||
LinkedList<Command> callbacks = new LinkedList<Command>(); | |||
private int widgetsLoading; | |||
private static ArrayList<ApplicationConnection> unstartedApplications = new ArrayList<ApplicationConnection>(); | |||
private static ArrayList<ApplicationConnection> runningApplications = new ArrayList<ApplicationConnection>(); | |||
@@ -146,11 +152,6 @@ public class ApplicationConfiguration { | |||
* the widgetset that is running the apps | |||
*/ | |||
public static void initConfigurations(WidgetSet widgetset) { | |||
String wsname = widgetset.getClass().getName(); | |||
String module = GWT.getModuleName(); | |||
int lastdot = module.lastIndexOf("."); | |||
String base = module.substring(0, lastdot); | |||
String simpleName = module.substring(lastdot + 1); | |||
if (initedWidgetSet != null) { | |||
// Multiple widgetsets inited; can happen with custom WS + entry | |||
@@ -241,7 +242,7 @@ public class ApplicationConfiguration { | |||
for (int i = 0; i < keyArray.length(); i++) { | |||
String key = keyArray.get(i).intern(); | |||
int value = valueMap.getInt(key); | |||
classes[value] = widgetSet.getImplementationByClassName(key); | |||
classes[value] = widgetSet.getImplementationByClassName(key, this); | |||
if (classes[value] == VUnknownComponent.class) { | |||
if (unknownComponents == null) { | |||
unknownComponents = new HashMap<String, String>(); | |||
@@ -267,4 +268,31 @@ public class ApplicationConfiguration { | |||
} | |||
return null; | |||
} | |||
/** | |||
* | |||
* @param c | |||
*/ | |||
void runWhenWidgetsLoaded(Command c) { | |||
if (widgetsLoading == 0) { | |||
c.execute(); | |||
} else { | |||
callbacks.add(c); | |||
} | |||
} | |||
void widgetLoadStart() { | |||
widgetsLoading++; | |||
} | |||
void widgetLoaded() { | |||
widgetsLoading--; | |||
if (widgetsLoading == 0 && !callbacks.isEmpty()) { | |||
for (Command cmd : callbacks) { | |||
cmd.execute(); | |||
} | |||
callbacks.clear(); | |||
} | |||
} | |||
} |
@@ -670,10 +670,10 @@ public class ApplicationConnection { | |||
private void handleReceivedJSONMessage(Response response) { | |||
final Date start = new Date(); | |||
String jsonText = response.getText(); | |||
// for(;;);[realjson] | |||
jsonText = jsonText.substring(9, jsonText.length() - 1); | |||
ValueMap json; | |||
final String jsonText = response.getText().substring(9, | |||
response.getText().length() - 1); | |||
final ValueMap json; | |||
try { | |||
json = parseJSONResponse(jsonText); | |||
} catch (final Exception e) { | |||
@@ -714,159 +714,181 @@ public class ApplicationConnection { | |||
json.getValueMap("typeMappings"), widgetSet); | |||
} | |||
if (json.containsKey("locales")) { | |||
// Store locale data | |||
JsArray<ValueMap> valueMapArray = json | |||
.getJSValueMapArray("locales"); | |||
LocaleService.addLocales(valueMapArray); | |||
} | |||
Command c = new Command() { | |||
public void execute() { | |||
ValueMap meta = null; | |||
if (json.containsKey("meta")) { | |||
meta = json.getValueMap("meta"); | |||
if (meta.containsKey("repaintAll")) { | |||
view.clear(); | |||
idToPaintableDetail.clear(); | |||
if (meta.containsKey("invalidLayouts")) { | |||
validatingLayouts = true; | |||
zeroWidthComponents = new HashSet<Paintable>(); | |||
zeroHeightComponents = new HashSet<Paintable>(); | |||
if (json.containsKey("locales")) { | |||
// Store locale data | |||
JsArray<ValueMap> valueMapArray = json | |||
.getJSValueMapArray("locales"); | |||
LocaleService.addLocales(valueMapArray); | |||
} | |||
} | |||
if (meta.containsKey("timedRedirect")) { | |||
final ValueMap timedRedirect = meta | |||
.getValueMap("timedRedirect"); | |||
redirectTimer = new Timer() { | |||
@Override | |||
public void run() { | |||
redirect(timedRedirect.getString("url")); | |||
ValueMap meta = null; | |||
if (json.containsKey("meta")) { | |||
meta = json.getValueMap("meta"); | |||
if (meta.containsKey("repaintAll")) { | |||
view.clear(); | |||
idToPaintableDetail.clear(); | |||
if (meta.containsKey("invalidLayouts")) { | |||
validatingLayouts = true; | |||
zeroWidthComponents = new HashSet<Paintable>(); | |||
zeroHeightComponents = new HashSet<Paintable>(); | |||
} | |||
} | |||
}; | |||
sessionExpirationInterval = timedRedirect.getInt("interval"); | |||
} | |||
} | |||
if (meta.containsKey("timedRedirect")) { | |||
final ValueMap timedRedirect = meta | |||
.getValueMap("timedRedirect"); | |||
redirectTimer = new Timer() { | |||
@Override | |||
public void run() { | |||
redirect(timedRedirect.getString("url")); | |||
} | |||
}; | |||
sessionExpirationInterval = timedRedirect | |||
.getInt("interval"); | |||
} | |||
} | |||
if (redirectTimer != null) { | |||
redirectTimer.schedule(1000 * sessionExpirationInterval); | |||
} | |||
if (redirectTimer != null) { | |||
redirectTimer.schedule(1000 * sessionExpirationInterval); | |||
} | |||
// Process changes | |||
JsArray<ValueMap> changes = json.getJSValueMapArray("changes"); | |||
// Process changes | |||
JsArray<ValueMap> changes = json.getJSValueMapArray("changes"); | |||
ArrayList<Paintable> updatedWidgets = new ArrayList<Paintable>(); | |||
relativeSizeChanges.clear(); | |||
componentCaptionSizeChanges.clear(); | |||
ArrayList<Paintable> updatedWidgets = new ArrayList<Paintable>(); | |||
relativeSizeChanges.clear(); | |||
componentCaptionSizeChanges.clear(); | |||
int length = changes.length(); | |||
for (int i = 0; i < length; i++) { | |||
try { | |||
final UIDL change = changes.get(i).cast(); | |||
try { | |||
console.dirUIDL(change); | |||
} catch (final Exception e) { | |||
ClientExceptionHandler.displayError(e); | |||
// TODO: dir doesn't work in any browser although it should | |||
// work (works in hosted mode) | |||
// it partially did at some part but now broken. | |||
} | |||
final UIDL uidl = change.getChildUIDL(0); | |||
// TODO optimize | |||
final Paintable paintable = getPaintable(uidl.getId()); | |||
if (paintable != null) { | |||
paintable.updateFromUIDL(uidl, this); | |||
// paintable may have changed during render to another | |||
// implementation, use the new one for updated widgets map | |||
updatedWidgets.add(idToPaintableDetail.get(uidl.getId()) | |||
.getComponent()); | |||
} else { | |||
if (!uidl.getTag().equals( | |||
configuration.getEncodedWindowTag())) { | |||
ClientExceptionHandler | |||
.displayError("Received update for " | |||
+ uidl.getTag() | |||
+ ", but there is no such paintable (" | |||
+ uidl.getId() + ") rendered."); | |||
} else { | |||
view.updateFromUIDL(uidl, this); | |||
int length = changes.length(); | |||
for (int i = 0; i < length; i++) { | |||
try { | |||
final UIDL change = changes.get(i).cast(); | |||
try { | |||
console.dirUIDL(change); | |||
} catch (final Exception e) { | |||
ClientExceptionHandler.displayError(e); | |||
// TODO: dir doesn't work in any browser although it | |||
// should | |||
// work (works in hosted mode) | |||
// it partially did at some part but now broken. | |||
} | |||
final UIDL uidl = change.getChildUIDL(0); | |||
// TODO optimize | |||
final Paintable paintable = getPaintable(uidl.getId()); | |||
if (paintable != null) { | |||
paintable.updateFromUIDL(uidl, | |||
ApplicationConnection.this); | |||
// paintable may have changed during render to | |||
// another | |||
// implementation, use the new one for updated | |||
// widgets map | |||
updatedWidgets.add(idToPaintableDetail.get( | |||
uidl.getId()).getComponent()); | |||
} else { | |||
if (!uidl.getTag().equals( | |||
configuration.getEncodedWindowTag())) { | |||
ClientExceptionHandler | |||
.displayError("Received update for " | |||
+ uidl.getTag() | |||
+ ", but there is no such paintable (" | |||
+ uidl.getId() + ") rendered."); | |||
} else { | |||
view.updateFromUIDL(uidl, | |||
ApplicationConnection.this); | |||
} | |||
} | |||
} catch (final Throwable e) { | |||
ClientExceptionHandler.displayError(e); | |||
} | |||
} | |||
} catch (final Throwable e) { | |||
ClientExceptionHandler.displayError(e); | |||
} | |||
} | |||
if (json.containsKey("dd")) { | |||
// response contains data for drag and drop service | |||
VDragAndDropManager.get().handleServerResponse( | |||
json.getValueMap("dd")); | |||
} | |||
if (json.containsKey("dd")) { | |||
// response contains data for drag and drop service | |||
VDragAndDropManager.get().handleServerResponse( | |||
json.getValueMap("dd")); | |||
} | |||
// Check which widgets' size has been updated | |||
Set<Paintable> sizeUpdatedWidgets = new HashSet<Paintable>(); | |||
// Check which widgets' size has been updated | |||
Set<Paintable> sizeUpdatedWidgets = new HashSet<Paintable>(); | |||
updatedWidgets.addAll(relativeSizeChanges); | |||
sizeUpdatedWidgets.addAll(componentCaptionSizeChanges); | |||
updatedWidgets.addAll(relativeSizeChanges); | |||
sizeUpdatedWidgets.addAll(componentCaptionSizeChanges); | |||
for (Paintable paintable : updatedWidgets) { | |||
ComponentDetail detail = idToPaintableDetail.get(getPid(paintable)); | |||
Widget widget = (Widget) paintable; | |||
Size oldSize = detail.getOffsetSize(); | |||
Size newSize = new Size(widget.getOffsetWidth(), widget | |||
.getOffsetHeight()); | |||
for (Paintable paintable : updatedWidgets) { | |||
ComponentDetail detail = idToPaintableDetail | |||
.get(getPid(paintable)); | |||
Widget widget = (Widget) paintable; | |||
Size oldSize = detail.getOffsetSize(); | |||
Size newSize = new Size(widget.getOffsetWidth(), widget | |||
.getOffsetHeight()); | |||
if (oldSize == null || !oldSize.equals(newSize)) { | |||
sizeUpdatedWidgets.add(paintable); | |||
detail.setOffsetSize(newSize); | |||
} | |||
if (oldSize == null || !oldSize.equals(newSize)) { | |||
sizeUpdatedWidgets.add(paintable); | |||
detail.setOffsetSize(newSize); | |||
} | |||
} | |||
} | |||
Util.componentSizeUpdated(sizeUpdatedWidgets); | |||
Util.componentSizeUpdated(sizeUpdatedWidgets); | |||
if (meta != null) { | |||
if (meta.containsKey("appError")) { | |||
ValueMap error = meta.getValueMap("appError"); | |||
String html = ""; | |||
if (error.containsKey("caption") | |||
&& error.getString("caption") != null) { | |||
html += "<h1>" + error.getAsString("caption") + "</h1>"; | |||
} | |||
if (error.containsKey("message") | |||
&& error.getString("message") != null) { | |||
html += "<p>" + error.getAsString("message") + "</p>"; | |||
} | |||
String url = null; | |||
if (error.containsKey("url")) { | |||
url = error.getString("url"); | |||
} | |||
if (meta != null) { | |||
if (meta.containsKey("appError")) { | |||
ValueMap error = meta.getValueMap("appError"); | |||
String html = ""; | |||
if (error.containsKey("caption") | |||
&& error.getString("caption") != null) { | |||
html += "<h1>" + error.getAsString("caption") | |||
+ "</h1>"; | |||
} | |||
if (error.containsKey("message") | |||
&& error.getString("message") != null) { | |||
html += "<p>" + error.getAsString("message") | |||
+ "</p>"; | |||
} | |||
String url = null; | |||
if (error.containsKey("url")) { | |||
url = error.getString("url"); | |||
} | |||
if (html.length() != 0) { | |||
/* 45 min */ | |||
VNotification n = new VNotification(1000 * 60 * 45); | |||
n.addEventListener(new NotificationRedirect(url)); | |||
n.show(html, VNotification.CENTERED_TOP, | |||
VNotification.STYLE_SYSTEM); | |||
} else { | |||
redirect(url); | |||
if (html.length() != 0) { | |||
/* 45 min */ | |||
VNotification n = new VNotification(1000 * 60 * 45); | |||
n.addEventListener(new NotificationRedirect(url)); | |||
n.show(html, VNotification.CENTERED_TOP, | |||
VNotification.STYLE_SYSTEM); | |||
} else { | |||
redirect(url); | |||
} | |||
applicationRunning = false; | |||
} | |||
if (validatingLayouts) { | |||
getConsole().printLayoutProblems(meta, | |||
ApplicationConnection.this, | |||
zeroHeightComponents, zeroWidthComponents); | |||
zeroHeightComponents = null; | |||
zeroWidthComponents = null; | |||
validatingLayouts = false; | |||
} | |||
} | |||
applicationRunning = false; | |||
} | |||
if (validatingLayouts) { | |||
getConsole().printLayoutProblems(meta, this, | |||
zeroHeightComponents, zeroWidthComponents); | |||
zeroHeightComponents = null; | |||
zeroWidthComponents = null; | |||
validatingLayouts = false; | |||
} | |||
} | |||
// TODO build profiling for widget impl loading time | |||
final long prosessingTime = (new Date().getTime()) | |||
- start.getTime(); | |||
console.log(" Processing time was " | |||
+ String.valueOf(prosessingTime) + "ms for " | |||
+ jsonText.length() + " characters of JSON"); | |||
console.log("Referenced paintables: " | |||
+ idToPaintableDetail.size()); | |||
final long prosessingTime = (new Date().getTime()) - start.getTime(); | |||
console.log(" Processing time was " + String.valueOf(prosessingTime) | |||
+ "ms for " + jsonText.length() + " characters of JSON"); | |||
console.log("Referenced paintables: " + idToPaintableDetail.size()); | |||
endRequest(); | |||
endRequest(); | |||
} | |||
}; | |||
configuration.runWhenWidgetsLoaded(c); | |||
} | |||
/** |
@@ -9,7 +9,6 @@ import com.google.gwt.user.client.ui.Widget; | |||
import com.vaadin.terminal.gwt.client.ui.VButton; | |||
import com.vaadin.terminal.gwt.client.ui.VCheckBox; | |||
import com.vaadin.terminal.gwt.client.ui.VDateFieldCalendar; | |||
import com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper; | |||
import com.vaadin.terminal.gwt.client.ui.VFilterSelect; | |||
import com.vaadin.terminal.gwt.client.ui.VListSelect; | |||
import com.vaadin.terminal.gwt.client.ui.VNativeSelect; | |||
@@ -69,7 +68,7 @@ public class DefaultWidgetSet implements WidgetSet { | |||
Class<? extends Paintable> widgetClass = conf | |||
.getWidgetClassByEncodedTag(tag); | |||
// TODO add our quirks | |||
// add our historical quirks | |||
if (widgetClass == VButton.class && uidl.hasAttribute("type")) { | |||
return VCheckBox.class; | |||
@@ -119,10 +118,13 @@ public class DefaultWidgetSet implements WidgetSet { | |||
} | |||
public Class<? extends Paintable> getImplementationByClassName( | |||
String fullyqualifiedName) { | |||
String fullyqualifiedName, | |||
ApplicationConfiguration applicationConfiguration) { | |||
Class<? extends Paintable> implementationByServerSideClassName = map | |||
.getImplementationByServerSideClassName(fullyqualifiedName); | |||
.getImplementationByServerSideClassName(fullyqualifiedName, | |||
applicationConfiguration); | |||
return implementationByServerSideClassName; | |||
} | |||
} |
@@ -12,6 +12,7 @@ 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 | |||
@@ -36,6 +37,7 @@ public abstract class WidgetMap { | |||
} | |||
public abstract Class<? extends Paintable> getImplementationByServerSideClassName( | |||
String fullyqualifiedName); | |||
String fullyqualifiedName, | |||
ApplicationConfiguration applicationConfiguration); | |||
} |
@@ -42,9 +42,11 @@ public interface WidgetSet extends EntryPoint { | |||
* qualified name. | |||
* | |||
* @param fullyQualifiedName | |||
* @param applicationConfiguration | |||
* @return | |||
*/ | |||
public Class<? extends Paintable> getImplementationByClassName( | |||
String fullyQualifiedName); | |||
String fullyQualifiedName, | |||
ApplicationConfiguration applicationConfiguration); | |||
} |
@@ -78,6 +78,8 @@ public class WidgetMapGenerator extends Generator { | |||
ClassSourceFileComposerFactory composer = null; | |||
composer = new ClassSourceFileComposerFactory(packageName, className); | |||
composer.addImport("com.google.gwt.core.client.GWT"); | |||
composer.addImport("java.util.HashMap"); | |||
composer.addImport("com.google.gwt.core.client.RunAsyncCallback"); | |||
composer.setSuperclass("com.vaadin.terminal.gwt.client.WidgetMap"); | |||
SourceWriter sourceWriter = composer.createSourceWriter(context, | |||
printWriter); | |||
@@ -145,12 +147,10 @@ public class WidgetMapGenerator extends Generator { | |||
} | |||
/** | |||
* 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. | |||
* This method is protected to allow creation of optimized widgetsets. The | |||
* Widgetset will contain only implementation returned by this function. If | |||
* one knows which widgets are needed for the application, returning only | |||
* them here will significantly optimize the size of the produced JS. | |||
* | |||
* @return a collections of Vaadin components that will be added to | |||
* widgetset | |||
@@ -159,16 +159,42 @@ public class WidgetMapGenerator extends Generator { | |||
return ClassPathExplorer.getPaintablesHavingWidgetAnnotation(); | |||
} | |||
/** | |||
* Returns true if the widget for given component will be lazy loaded by the | |||
* client. The default implementation reads the information from the | |||
* {@link ClientWidget} annotation. | |||
* <p> | |||
* The method can be overridden to optimize the widget loading mechanism. If | |||
* the Widgetset is wanted to be optimized for a network with a high latency | |||
* or for a one with a very fast throughput, it may be good to return false | |||
* for every component. | |||
* | |||
* @param paintableType | |||
* @return true iff the widget for given component should be lazy loaded by | |||
* the client side engine | |||
*/ | |||
protected boolean isLazyLoaded(Class<? extends Paintable> paintableType) { | |||
ClientWidget annotation = paintableType | |||
.getAnnotation(ClientWidget.class); | |||
return annotation.lazyLoad(); | |||
} | |||
private void generateInstantiatorMethod( | |||
SourceWriter sourceWriter, | |||
Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation) { | |||
sourceWriter | |||
.println("public Paintable instantiate(Class<? extends Paintable> classType) {"); | |||
sourceWriter.indent(); | |||
.println("public interface Instantiator { public Paintable get();};"); | |||
// TODO detect if it would be noticably faster to instantiate with a | |||
// lookup with index than with the hashmap | |||
sourceWriter | |||
.println("Paintable p = super.instantiate(classType); if(p!= null) return p;"); | |||
.println("private HashMap<Class,Instantiator> instmap = new HashMap<Class,Instantiator>();"); | |||
sourceWriter | |||
.println("public void ensureInstantiator(Class<? extends Paintable> classType, final ApplicationConfiguration c) {"); | |||
sourceWriter.println("if(!instmap.containsKey(classType)){"); | |||
for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) { | |||
ClientWidget annotation = class1.getAnnotation(ClientWidget.class); | |||
Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = annotation | |||
@@ -177,14 +203,50 @@ public class WidgetMapGenerator extends Generator { | |||
// 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.print("if( classType == " + clientClass.getName() | |||
+ ".class) {"); | |||
String instantiator = "new Instantiator() { public Paintable get(){ return GWT.create(" | |||
+ clientClass.getName() + ".class );}}"; | |||
if (isLazyLoaded(class1)) { | |||
sourceWriter | |||
.print("c.widgetLoadStart();GWT.runAsync(new RunAsyncCallback() {\n" | |||
+ " public void onSuccess() {"); | |||
sourceWriter.print("instmap.put("); | |||
sourceWriter.print(clientClass.getName()); | |||
sourceWriter.print(".class, "); | |||
sourceWriter.print(instantiator); | |||
sourceWriter.println("); c.widgetLoaded();"); | |||
sourceWriter | |||
.print(" }\n" | |||
+ "\n" | |||
+ " public void onFailure(Throwable reason) {c.widgetLoaded();\n" | |||
+ "\n" + " }\n" + " });\n"); | |||
} else { | |||
// widget implementation in initially loaded js script | |||
sourceWriter.print("instmap.put("); | |||
sourceWriter.print(clientClass.getName()); | |||
sourceWriter.print(".class, "); | |||
sourceWriter.print(instantiator); | |||
sourceWriter.print(");"); | |||
} | |||
sourceWriter.print("}"); | |||
} | |||
sourceWriter.println("return null;"); | |||
sourceWriter.println("}"); | |||
sourceWriter.println("}"); | |||
sourceWriter | |||
.println("public Paintable instantiate(Class<? extends Paintable> classType) {"); | |||
sourceWriter.indent(); | |||
sourceWriter | |||
.println("Paintable p = super.instantiate(classType); if(p!= null) return p;"); | |||
sourceWriter.println("return instmap.get(classType).get();"); | |||
sourceWriter.outdent(); | |||
sourceWriter.println("}"); | |||
} | |||
@@ -200,7 +262,7 @@ public class WidgetMapGenerator extends Generator { | |||
Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation) { | |||
sourceWriter | |||
.println("public Class<? extends Paintable> " | |||
+ "getImplementationByServerSideClassName(String fullyQualifiedName) {"); | |||
+ "getImplementationByServerSideClassName(String fullyQualifiedName, ApplicationConfiguration c) {"); | |||
sourceWriter.indent(); | |||
sourceWriter | |||
.println("fullyQualifiedName = fullyQualifiedName.intern();"); | |||
@@ -211,9 +273,10 @@ public class WidgetMapGenerator extends Generator { | |||
.value(); | |||
sourceWriter.print("if ( fullyQualifiedName == \""); | |||
sourceWriter.print(class1.getName()); | |||
sourceWriter.print("\" ) return "); | |||
sourceWriter.print("\" ) { ensureInstantiator(" | |||
+ clientClass.getName() + ".class, c); return "); | |||
sourceWriter.print(clientClass.getName()); | |||
sourceWriter.println(".class;"); | |||
sourceWriter.println(".class;}"); | |||
sourceWriter.print("else "); | |||
} | |||
sourceWriter | |||
@@ -222,5 +285,4 @@ public class WidgetMapGenerator extends Generator { | |||
sourceWriter.println("}"); | |||
} | |||
} |
@@ -33,7 +33,7 @@ import com.vaadin.ui.themes.BaseTheme; | |||
* @since 3.0 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VButton.class) | |||
@ClientWidget(value = VButton.class, lazyLoad = false) | |||
public class Button extends AbstractField implements FieldEvents.BlurNotifier, | |||
FieldEvents.FocusNotifier { | |||
@@ -472,7 +472,7 @@ public class Button extends AbstractField implements FieldEvents.BlurNotifier, | |||
@Override | |||
public void handleAction(Object sender, Object target) { | |||
this.button.fireClick(); | |||
button.fireClick(); | |||
} | |||
} | |||
@@ -12,6 +12,7 @@ import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
import com.vaadin.terminal.gwt.client.Paintable; | |||
import com.vaadin.terminal.gwt.widgetsetutils.WidgetMapGenerator; | |||
/** | |||
* Annotation defining the default client side counterpart in GWT terminal for | |||
@@ -35,4 +36,34 @@ public @interface ClientWidget { | |||
* @return the client side counterpart for the annotated component | |||
*/ | |||
Class<? extends Paintable> value(); | |||
/** | |||
* The lazy loading of a widget implementation means the client side | |||
* component is not included in the initial JavaScript application loaded | |||
* when the application starts. Instead the implementation is loaded to the | |||
* client when it is first needed. | |||
* <p> | |||
* Lazy loaded widgets don't stress the size and startup time of the client | |||
* side as much as eagerly loaded widgets. On the other hand there is a | |||
* slight latency when lazy loaded widgets are first used as the client side | |||
* needs to visit the server to fetch the client side implementation. | |||
* <p> | |||
* In common situations the default value should be fine. If the widget | |||
* implementation commonly used and often on first view it is better set | |||
* lazy loading off for it. Also if the component implementation is really | |||
* thing, it may by justified to make the widget implementation eagerly | |||
* loaded. | |||
* <p> | |||
* Tunings to widget loading can also be made by overriding | |||
* {@link WidgetMapGenerator} in GWT module. Tunings might be helpful if the | |||
* end users have slow connections and especially if they have high latency | |||
* in their network. | |||
* | |||
* @return if true (default), the GWT code generator will make the client | |||
* side implementation lazy loaded. Displaying it first time on the | |||
* screen slightly increases, but widgets implementation does not | |||
* stress the initialization of the client side engine. | |||
*/ | |||
boolean lazyLoad() default true; | |||
} |
@@ -26,7 +26,7 @@ import com.vaadin.terminal.gwt.client.ui.VCustomComponent; | |||
* @since 3.0 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VCustomComponent.class) | |||
@ClientWidget(value = VCustomComponent.class, lazyLoad = false) | |||
public class CustomComponent extends AbstractComponentContainer { | |||
/** |
@@ -17,7 +17,7 @@ import com.vaadin.terminal.gwt.client.ui.VHorizontalLayout; | |||
* @since 5.3 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VHorizontalLayout.class) | |||
@ClientWidget(value = VHorizontalLayout.class, lazyLoad = false) | |||
public class HorizontalLayout extends AbstractOrderedLayout { | |||
public HorizontalLayout() { |
@@ -38,7 +38,7 @@ import com.vaadin.terminal.gwt.client.ui.VLabel; | |||
* @since 3.0 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VLabel.class) | |||
@ClientWidget(value = VLabel.class, lazyLoad = false) | |||
public class Label extends AbstractComponent implements Property, | |||
Property.Viewer, Property.ValueChangeListener, | |||
Property.ValueChangeNotifier, Comparable { |
@@ -24,7 +24,7 @@ import com.vaadin.terminal.gwt.client.ui.VOrderedLayout; | |||
*/ | |||
@SuppressWarnings("serial") | |||
@Deprecated | |||
@ClientWidget(VOrderedLayout.class) | |||
@ClientWidget(value = VOrderedLayout.class, lazyLoad = false) | |||
public class OrderedLayout extends AbstractOrderedLayout { | |||
/* Predefined orientations */ | |||
@@ -30,7 +30,7 @@ import com.vaadin.tools.ReflectTools; | |||
* @since 5.0 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VSplitPanelHorizontal.class) | |||
@ClientWidget(value = VSplitPanelHorizontal.class, lazyLoad = false) | |||
public class SplitPanel extends AbstractLayout { | |||
/* Predefined orientations */ |
@@ -38,7 +38,7 @@ import com.vaadin.terminal.gwt.client.ui.VTextField; | |||
* @since 3.0 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VTextField.class) | |||
@ClientWidget(value = VTextField.class, lazyLoad = false) | |||
public class TextField extends AbstractField implements | |||
FieldEvents.BlurNotifier, FieldEvents.FocusNotifier { | |||
@@ -20,7 +20,7 @@ import com.vaadin.terminal.gwt.client.ui.VUriFragmentUtility; | |||
* | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VUriFragmentUtility.class) | |||
@ClientWidget(value = VUriFragmentUtility.class, lazyLoad = false) | |||
public class UriFragmentUtility extends AbstractComponent { | |||
/** |
@@ -18,7 +18,7 @@ import com.vaadin.terminal.gwt.client.ui.VVerticalLayout; | |||
* @since 5.3 | |||
*/ | |||
@SuppressWarnings("serial") | |||
@ClientWidget(VVerticalLayout.class) | |||
@ClientWidget(value = VVerticalLayout.class, lazyLoad = false) | |||
public class VerticalLayout extends AbstractOrderedLayout { | |||
public VerticalLayout() { |