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 ""; + } +}