Revision: 7742
Author: [email protected]
Date: Wed Mar 17 11:08:23 2010
Log: Checkpoint validation work + some misc stock fixes

http://code.google.com/p/google-web-toolkit/source/detail?r=7742

Added:
 /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation
/trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation/Validation.gwt.xml
 /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation/client
/trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation/client/ValidatableColumn.java /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation/client/ValidatableField.java /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation/client/ValidatableInputCell.java /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation/client/Validation.java
 /trunk/bikeshed/war/Validation.html
Modified:
 /trunk/bikeshed/src/com/google/gwt/bikeshed/cells/client/FieldUpdater.java
 /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/Column.java
/trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListModel.java
 /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java
/trunk/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/FavoritesWidget.java /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockSample.java

=======================================
--- /dev/null
+++ /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation/Validation.gwt.xml Wed Mar 17 11:08:23 2010
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Could not determine the version of your GWT SDK; using the module DTD from GWT 1.6.4. You may want to change this. --> +<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6.4//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.6.4/distro-source/core/src/gwt-module.dtd";>
+<module rename-to='validation'>
+       <inherits name="com.google.gwt.bikeshed.list.List" />
+       <source path="client" />
+       <entry-point
+               
class="com.google.gwt.bikeshed.sample.validation.client.Validation">
+       </entry-point>
+</module>
=======================================
--- /dev/null
+++ /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation/client/ValidatableColumn.java Wed Mar 17 11:08:23 2010
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.bikeshed.sample.validation.client;
+
+import com.google.gwt.bikeshed.cells.client.Cell;
+import com.google.gwt.bikeshed.cells.client.FieldUpdater;
+import com.google.gwt.bikeshed.cells.client.ValueUpdater;
+import com.google.gwt.bikeshed.list.client.Column;
+import com.google.gwt.bikeshed.sample.validation.client.ValidatableField.DefaultValidatableField;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NativeEvent;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A column that support validation.
+ *
+ * @param <T> the row type
+ * @param <C> the column type
+ */
+// TODO - avoid wrapping cells that are never modified
+public abstract class ValidatableColumn<T, C> extends Column<T, ValidatableField<C>> {
+
+ Map<T, ValidatableField<C>> fieldMap = new HashMap<T, ValidatableField<C>>();
+
+  public ValidatableColumn(Cell<ValidatableField<C>> cell) {
+    super(cell);
+  }
+
+  // Override onBrowserEvent to copy the ValueUpdater value into our copy
+  @Override
+  public void onBrowserEvent(Element elem, final int index, final T object,
+      NativeEvent event) {
+ final FieldUpdater<T, ValidatableField<C>> fieldUpdater = getFieldUpdater();
+    final ValidatableField<C> field = getValue(object);
+    getCell().onBrowserEvent(elem, field, event,
+ fieldUpdater == null ? null : new ValueUpdater<ValidatableField<C>>() {
+      public void update(ValidatableField<C> value) {
+        // Copy pending value from value (copy) to field (original)
+        field.setPendingValue(value.getPendingValue());
+        fieldUpdater.update(index, object, field);
+      }
+    });
+  }
+
+  /**
+ * Returns the value of the field with the underlying object that is to be
+   * validated.
+   *
+   * @param object the underlying data transfer object, of type T
+   * @return a value of type C
+   */
+  protected abstract C getValidatableValue(T object);
+
+  @Override
+  protected ValidatableField<C> getValue(T object) {
+    ValidatableField<C> vfield = fieldMap.get(object);
+    if (vfield == null) {
+      C validatableValue = getValidatableValue(object);
+      vfield = new DefaultValidatableField<C>(validatableValue);
+      fieldMap.put(object, vfield);
+    }
+
+    return vfield;
+  }
+}
=======================================
--- /dev/null
+++ /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation/client/ValidatableField.java Wed Mar 17 11:08:23 2010
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.bikeshed.sample.validation.client;
+
+/**
+ * A field value with a pending future value and a valid flag.
+ *
+ * @param <T> the value type of the field
+ */
+public interface ValidatableField<T> {
+  T getPendingValue();
+  T getValue();
+  boolean isInvalid();
+  void setInvalid(boolean isInvalid);
+  void setPendingValue(T pendingValue);
+  void setValue(T value);
+
+  /**
+   * Default implementation of ValidatableField.
+   *
+   * @param <T> the value type of the field
+   */
+ public static class DefaultValidatableField<T> implements ValidatableField<T> {
+    static int genserial = 0;
+    int serial;
+    boolean isInvalid;
+    T pendingValue;
+    T value;
+
+    public DefaultValidatableField(T value) {
+      this.serial = genserial++;
+      this.value = value;
+    }
+
+    public DefaultValidatableField(ValidatableField<T> other) {
+      if (other instanceof DefaultValidatableField<?>) {
+        this.serial = ((DefaultValidatableField<T>) other).serial;
+      }
+      this.value = other.getValue();
+      this.pendingValue = other.getPendingValue();
+      this.isInvalid = other.isInvalid();
+    }
+
+    public T getPendingValue() {
+      return pendingValue;
+    }
+
+    public T getValue() {
+      return value;
+    }
+
+    public boolean isInvalid() {
+      return isInvalid;
+    }
+
+    public void setInvalid(boolean isInvalid) {
+      this.isInvalid = isInvalid;
+    }
+
+    public void setPendingValue(T pendingValue) {
+      this.pendingValue = pendingValue;
+    }
+
+    public void setValue(T value) {
+      this.value = value;
+    }
+  }
+}
=======================================
--- /dev/null
+++ /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation/client/ValidatableInputCell.java Wed Mar 17 11:08:23 2010
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.bikeshed.sample.validation.client;
+
+import com.google.gwt.bikeshed.cells.client.Cell;
+import com.google.gwt.bikeshed.cells.client.ValueUpdater;
+import com.google.gwt.bikeshed.sample.validation.client.ValidatableField.DefaultValidatableField;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.InputElement;
+import com.google.gwt.dom.client.NativeEvent;
+
+/**
+ * A String Cell that supports validation.
+ */
+public class ValidatableInputCell extends Cell<ValidatableField<String>> {
+
+  @Override
+ public void onBrowserEvent(Element parent, ValidatableField<String> value, NativeEvent event,
+      ValueUpdater<ValidatableField<String>> valueUpdater) {
+    if (event.getType().equals("change")) {
+      InputElement input = parent.getFirstChild().cast();
+
+      // Mark as pending
+      input.getStyle().setColor("blue");
+
+ ValidatableField<String> field = new DefaultValidatableField<String>(value);
+      field.setPendingValue(input.getValue());
+      valueUpdater.update(field);
+    }
+  }
+
+  @Override
+  public void render(ValidatableField<String> value, StringBuilder sb) {
+    String pendingValue = value.getPendingValue();
+    sb.append("<input type=\"text\" value=\"");
+    boolean invalid = value.isInvalid();
+    if (pendingValue != null) {
+      sb.append(pendingValue);
+    } else {
+      sb.append(value.getValue());
+    }
+    sb.append("\" style=\"color:");
+    if (pendingValue != null) {
+      sb.append(invalid ? "red" : "blue");
+    } else {
+      sb.append("black");
+    }
+    sb.append("\"></input>");
+  }
+}
=======================================
--- /dev/null
+++ /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/validation/client/Validation.java Wed Mar 17 11:08:23 2010
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.bikeshed.sample.validation.client;
+
+import com.google.gwt.bikeshed.cells.client.FieldUpdater;
+import com.google.gwt.bikeshed.cells.client.TextCell;
+import com.google.gwt.bikeshed.list.client.Column;
+import com.google.gwt.bikeshed.list.client.PagingTableListView;
+import com.google.gwt.bikeshed.list.shared.ListListModel;
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.RootPanel;
+
+import java.util.List;
+
+/**
+ * Validation demo.
+ */
+public class Validation implements EntryPoint {
+
+  static class Address {
+    static int genkey = 0;
+    int key;
+    String message;
+    String state;
+    String zip;
+    boolean zipInvalid;
+
+    public Address(Address address) {
+      this.key = address.key;
+      this.state = address.state;
+      this.zip = address.zip;
+    }
+
+    public Address(String state, String zip) {
+      this.key = genkey++;
+      this.state = state;
+      this.zip = zip;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+      if (!(other instanceof Address)) {
+        return false;
+      }
+      return ((Address) other).key == key;
+    }
+
+    @Override
+    public int hashCode() {
+      return key;
+    }
+  }
+
+  public static boolean zipInvalid(int zip) {
+    return zip % 3 == 0;
+  }
+
+  public void onModuleLoad() {
+    ListListModel<Address> listModel = new ListListModel<Address>();
+    final List<Address> list = listModel.getList();
+    for (int i = 10; i < 50; i++) {
+      if (zipInvalid(30000 + i)) {
+        continue;
+      }
+
+      String zip = "300" + i;
+      list.add(new Address("GA", zip));
+    }
+
+ PagingTableListView<Address> table = new PagingTableListView<Address>(listModel, 10); + Column<Address, String> stateColumn = new Column<Address, String>(new TextCell()) {
+      @Override
+      protected String getValue(Address object) {
+        return object.state;
+      }
+    };
+
+    ValidatableColumn<Address, String> zipColumn =
+      new ValidatableColumn<Address, String>(new ValidatableInputCell()) {
+        @Override
+        protected String getValidatableValue(Address object) {
+          return object.zip;
+        }
+    };
+ zipColumn.setFieldUpdater(new FieldUpdater<Address, ValidatableField<String>>() { + public void update(final int index, final Address object, final ValidatableField<String> value) {
+        // Perform validation after a 2-second delay
+        new Timer() {
+          @Override
+          public void run() {
+            String pendingValue = value.getPendingValue();
+
+            int zip = Integer.parseInt(pendingValue);
+            boolean zipInvalid = Validation.zipInvalid(zip);
+
+            final Address newValue = new Address(object);
+ newValue.zip = pendingValue == null ? value.getValue() : pendingValue;
+            newValue.zipInvalid = zipInvalid;
+
+            value.setInvalid(zipInvalid);
+            if (!zipInvalid) {
+              value.setValue(pendingValue);
+              value.setPendingValue(null);
+            }
+
+            list.set(index, newValue);
+          }
+        }.schedule(2000);
+      }
+    });
+
+ Column<Address, String> messageColumn = new Column<Address, String>(new TextCell()) {
+      @Override
+      protected String getValue(Address object) {
+        return object.zipInvalid ? "Please fix the zip code" : "";
+      }
+    };
+
+    table.addColumn(stateColumn);
+    table.addColumn(zipColumn);
+    table.addColumn(messageColumn);
+
+    RootPanel.get().add(table);
+  }
+}
=======================================
--- /dev/null
+++ /trunk/bikeshed/war/Validation.html Wed Mar 17 11:08:23 2010
@@ -0,0 +1,13 @@
+<!doctype html>
+<html>
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <title>Validation</title>
+ <script type="text/javascript" language="javascript" src="validation/validation.nocache.js"></script>
+  </head>
+
+  <body>
+ <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
+
+  </body>
+</html>
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/cells/client/FieldUpdater.java Fri Feb 26 09:32:06 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/cells/client/FieldUpdater.java Wed Mar 17 11:08:23 2010
@@ -26,9 +26,9 @@

   /**
    * Announces a new value for a field within a base object.
-   *
+   * @param index TODO
    * @param object the base object to be updated
    * @param value the new value of the field being updated.
    */
-  void update(T object, C value);
-}
+  void update(int index, T object, C value);
+}
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/Column.java Fri Feb 26 09:32:06 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/Column.java Wed Mar 17 11:08:23 2010
@@ -35,17 +35,19 @@
     this.cell = cell;
   }

- public void onBrowserEvent(Element elem, final T object, NativeEvent event) {
+  public void onBrowserEvent(Element elem, final int index, final T object,
+      NativeEvent event) {
     cell.onBrowserEvent(elem, getValue(object), event,
         fieldUpdater == null ? null : new ValueUpdater<C>() {
       public void update(C value) {
-        fieldUpdater.update(object, value);
+        fieldUpdater.update(index, object, value);
       }
     });
   }

   public void render(T object, StringBuilder sb) {
-    cell.render(getValue(object), sb);
+    C value = getValue(object);
+    cell.render(value, sb);
   }

   public void setFieldUpdater(FieldUpdater<T, C> fieldUpdater) {
@@ -55,6 +57,10 @@
   protected Cell<C> getCell() {
     return cell;
   }
+
+  protected FieldUpdater<T, C> getFieldUpdater() {
+    return fieldUpdater;
+  }

   protected abstract C getValue(T object);
 }
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java Wed Mar 10 08:48:25 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java Wed Mar 17 11:08:23 2010
@@ -149,7 +149,7 @@
       int row = tr.getSectionRowIndex();
       T value = data.get(row);
       Column<T, ?> column = columns.get(col);
-      column.onBrowserEvent(cell, value, event);
+      column.onBrowserEvent(cell, curPage * pageSize + row, value, event);
     }
   }

=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListModel.java Fri Mar 12 11:27:24 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListModel.java Wed Mar 17 11:08:23 2010
@@ -151,10 +151,6 @@
   protected void updateViewData(int start, int length, List<T> values) {
     int end = start + length;
     for (DefaultListRegistration reg : registrations) {
-      // Inform the views if there is no data
-      if (values.size() == 0) {
-        reg.getHandler().onSizeChanged(new SizeChangeEvent(0, true));
-      }
       int curStart = reg.getStart();
       int curLength = reg.getLength();
       int curEnd = curStart + curLength;
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java Fri Feb 26 10:28:42 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java Wed Mar 17 11:08:23 2010
@@ -223,6 +223,7 @@

   @Override
   protected void onRangeChanged() {
+    updateDataSize(listWrapper.size(), true);
     updateViewData(0, listWrapper.size(), listWrapper);
   }
 }
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/FavoritesWidget.java Thu Mar 11 09:45:33 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/FavoritesWidget.java Wed Mar 17 11:08:23 2010
@@ -47,6 +47,7 @@
     listView.addColumn(Columns.changeColumn, new TextHeader("change"));
     listView.addColumn(Columns.sharesColumn, new TextHeader("shares"));
     listView.addColumn(Columns.dollarsColumn, new TextHeader("value"));
+ listView.addColumn(Columns.profitLossColumn, new TextHeader("profit/loss"));
     listView.addColumn(Columns.buyColumn);
     listView.addColumn(Columns.sellColumn);
   }
=======================================
--- /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockSample.java Fri Mar 12 11:27:24 2010 +++ /trunk/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockSample.java Wed Mar 17 11:08:23 2010
@@ -143,19 +143,19 @@

     // Hook up handlers to columns and the buy/sell popup.
Columns.favoriteColumn.setFieldUpdater(new FieldUpdater<StockQuote, Boolean>() {
-      public void update(StockQuote object, Boolean value) {
+      public void update(int index, StockQuote object, Boolean value) {
         setFavorite(object.getTicker(), value);
       }
     });

Columns.buyColumn.setFieldUpdater(new FieldUpdater<StockQuote, String>() {
-      public void update(StockQuote quote, String value) {
+      public void update(int index, StockQuote quote, String value) {
         buy(quote);
       }
     });

Columns.sellColumn.setFieldUpdater(new FieldUpdater<StockQuote, String>() {
-      public void update(StockQuote quote, String value) {
+      public void update(int index, StockQuote quote, String value) {
         sell(quote);
       }
     });

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to