Column should not use a singleton FieldUpdater because the Cell may hang on to the FieldUpdater. We now create a new instance each time.

Review at http://gwt-code-reviews.appspot.com/620803

Review by: rice@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8327 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/cellview/client/Column.java b/user/src/com/google/gwt/user/cellview/client/Column.java
index 30e4249..1a51504 100644
--- a/user/src/com/google/gwt/user/cellview/client/Column.java
+++ b/user/src/com/google/gwt/user/cellview/client/Column.java
@@ -44,43 +44,36 @@
 
   /**
    * A {@link ValueUpdater} used by the {@link Column} to delay the field update
-   * until after the view data has been set.
-   * 
-   * @param <C> the type of data
+   * until after the view data has been set. After the view data has been set,
+   * the delay is revoked and we pass updates directly to the
+   * {@link FieldUpdater}.
    */
-  private static class DelayedValueUpdater<C> implements ValueUpdater<C> {
-    private C newValue;
+  private class DelayedValueUpdater implements ValueUpdater<C> {
+
     private boolean hasNewValue;
+    private boolean isDelayed = true;
+    private C newValue;
+    private final int rowIndex;
+    private final T rowObject;
 
-    /**
-     * Get the new value.
-     * 
-     * @return the new value
-     */
-    public C getNewValue() {
-      return newValue;
+    public DelayedValueUpdater(int rowIndex, T rowObject) {
+      this.rowIndex = rowIndex;
+      this.rowObject = rowObject;
     }
 
-    /**
-     * Check if the value has been updated.
-     * 
-     * @return true if updated, false if not
-     */
-    public boolean hasNewValue() {
-      return hasNewValue;
-    }
-
-    /**
-     * Reset this updater so it can be reused.
-     */
-    public void reset() {
-      newValue = null;
-      hasNewValue = false;
+    public void flush() {
+      isDelayed = false;
+      if (hasNewValue && fieldUpdater != null) {
+        fieldUpdater.update(rowIndex, rowObject, newValue);
+      }
     }
 
     public void update(C value) {
       hasNewValue = true;
       newValue = value;
+      if (!isDelayed) {
+        flush();
+      }
     }
   }
 
@@ -90,11 +83,6 @@
 
   protected Map<Object, Object> viewDataMap = new HashMap<Object, Object>();
 
-  /**
-   * The {@link DelayedValueUpdater} singleton.
-   */
-  private final DelayedValueUpdater<C> delayedValueUpdater = new DelayedValueUpdater<C>();
-
   public Column(Cell<C> cell) {
     this.cell = cell;
   }
@@ -134,9 +122,10 @@
       NativeEvent event, ProvidesKey<T> providesKey) {
     Object key = getKey(object, providesKey);
     Object viewData = getViewData(key);
-    delayedValueUpdater.reset();
+    DelayedValueUpdater valueUpdater = (fieldUpdater == null) ? null
+        : new DelayedValueUpdater(index, object);
     Object newViewData = cell.onBrowserEvent(elem, getValue(object), viewData,
-        event, fieldUpdater == null ? null : delayedValueUpdater);
+        event, valueUpdater);
 
     // We have to save the view data before calling the field updater, or the
     // view data will not be available.
@@ -146,8 +135,8 @@
     }
 
     // Call the FieldUpdater after setting the view data.
-    if (delayedValueUpdater.hasNewValue()) {
-      fieldUpdater.update(index, object, delayedValueUpdater.getNewValue());
+    if (valueUpdater != null) {
+      valueUpdater.flush();
     }
   }