aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatti Tahvonen <matti.tahvonen@itmill.com>2009-01-29 14:11:49 +0000
committerMatti Tahvonen <matti.tahvonen@itmill.com>2009-01-29 14:11:49 +0000
commita65c7b1d2e592f1473e1889662c0dd70d67d33be (patch)
tree6c53c51d52b8dc4449ce564440397ac58c77637a
parentfdd97dd3b3659ffc0e11d2656b39ce802fd319d6 (diff)
downloadvaadin-framework-a65c7b1d2e592f1473e1889662c0dd70d67d33be.tar.gz
vaadin-framework-a65c7b1d2e592f1473e1889662c0dd70d67d33be.zip
#2519, #2520 optimized usage of hasmaps in ac + dom inserts in cellbasedlayout
svn changeset:6676/svn branch:trunk
-rwxr-xr-xsrc/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java139
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ComponentDetail.java88
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ComponentDetailMap.java72
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ui/layout/CellBasedLayout.java42
4 files changed, 279 insertions, 62 deletions
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
index 00d43c3efb..47e1f06d52 100755
--- a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
@@ -72,15 +72,8 @@ public class ApplicationConnection {
private final Vector<String> pendingVariables = new Vector<String>();
- private final HashMap<String, Paintable> idToPaintable = new HashMap<String, Paintable>();
-
- private final HashMap<Paintable, String> paintableToId = new HashMap<Paintable, String>();
-
- /** Contains ExtendedTitleInfo by paintable id */
- private final HashMap<Paintable, TooltipInfo> paintableToTitle = new HashMap<Paintable, TooltipInfo>();
-
- private final HashMap<Widget, FloatSize> componentRelativeSizes = new HashMap<Widget, FloatSize>();
- private final HashMap<Widget, Size> componentOffsetSizes = new HashMap<Widget, Size>();
+ private final ComponentDetailMap idToPaintableDetail = ComponentDetailMap
+ .create();
private final WidgetSet widgetSet;
@@ -516,7 +509,7 @@ public class ApplicationConnection {
for (int i = 1; i < variableBurst.size(); i += 2) {
String id = variableBurst.get(i);
id = id.substring(0, id.indexOf(VAR_FIELD_SEPARATOR));
- if (!idToPaintable.containsKey(id)) {
+ if (!idToPaintableDetail.containsKey(id)) {
// variable owner does not exist anymore
variableBurst.remove(i - 1);
variableBurst.remove(i - 1);
@@ -622,8 +615,7 @@ public class ApplicationConnection {
meta = ((JSONObject) json).get("meta").isObject();
if (meta.containsKey("repaintAll")) {
view.clear();
- idToPaintable.clear();
- paintableToId.clear();
+ idToPaintableDetail.clear();
if (meta.containsKey("invalidLayouts")) {
validatingLayouts = true;
zeroWidthComponents = new HashSet<Paintable>();
@@ -667,12 +659,14 @@ public class ApplicationConnection {
// 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(idToPaintable.get(uidl.getId()));
+ updatedWidgets.add(idToPaintableDetail.get(uidl.getId())
+ .getComponent());
} else {
if (!uidl.getTag().equals("window")) {
ClientExceptionHandler
@@ -696,14 +690,15 @@ public class ApplicationConnection {
sizeUpdatedWidgets.addAll(componentCaptionSizeChanges);
for (Paintable paintable : updatedWidgets) {
+ ComponentDetail detail = idToPaintableDetail.get(getPid(paintable));
Widget widget = (Widget) paintable;
- Size oldSize = componentOffsetSizes.get(widget);
+ Size oldSize = detail.getOffsetSize();
Size newSize = new Size(widget.getOffsetWidth(), widget
.getOffsetHeight());
if (oldSize == null || !oldSize.equals(newSize)) {
sizeUpdatedWidgets.add(paintable);
- componentOffsetSizes.put(widget, newSize);
+ detail.setOffsetSize(newSize);
}
}
@@ -753,7 +748,7 @@ public class ApplicationConnection {
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: " + idToPaintable.size());
+ console.log("Referenced paintables: " + idToPaintableDetail.size());
endRequest();
}
@@ -783,16 +778,29 @@ public class ApplicationConnection {
}-*/;
public void registerPaintable(String id, Paintable paintable) {
- idToPaintable.put(id, paintable);
- paintableToId.put(paintable, id);
+ ComponentDetail componentDetail = new ComponentDetail();
+ componentDetail.setComponent(paintable);
+ idToPaintableDetail.put(id, componentDetail);
+ setPid(((Widget) paintable).getElement(), id);
}
- public void unregisterPaintable(Paintable p) {
- String id = paintableToId.get(p);
- idToPaintable.remove(id);
- paintableToTitle.remove(id);
- paintableToId.remove(p);
+ private native void setPid(Element el, String pid)
+ /*-{
+ el.tkPid = pid;
+ }-*/;
+
+ private String getPid(Paintable paintable) {
+ return getPid(((Widget) paintable).getElement());
+ }
+ private native String getPid(Element el)
+ /*-{
+ return el.tkPid;
+ }-*/;
+
+ public void unregisterPaintable(Paintable p) {
+ String id = getPid(p);
+ idToPaintableDetail.remove(id);
if (p instanceof HasWidgets) {
unregisterChildPaintables((HasWidgets) p);
}
@@ -817,7 +825,12 @@ public class ApplicationConnection {
* Paintable ID
*/
public Paintable getPaintable(String id) {
- return idToPaintable.get(id);
+ ComponentDetail componentDetail = idToPaintableDetail.get(id);
+ if (componentDetail == null) {
+ return null;
+ } else {
+ return componentDetail.getComponent();
+ }
}
private void addVariableToQueue(String paintableId, String variableName,
@@ -993,6 +1006,8 @@ public class ApplicationConnection {
*/
public boolean updateComponent(Widget component, UIDL uidl,
boolean manageCaption) {
+ ComponentDetail componentDetail = idToPaintableDetail
+ .get(getPid(component.getElement()));
// If the server request that a cached instance should be used, do
// nothing
@@ -1019,7 +1034,7 @@ public class ApplicationConnection {
if (!visible) {
// component is invisible, delete old size to notify parent, if
// later make visible
- componentOffsetSizes.remove(component);
+ componentDetail.setOffsetSize(null);
return true;
}
@@ -1079,7 +1094,7 @@ public class ApplicationConnection {
styleBuf.append(MODIFIED_CLASSNAME);
}
- TooltipInfo tooltipInfo = getTitleInfo((Paintable) component);
+ TooltipInfo tooltipInfo = componentDetail.getTooltipInfo();
if (uidl.hasAttribute("description")) {
tooltipInfo.setTitle(uidl.getStringAttribute("description"));
} else {
@@ -1124,12 +1139,12 @@ public class ApplicationConnection {
* taken into account
*/
- updateComponentSize(component, uidl);
+ updateComponentSize(componentDetail, uidl);
return false;
}
- private void updateComponentSize(Widget component, UIDL uidl) {
+ private void updateComponentSize(ComponentDetail cd, UIDL uidl) {
String w = uidl.hasAttribute("width") ? uidl
.getStringAttribute("width") : "";
@@ -1144,18 +1159,20 @@ public class ApplicationConnection {
// One or both is relative
FloatSize relativeSize = new FloatSize(relativeWidth,
relativeHeight);
- if (componentRelativeSizes.put(component, relativeSize) == null
- && componentOffsetSizes.containsKey(component)) {
+ if (cd.getRelativeSize() == null && cd.getOffsetSize() != null) {
// The component has changed from absolute size to relative size
- relativeSizeChanges.add((Paintable) component);
+ relativeSizeChanges.add(cd.getComponent());
}
+ cd.setRelativeSize(relativeSize);
} else if (relativeHeight < 0.0 && relativeWidth < 0.0) {
- if (componentRelativeSizes.remove(component) != null) {
+ if (cd.getRelativeSize() != null) {
// The component has changed from relative size to absolute size
- relativeSizeChanges.add((Paintable) component);
+ relativeSizeChanges.add(cd.getComponent());
}
+ cd.setRelativeSize(null);
}
+ Widget component = (Widget) cd.getComponent();
// Set absolute sizes
if (relativeHeight < 0.0) {
component.setHeight(h);
@@ -1167,7 +1184,7 @@ public class ApplicationConnection {
// Set relative sizes
if (relativeHeight >= 0.0 || relativeWidth >= 0.0) {
// One or both is relative
- handleComponentRelativeSize(component);
+ handleComponentRelativeSize(cd);
}
}
@@ -1197,7 +1214,11 @@ public class ApplicationConnection {
* development. Published to JavaScript.
*/
public void forceLayout() {
- Util.componentSizeUpdated(paintableToId.keySet());
+ Set<Paintable> set = new HashSet<Paintable>();
+ for (ComponentDetail cd : idToPaintableDetail.values()) {
+ set.add(cd.getComponent());
+ }
+ Util.componentSizeUpdated(set);
}
private void internalRunDescendentsLayout(HasWidgets container) {
@@ -1232,15 +1253,12 @@ public class ApplicationConnection {
}
}
- /**
- * Converts relative sizes into pixel sizes.
- *
- * @param child
- * @return true if the child has a relative size
- */
- public boolean handleComponentRelativeSize(Widget child) {
- Widget widget = child;
- FloatSize relativeSize = getRelativeSize(child);
+ private boolean handleComponentRelativeSize(ComponentDetail cd) {
+ if (cd == null) {
+ return false;
+ }
+ Widget widget = (Widget) cd.getComponent();
+ FloatSize relativeSize = cd.getRelativeSize();
if (relativeSize == null) {
return false;
}
@@ -1281,7 +1299,7 @@ public class ApplicationConnection {
height -= renderSpace.getScrollbarSize();
}
if (validatingLayouts && height <= 0) {
- zeroHeightComponents.add((Paintable) child);
+ zeroHeightComponents.add(cd.getComponent());
}
height = (int) (height * relativeSize.getHeight() / 100.0);
@@ -1321,7 +1339,7 @@ public class ApplicationConnection {
width -= renderSpace.getScrollbarSize();
}
if (validatingLayouts && width <= 0) {
- zeroWidthComponents.add((Paintable) child);
+ zeroWidthComponents.add(cd.getComponent());
}
width = (int) (width * relativeSize.getWidth() / 100.0);
@@ -1341,11 +1359,23 @@ public class ApplicationConnection {
}
return true;
+ }
+
+ /**
+ * Converts relative sizes into pixel sizes.
+ *
+ * @param child
+ * @return true if the child has a relative size
+ */
+ public boolean handleComponentRelativeSize(Widget child) {
+ return handleComponentRelativeSize(idToPaintableDetail.get(getPid(child
+ .getElement())));
}
public FloatSize getRelativeSize(Widget widget) {
- return componentRelativeSizes.get(widget);
+ return idToPaintableDetail.get(getPid(widget.getElement()))
+ .getRelativeSize();
}
/**
@@ -1365,10 +1395,12 @@ public class ApplicationConnection {
Paintable w = getPaintable(id);
if (w != null) {
return w;
+ } else {
+ w = widgetSet.createWidget(uidl);
+ registerPaintable(id, w);
+ return w;
+
}
- w = widgetSet.createWidget(uidl);
- registerPaintable(id, w);
- return w;
}
public String getResource(String name) {
@@ -1448,12 +1480,7 @@ public class ApplicationConnection {
*
*/
public TooltipInfo getTitleInfo(Paintable titleOwner) {
- TooltipInfo info = paintableToTitle.get(titleOwner);
- if (info == null) {
- info = new TooltipInfo();
- paintableToTitle.put(titleOwner, info);
- }
- return info;
+ return idToPaintableDetail.get(getPid(titleOwner)).getTooltipInfo();
}
private final ITooltip tooltip = new ITooltip(this);
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ComponentDetail.java b/src/com/itmill/toolkit/terminal/gwt/client/ComponentDetail.java
new file mode 100644
index 0000000000..7a47651332
--- /dev/null
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ComponentDetail.java
@@ -0,0 +1,88 @@
+package com.itmill.toolkit.terminal.gwt.client;
+
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.FloatSize;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
+
+class ComponentDetail {
+ private String pid;
+ private Paintable component;
+ private TooltipInfo tooltipInfo = new TooltipInfo();
+ private FloatSize relativeSize;
+ private Size offsetSize;
+
+ /**
+ * @return the pid
+ */
+ String getPid() {
+ return pid;
+ }
+
+ /**
+ * @param pid
+ * the pid to set
+ */
+ void setPid(String pid) {
+ this.pid = pid;
+ }
+
+ /**
+ * @return the component
+ */
+ Paintable getComponent() {
+ return component;
+ }
+
+ /**
+ * @param component
+ * the component to set
+ */
+ void setComponent(Paintable component) {
+ this.component = component;
+ }
+
+ /**
+ * @return the tooltipInfo
+ */
+ TooltipInfo getTooltipInfo() {
+ return tooltipInfo;
+ }
+
+ /**
+ * @param tooltipInfo
+ * the tooltipInfo to set
+ */
+ void setTooltipInfo(TooltipInfo tooltipInfo) {
+ this.tooltipInfo = tooltipInfo;
+ }
+
+ /**
+ * @return the relativeSize
+ */
+ FloatSize getRelativeSize() {
+ return relativeSize;
+ }
+
+ /**
+ * @param relativeSize
+ * the relativeSize to set
+ */
+ void setRelativeSize(FloatSize relativeSize) {
+ this.relativeSize = relativeSize;
+ }
+
+ /**
+ * @return the offsetSize
+ */
+ Size getOffsetSize() {
+ return offsetSize;
+ }
+
+ /**
+ * @param offsetSize
+ * the offsetSize to set
+ */
+ void setOffsetSize(Size offsetSize) {
+ this.offsetSize = offsetSize;
+ }
+
+}
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ComponentDetailMap.java b/src/com/itmill/toolkit/terminal/gwt/client/ComponentDetailMap.java
new file mode 100644
index 0000000000..cc7f474a06
--- /dev/null
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ComponentDetailMap.java
@@ -0,0 +1,72 @@
+package com.itmill.toolkit.terminal.gwt.client;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+final class ComponentDetailMap extends JavaScriptObject {
+
+ protected ComponentDetailMap() {
+ }
+
+ static ComponentDetailMap create() {
+ return (ComponentDetailMap) JavaScriptObject.createObject();
+ }
+
+ boolean isEmpty() {
+ return size() == 0;
+ }
+
+ final native boolean containsKey(String key)
+ /*-{
+ return this.hasOwnProperty(key);
+ }-*/;
+
+ final native ComponentDetail get(String key)
+ /*-{
+ return this[key];
+ }-*/;
+
+ final native void put(String id, ComponentDetail value)
+ /*-{
+ this[id] = value;
+ }-*/;
+
+ final native void remove(String id)
+ /*-{
+ delete this[id];
+ }-*/;
+
+ final native int size()
+ /*-{
+ var count = 0;
+ for(var key in this) {
+ count++;
+ }
+ return count;
+ }-*/;
+
+ final native void clear()
+ /*-{
+ for(var key in this) {
+ if(this.hasOwnProperty(key)) {
+ delete this[key];
+ }
+ }
+ }-*/;
+
+ private final native void fillWithValues(Collection<ComponentDetail> list)
+ /*-{
+ for(var key in this) {
+ list.@java.util.Collection::add(Ljava/lang/Object;)(this[key]);
+ }
+ }-*/;
+
+ final Collection<ComponentDetail> values() {
+ ArrayList<ComponentDetail> list = new ArrayList<ComponentDetail>();
+ fillWithValues(list);
+ return list;
+ }
+
+}
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/layout/CellBasedLayout.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/layout/CellBasedLayout.java
index 7e9258a436..f0a06c26dd 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/ui/layout/CellBasedLayout.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/layout/CellBasedLayout.java
@@ -6,7 +6,6 @@ import java.util.Map;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style;
-import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.Widget;
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
@@ -38,7 +37,7 @@ public abstract class CellBasedLayout extends ComplexPanel implements Container
private boolean dynamicHeight;
- private DivElement clearElement;
+ private final DivElement clearElement = Document.get().createDivElement();
private String lastStyleName = "";
@@ -86,7 +85,6 @@ public abstract class CellBasedLayout extends ComplexPanel implements Container
getElement().appendChild(root);
- clearElement = Document.get().createDivElement();
Style style = clearElement.getStyle();
style.setProperty("width", "0px");
style.setProperty("height", "0px");
@@ -163,9 +161,41 @@ public abstract class CellBasedLayout extends ComplexPanel implements Container
protected void addOrMoveChild(ChildComponentContainer childComponent,
int position) {
- widgetToComponentContainer.put(childComponent.getWidget(),
- childComponent);
- super.insert(childComponent, (Element) root.cast(), position, true);
+ if (childComponent.getParent() == this) {
+ if (getWidgetIndex(childComponent) != position) {
+ // Detach from old position child.
+ childComponent.removeFromParent();
+
+ // Logical attach.
+ getChildren().insert(childComponent, position);
+
+ root.insertBefore(childComponent.getElement(), root
+ .getChildNodes().getItem(position));
+
+ adopt(childComponent);
+ }
+ } else {
+ widgetToComponentContainer.put(childComponent.getWidget(),
+ childComponent);
+
+ // Logical attach.
+ getChildren().insert(childComponent, position);
+
+ // avoid inserts (they are slower than appends)
+ boolean insert = true;
+ if (widgetToComponentContainer.size() == position) {
+ insert = false;
+ }
+ if (insert) {
+ root.insertBefore(childComponent.getElement(), root
+ .getChildNodes().getItem(position));
+ } else {
+ root.insertBefore(childComponent.getElement(), clearElement);
+ }
+ // Adopt.
+ adopt(childComponent);
+
+ }
}