Replacing CurrencyCell with generic NumberCell that uses NumberFormat.
Review at http://gwt-code-reviews.appspot.com/568801
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8240 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gwt/ExpensesCommon.gwt.xml b/bikeshed/src/com/google/gwt/sample/expenses/gwt/ExpensesCommon.gwt.xml
index ebac66c..6987344 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/gwt/ExpensesCommon.gwt.xml
+++ b/bikeshed/src/com/google/gwt/sample/expenses/gwt/ExpensesCommon.gwt.xml
@@ -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>
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/ExpenseDetails.java b/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/ExpenseDetails.java
index ef3b856..0ffda82 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/ExpenseDetails.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/ExpenseDetails.java
@@ -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,32 +575,52 @@
});
// 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();
- }
- });
-
- // Category column.
- addColumn(view, "Category", 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);
+ addColumn(view, "Description", new TextCell(),
+ new GetValue<ExpenseRecord, String>() {
+ public String getValue(ExpenseRecord object) {
+ return object.getDescription();
}
});
+ // Category column.
+ addColumn(view, "Category", new TextCell(),
+ new GetValue<ExpenseRecord, String>() {
+ public String getValue(ExpenseRecord object) {
+ return object.getCategory();
+ }
+ });
+
+ // Amount column.
+ 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();
denialPopup.addCloseHandler(new CloseHandler<PopupPanel>() {
@@ -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;
+ }
+ };
}
/**
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/SortableColumn.java b/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/SortableColumn.java
deleted file mode 100644
index 42db8c2..0000000
--- a/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/SortableColumn.java
+++ /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;
- }
-}
diff --git a/user/src/com/google/gwt/cell/client/CurrencyCell.java b/user/src/com/google/gwt/cell/client/CurrencyCell.java
deleted file mode 100644
index a0c9464..0000000
--- a/user/src/com/google/gwt/cell/client/CurrencyCell.java
+++ /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);
- }
-}
diff --git a/user/src/com/google/gwt/cell/client/NumberCell.java b/user/src/com/google/gwt/cell/client/NumberCell.java
new file mode 100644
index 0000000..5888c0e
--- /dev/null
+++ b/user/src/com/google/gwt/cell/client/NumberCell.java
@@ -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));
+ }
+ }
+}
diff --git a/user/test/com/google/gwt/cell/client/NumberCellTest.java b/user/test/com/google/gwt/cell/client/NumberCellTest.java
new file mode 100644
index 0000000..543a5fe
--- /dev/null
+++ b/user/test/com/google/gwt/cell/client/NumberCellTest.java
@@ -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 "";
+ }
+}