Revision: 8240
Author: jlaba...@google.com
Date: Wed Jun  9 09:35:40 2010
Log: Replacing CurrencyCell with generic NumberCell that uses NumberFormat.

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

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

Added:
 /trunk/user/src/com/google/gwt/cell/client/NumberCell.java
 /trunk/user/test/com/google/gwt/cell/client/NumberCellTest.java
Deleted:
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/SortableColumn.java
 /trunk/user/src/com/google/gwt/cell/client/CurrencyCell.java
Modified:
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/ExpensesCommon.gwt.xml /trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/ExpenseDetails.java

=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/cell/client/NumberCell.java Wed Jun 9 09:35:40 2010
@@ -0,0 +1,52 @@
+/*
+ * 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.cell.client;
+
+import com.google.gwt.i18n.client.NumberFormat;
+
+/**
+ * A {...@link Cell} used to render formatted numbers.
+ */
+public class NumberCell extends AbstractCell<Number> {
+
+  /**
+   * The {...@link NumberFormat} used to render the number.
+   */
+  private final NumberFormat format;
+
+  /**
+   * Construct a new {...@link NumberCell} using decimal format.
+   */
+  public NumberCell() {
+    this(NumberFormat.getDecimalFormat());
+  }
+
+  /**
+   * Construct a new {...@link NumberCell}.
+   *
+   * @param format the {...@link NumberFormat} used to render the number
+   */
+  public NumberCell(NumberFormat format) {
+    this.format = format;
+  }
+
+  @Override
+  public void render(Number value, Object viewData, StringBuilder sb) {
+    if (value != null) {
+      sb.append(format.format(value));
+    }
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/cell/client/NumberCellTest.java Wed Jun 9 09:35:40 2010
@@ -0,0 +1,54 @@
+/*
+ * 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.cell.client;
+
+import com.google.gwt.i18n.client.NumberFormat;
+
+/**
+ * Tests for {...@link ButtonCell}.
+ */
+public class NumberCellTest extends CellTestBase<Number> {
+
+  @Override
+  protected boolean consumesEvents() {
+    return false;
+  }
+
+  @Override
+  protected Cell<Number> createCell() {
+    return new NumberCell(NumberFormat.getFormat("#.##"));
+  }
+
+  @Override
+  protected Number createCellValue() {
+    return new Double(100.12);
+  }
+
+  @Override
+  protected boolean dependsOnSelection() {
+    return false;
+  }
+
+  @Override
+  protected String getExpectedInnerHtml() {
+    return "100.12";
+  }
+
+  @Override
+  protected String getExpectedInnerHtmlNull() {
+    return "";
+  }
+}
=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/SortableColumn.java Mon Jun 7 12:20:31 2010
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.sample.expenses.gwt.client;
-
-import com.google.gwt.cell.client.Cell;
-import com.google.gwt.user.cellview.client.Column;
-
-import java.util.Comparator;
-
-/**
- * A column that provides forward and reverse {...@link Comparator}s.
- *
- * @param <T> the row type
- * @param <C> the column type
- */
-public abstract class SortableColumn<T, C> extends Column<T, C> {
-  private Comparator<T> forwardComparator;
-
-  private Comparator<T> reverseComparator;
-
-  public SortableColumn(Cell<C> cell) {
-    super(cell);
-  }
-
-  /**
- * Convenience method to return a {...@link Comparator} that may be used to sort - * records of type T by the values of this column, using the natural ordering
-   * of the column type C. If C does not implement Comparable<C>, a runtime
-   * exception will be thrown when the returned comparator's
- * {...@link Comparator#compare(Object, Object) compare} method is called. If - * reverse is true, the returned comparator will sort in reverse order. The
-   * returned comparator instances are cached for future calls.
-   *
-   * @param reverse if true, sort in reverse
-   * @return an instance of Comparator<T>
-   */
-  public Comparator<T> getComparator(final boolean reverse) {
-    if (!reverse && forwardComparator != null) {
-      return forwardComparator;
-    }
-    if (reverse && reverseComparator != null) {
-      return reverseComparator;
-    }
-    Comparator<T> comparator = new Comparator<T>() {
-      @SuppressWarnings("unchecked")
-      public int compare(T o1, T o2) {
-        // Null check the row object.
-        if (o1 == null && o2 == null) {
-          return 0;
-        } else if (o1 == null) {
-          return reverse ? 1 : -1;
-        } else if (o2 == null) {
-          return reverse ? -1 : 1;
-        }
-
-        // Compare the column value.
-        C c1 = getValue(o1);
-        C c2 = getValue(o2);
-        if (c1 == null && c2 == null) {
-          return 0;
-        } else if (c1 == null) {
-          return reverse ? 1 : -1;
-        } else if (c2 == null) {
-          return reverse ? -1 : 1;
-        }
-        int comparison = ((Comparable<C>) c1).compareTo(c2);
-        return reverse ? -comparison : comparison;
-      }
-    };
-
-    if (reverse) {
-      reverseComparator = comparator;
-    } else {
-      forwardComparator = comparator;
-    }
-    return comparator;
-  }
-}
=======================================
--- /trunk/user/src/com/google/gwt/cell/client/CurrencyCell.java Fri May 28 08:44:36 2010
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.cell.client;
-
-/**
- * A {...@link Cell} used to render currency.
- *
- * <p>
- * Note: This class is new and its interface subject to change.
- * </p>
- */
-public class CurrencyCell extends AbstractCell<Integer> {
-
-  @Override
-  public void render(Integer price, Object viewData, StringBuilder sb) {
-    // TODO: Use legit i18n'd currency formatting.
-    boolean negative = price < 0;
-    if (negative) {
-      price = -price;
-    }
-    int dollars = price / 100;
-    int cents = price % 100;
-
-    if (negative) {
-      sb.append("-");
-    }
-    sb.append("$");
-    sb.append(dollars);
-    sb.append('.');
-    if (cents < 10) {
-      sb.append('0');
-    }
-    sb.append(cents);
-  }
-}
=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/ExpensesCommon.gwt.xml Mon Jun 7 12:20:31 2010 +++ /trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/ExpensesCommon.gwt.xml Wed Jun 9 09:35:40 2010
@@ -11,4 +11,8 @@
   <source path='request'/>
   <source path='place'/>
   <source path='ui'/>
+
+  <!-- Default Locale. -->
+  <extend-property name="locale" values="en"/>
+  <set-property-fallback name="locale" value="en"/>
 </module>
=======================================
--- /trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/ExpenseDetails.java Mon Jun 7 12:20:31 2010 +++ /trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/ExpenseDetails.java Wed Jun 9 09:35:40 2010
@@ -16,9 +16,9 @@
 package com.google.gwt.sample.expenses.gwt.client;

 import com.google.gwt.cell.client.Cell;
-import com.google.gwt.cell.client.CurrencyCell;
 import com.google.gwt.cell.client.DateCell;
 import com.google.gwt.cell.client.FieldUpdater;
+import com.google.gwt.cell.client.NumberCell;
 import com.google.gwt.cell.client.SelectionCell;
 import com.google.gwt.cell.client.TextCell;
 import com.google.gwt.cell.client.ValueUpdater;
@@ -38,6 +38,7 @@
 import com.google.gwt.event.logical.shared.CloseEvent;
 import com.google.gwt.event.logical.shared.CloseHandler;
 import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.NumberFormat;
 import com.google.gwt.requestfactory.shared.Receiver;
 import com.google.gwt.resources.client.ImageResource;
 import com.google.gwt.sample.bikeshed.style.client.Styles;
@@ -339,12 +340,6 @@
     TableStyle cellTableStyle();
   }

- private static final GetValue<ExpenseRecord, Date> createdGetter = new GetValue<ExpenseRecord, Date>() {
-    public Date getValue(ExpenseRecord object) {
-      return object.getCreated();
-    }
-  };
-
private static ExpenseDetailsUiBinder uiBinder = GWT.create(ExpenseDetailsUiBinder.class);

   @UiField
@@ -384,8 +379,12 @@

private List<SortableHeader> allHeaders = new ArrayList<SortableHeader>();

-  private SortableColumn<ExpenseRecord, String> approvalColumn;
-  private SortableColumn<ExpenseRecord, Date> createdColumn;
+  private Column<ExpenseRecord, String> approvalColumn;
+
+  /**
+   * The default {...@link Comparator} used for sorting.
+   */
+  private Comparator<ExpenseRecord> defaultComparator;

   /**
    * The popup used to display errors to the user.
@@ -542,7 +541,7 @@
     reportsLink.setText(ExpenseList.getBreadcrumb(department, employee));

     // Reset sorting state of table
-    lastComparator = createdColumn.getComparator(false);
+    lastComparator = defaultComparator;
     for (SortableHeader header : allHeaders) {
       header.setSorted(false);
       header.setReverseSort(true);
@@ -576,31 +575,51 @@
     });

     // Created column.
-    createdColumn = addColumn(view, "Created", new DateCell(
-        DateTimeFormat.getFormat("MMM dd yyyy")), createdGetter);
-    lastComparator = createdColumn.getComparator(false);
+ GetValue<ExpenseRecord, Date> createdGetter = new GetValue<ExpenseRecord, Date>() {
+      public Date getValue(ExpenseRecord object) {
+        return object.getCreated();
+      }
+    };
+    defaultComparator = createColumnComparator(createdGetter, false);
+    Comparator<ExpenseRecord> createdDesc = createColumnComparator(
+        createdGetter, true);
+    addColumn(view, "Created", new DateCell(
+        DateTimeFormat.getFormat("MMM dd yyyy")), createdGetter,
+        defaultComparator, createdDesc);
+    lastComparator = defaultComparator;

     // Description column.
-    addColumn(view, "Description", new GetValue<ExpenseRecord, String>() {
-      public String getValue(ExpenseRecord object) {
-        return object.getDescription();
-      }
-    });
+    addColumn(view, "Description", new TextCell(),
+        new GetValue<ExpenseRecord, String>() {
+          public String getValue(ExpenseRecord object) {
+            return object.getDescription();
+          }
+        });

     // Category column.
-    addColumn(view, "Category", new GetValue<ExpenseRecord, String>() {
-      public String getValue(ExpenseRecord object) {
-        return object.getCategory();
-      }
-    });
+    addColumn(view, "Category", new TextCell(),
+        new GetValue<ExpenseRecord, String>() {
+          public String getValue(ExpenseRecord object) {
+            return object.getCategory();
+          }
+        });

     // Amount column.
-    addColumn(view, "Amount", new CurrencyCell(),
-        new GetValue<ExpenseRecord, Integer>() {
-          public Integer getValue(ExpenseRecord object) {
-            return (int) (object.getAmount().doubleValue() * 100);
-          }
-        });
+ final GetValue<ExpenseRecord, Double> amountGetter = new GetValue<ExpenseRecord, Double>() {
+      public Double getValue(ExpenseRecord object) {
+        return object.getAmount();
+      }
+    };
+ Comparator<ExpenseRecord> amountAsc = createColumnComparator(amountGetter,
+        false);
+ Comparator<ExpenseRecord> amountDesc = createColumnComparator(amountGetter,
+        true);
+ addColumn(view, "Amount", new NumberCell(NumberFormat.getCurrencyFormat()),
+        new GetValue<ExpenseRecord, Number>() {
+          public Number getValue(ExpenseRecord object) {
+            return amountGetter.getValue(object);
+          }
+        }, amountAsc, amountDesc);

     // Dialog box to obtain a reason for a denial
     final DenialPopup denialPopup = new DenialPopup();
@@ -652,11 +671,43 @@
     return view;
   }

- private <C extends Comparable<C>> SortableColumn<ExpenseRecord, C> addColumn(
+  /**
+   * Add a column of a {...@link Comparable} type using default comparators.
+   *
+   * @param <C> the column type
+   * @param table the table
+   * @param text the header text
+   * @param cell the cell used to render values
+   * @param getter the {...@link GetValue} used to retrieve cell values
+   * @return the new column
+   */
+  private <C extends Comparable<C>> Column<ExpenseRecord, C> addColumn(
       final CellTable<ExpenseRecord> table, final String text,
       final Cell<C> cell, final GetValue<ExpenseRecord, C> getter) {
- final SortableColumn<ExpenseRecord, C> column = new SortableColumn<ExpenseRecord, C>(
-        cell) {
+ return addColumn(table, text, cell, getter, createColumnComparator(getter,
+        false), createColumnComparator(getter, true));
+  }
+
+  /**
+   * Add a column with the specified comparators.
+   *
+   * @param <C> the column type
+   * @param table the table
+   * @param text the header text
+   * @param cell the cell used to render values
+   * @param getter the {...@link GetValue} used to retrieve cell values
+   * @param ascComparator the comparator used to sort ascending
+   * @param descComparator the comparator used to sort ascending
+   * @return the new column
+   */
+  private <C> Column<ExpenseRecord, C> addColumn(
+      final CellTable<ExpenseRecord> table, final String text,
+      final Cell<C> cell, final GetValue<ExpenseRecord, C> getter,
+      final Comparator<ExpenseRecord> ascComparator,
+      final Comparator<ExpenseRecord> descComparator) {
+
+    // Create the column.
+ final Column<ExpenseRecord, C> column = new Column<ExpenseRecord, C>(cell) {
       @Override
       public C getValue(ExpenseRecord object) {
         return getter.getValue(object);
@@ -665,6 +716,7 @@
     final SortableHeader header = new SortableHeader(text);
     allHeaders.add(header);

+    // Hook up sorting.
     header.setUpdater(new ValueUpdater<String>() {
       public void update(String value) {
         header.setSorted(true);
@@ -676,8 +728,9 @@
             otherHeader.setReverseSort(true);
           }
         }
-        sortExpenses(items.getList(),
-            column.getComparator(header.getReverseSort()));
+
+ sortExpenses(items.getList(), header.getReverseSort() ? descComparator
+            : ascComparator);
         table.refreshHeaders();
       }
     });
@@ -685,10 +738,41 @@
     return column;
   }

-  private Column<ExpenseRecord, String> addColumn(
-      CellTable<ExpenseRecord> table, final String text,
-      final GetValue<ExpenseRecord, String> getter) {
-    return addColumn(table, text, new TextCell(), getter);
+  /**
+   * Create a comparator for the column.
+   *
+   * @param <C> the column type
+   * @param getter the {...@link GetValue} used to get the cell value
+   * @param descending true if descending, false if ascending
+   * @return the comparator
+   */
+ private <C extends Comparable<C>> Comparator<ExpenseRecord> createColumnComparator(
+      final GetValue<ExpenseRecord, C> getter, final boolean descending) {
+    return new Comparator<ExpenseRecord>() {
+      public int compare(ExpenseRecord o1, ExpenseRecord o2) {
+        // Null check the row object.
+        if (o1 == null && o2 == null) {
+          return 0;
+        } else if (o1 == null) {
+          return descending ? 1 : -1;
+        } else if (o2 == null) {
+          return descending ? -1 : 1;
+        }
+
+        // Compare the column value.
+        C c1 = getter.getValue(o1);
+        C c2 = getter.getValue(o2);
+        if (c1 == null && c2 == null) {
+          return 0;
+        } else if (c1 == null) {
+          return descending ? 1 : -1;
+        } else if (c2 == null) {
+          return descending ? -1 : 1;
+        }
+        int comparison = c1.compareTo(c2);
+        return descending ? -comparison : comparison;
+      }
+    };
   }

   /**

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

Reply via email to