1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 package com.google.gwt.sample.showcase.client.content.cell;
17 
18 import com.google.gwt.cell.client.CheckboxCell;
19 import com.google.gwt.cell.client.EditTextCell;
20 import com.google.gwt.cell.client.FieldUpdater;
21 import com.google.gwt.cell.client.NumberCell;
22 import com.google.gwt.cell.client.SelectionCell;
23 import com.google.gwt.cell.client.TextCell;
24 import com.google.gwt.core.client.GWT;
25 import com.google.gwt.core.client.RunAsyncCallback;
26 import com.google.gwt.dom.client.Style.Unit;
27 import com.google.gwt.i18n.client.Constants;
28 import com.google.gwt.safehtml.shared.SafeHtmlUtils;
29 import com.google.gwt.sample.showcase.client.ContentWidget;
30 import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseData;
31 import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseRaw;
32 import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseSource;
33 import com.google.gwt.sample.showcase.client.content.cell.ContactDatabase.Category;
34 import com.google.gwt.sample.showcase.client.content.cell.ContactDatabase.ContactInfo;
35 import com.google.gwt.uibinder.client.UiBinder;
36 import com.google.gwt.uibinder.client.UiField;
37 import com.google.gwt.user.cellview.client.Column;
38 import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
39 import com.google.gwt.user.cellview.client.DataGrid;
40 import com.google.gwt.user.cellview.client.Header;
41 import com.google.gwt.user.cellview.client.SafeHtmlHeader;
42 import com.google.gwt.user.cellview.client.SimplePager;
43 import com.google.gwt.user.cellview.client.SimplePager.TextLocation;
44 import com.google.gwt.user.client.rpc.AsyncCallback;
45 import com.google.gwt.user.client.ui.Label;
46 import com.google.gwt.user.client.ui.Widget;
47 import com.google.gwt.view.client.DefaultSelectionEventManager;
48 import com.google.gwt.view.client.MultiSelectionModel;
49 import com.google.gwt.view.client.SelectionModel;
50 
51 import java.util.ArrayList;
52 import java.util.Comparator;
53 import java.util.List;
54 
55 /**
56  * Example file.
57  */
58 @ShowcaseRaw({"ContactDatabase.java", "CwDataGrid.ui.xml"})
59 public class CwDataGrid extends ContentWidget {
60 
61   /**
62    * The UiBinder interface used by this example.
63    */
64   @ShowcaseSource
65   interface Binder extends UiBinder<Widget, CwDataGrid> {
66   }
67 
68   /**
69    * The constants used in this Content Widget.
70    */
71   @ShowcaseSource
72   public static interface CwConstants extends Constants {
cwDataGridColumnAddress()73     String cwDataGridColumnAddress();
74 
cwDataGridColumnAge()75     String cwDataGridColumnAge();
76 
cwDataGridColumnCategory()77     String cwDataGridColumnCategory();
78 
cwDataGridColumnFirstName()79     String cwDataGridColumnFirstName();
80 
cwDataGridColumnLastName()81     String cwDataGridColumnLastName();
82 
cwDataGridDescription()83     String cwDataGridDescription();
84 
cwDataGridEmpty()85     String cwDataGridEmpty();
86 
cwDataGridName()87     String cwDataGridName();
88   }
89 
90   /**
91    * The main DataGrid.
92    */
93   @ShowcaseData
94   @UiField(provided = true)
95   DataGrid<ContactInfo> dataGrid;
96 
97   /**
98    * The pager used to change the range of data.
99    */
100   @ShowcaseData
101   @UiField(provided = true)
102   SimplePager pager;
103 
104   /**
105    * An instance of the constants.
106    */
107   @ShowcaseData
108   private final CwConstants constants;
109 
110   /**
111    * Constructor.
112    *
113    * @param constants the constants
114    */
CwDataGrid(CwConstants constants)115   public CwDataGrid(CwConstants constants) {
116     super(constants.cwDataGridName(), constants.cwDataGridDescription(), false,
117         "ContactDatabase.java", "CwDataGrid.ui.xml");
118     this.constants = constants;
119   }
120 
121   @Override
hasMargins()122   public boolean hasMargins() {
123     return false;
124   }
125 
126   @Override
hasScrollableContent()127   public boolean hasScrollableContent() {
128     return false;
129   }
130 
131   /**
132    * Initialize this example.
133    */
134   @ShowcaseSource
135   @Override
onInitialize()136   public Widget onInitialize() {
137     // Create a DataGrid.
138 
139     /*
140      * Set a key provider that provides a unique key for each contact. If key is
141      * used to identify contacts when fields (such as the name and address)
142      * change.
143      */
144     dataGrid = new DataGrid<ContactInfo>(ContactDatabase.ContactInfo.KEY_PROVIDER);
145     dataGrid.setWidth("100%");
146 
147     /*
148      * Do not refresh the headers every time the data is updated. The footer
149      * depends on the current data, so we do not disable auto refresh on the
150      * footer.
151      */
152     dataGrid.setAutoHeaderRefreshDisabled(true);
153 
154     // Set the message to display when the table is empty.
155     dataGrid.setEmptyTableWidget(new Label(constants.cwDataGridEmpty()));
156 
157     // Attach a column sort handler to the ListDataProvider to sort the list.
158     ListHandler<ContactInfo> sortHandler =
159         new ListHandler<ContactInfo>(ContactDatabase.get().getDataProvider().getList());
160     dataGrid.addColumnSortHandler(sortHandler);
161 
162     // Create a Pager to control the table.
163     SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
164     pager = new SimplePager(TextLocation.CENTER, pagerResources, false, 0, true);
165     pager.setDisplay(dataGrid);
166 
167     // Add a selection model so we can select cells.
168     final SelectionModel<ContactInfo> selectionModel =
169         new MultiSelectionModel<ContactInfo>(ContactDatabase.ContactInfo.KEY_PROVIDER);
170     dataGrid.setSelectionModel(selectionModel, DefaultSelectionEventManager
171         .<ContactInfo> createCheckboxManager());
172 
173     // Initialize the columns.
174     initTableColumns(selectionModel, sortHandler);
175 
176     // Add the CellList to the adapter in the database.
177     ContactDatabase.get().addDataDisplay(dataGrid);
178 
179     // Create the UiBinder.
180     Binder uiBinder = GWT.create(Binder.class);
181     return uiBinder.createAndBindUi(this);
182   }
183 
184   @Override
asyncOnInitialize(final AsyncCallback<Widget> callback)185   protected void asyncOnInitialize(final AsyncCallback<Widget> callback) {
186     GWT.runAsync(CwDataGrid.class, new RunAsyncCallback() {
187 
188       @Override
189       public void onFailure(Throwable caught) {
190         callback.onFailure(caught);
191       }
192 
193       @Override
194       public void onSuccess() {
195         callback.onSuccess(onInitialize());
196       }
197     });
198   }
199 
200   /**
201    * Add the columns to the table.
202    */
203   @ShowcaseSource
initTableColumns(final SelectionModel<ContactInfo> selectionModel, ListHandler<ContactInfo> sortHandler)204   private void initTableColumns(final SelectionModel<ContactInfo> selectionModel,
205       ListHandler<ContactInfo> sortHandler) {
206     // Checkbox column. This table will uses a checkbox column for selection.
207     // Alternatively, you can call dataGrid.setSelectionEnabled(true) to enable
208     // mouse selection.
209     Column<ContactInfo, Boolean> checkColumn =
210         new Column<ContactInfo, Boolean>(new CheckboxCell(true, false)) {
211           @Override
212           public Boolean getValue(ContactInfo object) {
213             // Get the value from the selection model.
214             return selectionModel.isSelected(object);
215           }
216         };
217     dataGrid.addColumn(checkColumn, SafeHtmlUtils.fromSafeConstant("<br/>"));
218     dataGrid.setColumnWidth(checkColumn, 40, Unit.PX);
219 
220     // First name.
221     Column<ContactInfo, String> firstNameColumn =
222         new Column<ContactInfo, String>(new EditTextCell()) {
223           @Override
224           public String getValue(ContactInfo object) {
225             return object.getFirstName();
226           }
227         };
228     firstNameColumn.setSortable(true);
229     sortHandler.setComparator(firstNameColumn, new Comparator<ContactInfo>() {
230       @Override
231       public int compare(ContactInfo o1, ContactInfo o2) {
232         return o1.getFirstName().compareTo(o2.getFirstName());
233       }
234     });
235     dataGrid.addColumn(firstNameColumn, constants.cwDataGridColumnFirstName());
236     firstNameColumn.setFieldUpdater(new FieldUpdater<ContactInfo, String>() {
237       @Override
238       public void update(int index, ContactInfo object, String value) {
239         // Called when the user changes the value.
240         object.setFirstName(value);
241         ContactDatabase.get().refreshDisplays();
242       }
243     });
244     dataGrid.setColumnWidth(firstNameColumn, 20, Unit.PCT);
245 
246     // Last name.
247     Column<ContactInfo, String> lastNameColumn =
248         new Column<ContactInfo, String>(new EditTextCell()) {
249           @Override
250           public String getValue(ContactInfo object) {
251             return object.getLastName();
252           }
253         };
254     lastNameColumn.setSortable(true);
255     sortHandler.setComparator(lastNameColumn, new Comparator<ContactInfo>() {
256       @Override
257       public int compare(ContactInfo o1, ContactInfo o2) {
258         return o1.getLastName().compareTo(o2.getLastName());
259       }
260     });
261     dataGrid.addColumn(lastNameColumn, constants.cwDataGridColumnLastName());
262     lastNameColumn.setFieldUpdater(new FieldUpdater<ContactInfo, String>() {
263       @Override
264       public void update(int index, ContactInfo object, String value) {
265         // Called when the user changes the value.
266         object.setLastName(value);
267         ContactDatabase.get().refreshDisplays();
268       }
269     });
270     dataGrid.setColumnWidth(lastNameColumn, 20, Unit.PCT);
271 
272     // Age.
273     Column<ContactInfo, Number> ageColumn = new Column<ContactInfo, Number>(new NumberCell()) {
274       @Override
275       public Number getValue(ContactInfo object) {
276         return object.getAge();
277       }
278     };
279     ageColumn.setSortable(true);
280     sortHandler.setComparator(ageColumn, new Comparator<ContactInfo>() {
281       @Override
282       public int compare(ContactInfo o1, ContactInfo o2) {
283         return o1.getBirthday().compareTo(o2.getBirthday());
284       }
285     });
286     Header<String> ageFooter = new Header<String>(new TextCell()) {
287       @Override
288       public String getValue() {
289         List<ContactInfo> items = dataGrid.getVisibleItems();
290         if (items.size() == 0) {
291           return "";
292         } else {
293           int totalAge = 0;
294           for (ContactInfo item : items) {
295             totalAge += item.getAge();
296           }
297           return "Avg: " + totalAge / items.size();
298         }
299       }
300     };
301     dataGrid.addColumn(ageColumn, new SafeHtmlHeader(SafeHtmlUtils.fromSafeConstant(constants
302         .cwDataGridColumnAge())), ageFooter);
303     dataGrid.setColumnWidth(ageColumn, 7, Unit.EM);
304 
305     // Category.
306     final Category[] categories = ContactDatabase.get().queryCategories();
307     List<String> categoryNames = new ArrayList<String>();
308     for (Category category : categories) {
309       categoryNames.add(category.getDisplayName());
310     }
311     SelectionCell categoryCell = new SelectionCell(categoryNames);
312     Column<ContactInfo, String> categoryColumn = new Column<ContactInfo, String>(categoryCell) {
313       @Override
314       public String getValue(ContactInfo object) {
315         return object.getCategory().getDisplayName();
316       }
317     };
318     dataGrid.addColumn(categoryColumn, constants.cwDataGridColumnCategory());
319     categoryColumn.setFieldUpdater(new FieldUpdater<ContactInfo, String>() {
320       @Override
321       public void update(int index, ContactInfo object, String value) {
322         for (Category category : categories) {
323           if (category.getDisplayName().equals(value)) {
324             object.setCategory(category);
325           }
326         }
327         ContactDatabase.get().refreshDisplays();
328       }
329     });
330     dataGrid.setColumnWidth(categoryColumn, 130, Unit.PX);
331 
332     // Address.
333     Column<ContactInfo, String> addressColumn = new Column<ContactInfo, String>(new TextCell()) {
334       @Override
335       public String getValue(ContactInfo object) {
336         return object.getAddress();
337       }
338     };
339     addressColumn.setSortable(true);
340     sortHandler.setComparator(addressColumn, new Comparator<ContactInfo>() {
341       @Override
342       public int compare(ContactInfo o1, ContactInfo o2) {
343         return o1.getAddress().compareTo(o2.getAddress());
344       }
345     });
346     dataGrid.addColumn(addressColumn, constants.cwDataGridColumnAddress());
347     dataGrid.setColumnWidth(addressColumn, 60, Unit.PCT);
348   }
349 }
350