com.google.gwt.sample.showcase.client.content.cell.CwCellSampler.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.sample.showcase.client.content.cell.CwCellSampler.java

Source

/*
 * 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.showcase.client.content.cell;

import com.google.gwt.cell.client.AbstractEditableCell;
import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.ClickableTextCell;
import com.google.gwt.cell.client.DateCell;
import com.google.gwt.cell.client.DatePickerCell;
import com.google.gwt.cell.client.EditTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.IconCellDecorator;
import com.google.gwt.cell.client.ImageCell;
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.TextInputCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.sample.showcase.client.ContentWidget;
import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseData;
import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseRaw;
import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseSource;
import com.google.gwt.sample.showcase.client.content.cell.ContactDatabase.Category;
import com.google.gwt.sample.showcase.client.content.cell.ContactDatabase.ContactInfo;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Widget;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Example file.
 */
@ShowcaseRaw({ "ContactDatabase.java", "CwCellSampler.ui.xml" })
public class CwCellSampler extends ContentWidget {

    /**
     * The UiBinder interface used by this example.
     */
    @ShowcaseSource
    interface Binder extends UiBinder<Widget, CwCellSampler> {
    }

    /**
     * The constants used in this Content Widget.
     */
    @ShowcaseSource
    public static interface CwConstants extends Constants {
        String cwCellSamplerDescription();

        String cwCellSamplerName();
    }

    /**
     * The images used for this example.
     */
    @ShowcaseSource
    static interface Images extends ClientBundle {
        ImageResource contactsGroup();
    }

    /**
     * Get a cell value from a record.
     * 
     * @param <C> the cell type
     */
    @ShowcaseSource
    private static interface GetValue<C> {
        C getValue(ContactInfo contact);
    }

    /**
     * A pending change to a {@link ContactInfo}. Changes aren't committed
     * immediately to illustrate that cells can remember their pending changes.
     * 
     * @param <T> the data type being changed
     */
    @ShowcaseSource
    private abstract static class PendingChange<T> {
        private final ContactInfo contact;
        private final T value;

        public PendingChange(ContactInfo contact, T value) {
            this.contact = contact;
            this.value = value;
        }

        /**
         * Commit the change to the contact.
         */
        public void commit() {
            doCommit(contact, value);
        }

        /**
         * Update the appropriate field in the {@link ContactInfo}.
         * 
         * @param contact the contact to update
         * @param value the new value
         */
        protected abstract void doCommit(ContactInfo contact, T value);
    }

    /**
     * Updates the birthday.
     */
    @ShowcaseSource
    private static class BirthdayChange extends PendingChange<Date> {

        public BirthdayChange(ContactInfo contact, Date value) {
            super(contact, value);
        }

        @Override
        protected void doCommit(ContactInfo contact, Date value) {
            contact.setBirthday(value);
        }
    }

    /**
     * Updates the category.
     */
    @ShowcaseSource
    private static class CategoryChange extends PendingChange<Category> {

        public CategoryChange(ContactInfo contact, Category value) {
            super(contact, value);
        }

        @Override
        protected void doCommit(ContactInfo contact, Category value) {
            contact.setCategory(value);
        }
    }

    /**
     * Updates the first name.
     */
    @ShowcaseSource
    private static class FirstNameChange extends PendingChange<String> {

        public FirstNameChange(ContactInfo contact, String value) {
            super(contact, value);
        }

        @Override
        protected void doCommit(ContactInfo contact, String value) {
            contact.setFirstName(value);
        }
    }

    /**
     * Updates the last name.
     */
    @ShowcaseSource
    private static class LastNameChange extends PendingChange<String> {

        public LastNameChange(ContactInfo contact, String value) {
            super(contact, value);
        }

        @Override
        protected void doCommit(ContactInfo contact, String value) {
            contact.setLastName(value);
        }
    }

    /**
     * The main CellTable.
     */
    @ShowcaseData
    @UiField(provided = true)
    DataGrid<ContactInfo> contactList;

    /**
     * The commit button.
     */
    @ShowcaseData
    @UiField
    Button commitButton;

    /**
     * The redraw button.
     */
    @ShowcaseData
    @UiField
    Button redrawButton;

    /**
     * The list of cells that are editable.
     */
    @ShowcaseData
    private List<AbstractEditableCell<?, ?>> editableCells;

    /**
     * The list of pending changes.
     */
    @ShowcaseData
    private List<PendingChange<?>> pendingChanges = new ArrayList<PendingChange<?>>();

    /**
     * Constructor.
     * 
     * @param constants the constants
     */
    public CwCellSampler(CwConstants constants) {
        super(constants.cwCellSamplerName(), constants.cwCellSamplerDescription(), false, "ContactDatabase.java",
                "CwCellSampler.ui.xml");
    }

    @Override
    public boolean hasMargins() {
        return false;
    }

    @Override
    public boolean hasScrollableContent() {
        return false;
    }

    /**
     * Initialize this example.
     */
    @ShowcaseSource
    @Override
    public Widget onInitialize() {
        Images images = GWT.create(Images.class);

        // Create the table.
        editableCells = new ArrayList<AbstractEditableCell<?, ?>>();
        contactList = new DataGrid<ContactInfo>(25, ContactInfo.KEY_PROVIDER);
        contactList.setMinimumTableWidth(140, Unit.EM);
        ContactDatabase.get().addDataDisplay(contactList);

        // CheckboxCell.
        final Category[] categories = ContactDatabase.get().queryCategories();
        addColumn(new CheckboxCell(), "Checkbox", new GetValue<Boolean>() {
            @Override
            public Boolean getValue(ContactInfo contact) {
                // Checkbox indicates that the contact is a relative.
                // Index 0 = Family.
                return contact.getCategory() == categories[0];
            }
        }, new FieldUpdater<ContactInfo, Boolean>() {
            @Override
            public void update(int index, ContactInfo object, Boolean value) {
                if (value) {
                    // If a relative, use the Family Category.
                    pendingChanges.add(new CategoryChange(object, categories[0]));
                } else {
                    // If not a relative, use the Contacts Category.
                    pendingChanges.add(new CategoryChange(object, categories[categories.length - 1]));
                }
            }
        });

        // TextCell.
        addColumn(new TextCell(), "Text", new GetValue<String>() {
            @Override
            public String getValue(ContactInfo contact) {
                return contact.getFullName();
            }
        }, null);

        // EditTextCell.
        Column<ContactInfo, String> editTextColumn = addColumn(new EditTextCell(), "EditText",
                new GetValue<String>() {
                    @Override
                    public String getValue(ContactInfo contact) {
                        return contact.getFirstName();
                    }
                }, new FieldUpdater<ContactInfo, String>() {
                    @Override
                    public void update(int index, ContactInfo object, String value) {
                        pendingChanges.add(new FirstNameChange(object, value));
                    }
                });
        contactList.setColumnWidth(editTextColumn, 16.0, Unit.EM);

        // TextInputCell.
        Column<ContactInfo, String> textInputColumn = addColumn(new TextInputCell(), "TextInput",
                new GetValue<String>() {
                    @Override
                    public String getValue(ContactInfo contact) {
                        return contact.getLastName();
                    }
                }, new FieldUpdater<ContactInfo, String>() {
                    @Override
                    public void update(int index, ContactInfo object, String value) {
                        pendingChanges.add(new LastNameChange(object, value));
                    }
                });
        contactList.setColumnWidth(textInputColumn, 16.0, Unit.EM);

        // ClickableTextCell.
        addColumn(new ClickableTextCell(), "ClickableText", new GetValue<String>() {
            @Override
            public String getValue(ContactInfo contact) {
                return "Click " + contact.getFirstName();
            }
        }, new FieldUpdater<ContactInfo, String>() {
            @Override
            public void update(int index, ContactInfo object, String value) {
                Window.alert("You clicked " + object.getFullName());
            }
        });

        // ActionCell.
        addColumn(new ActionCell<ContactInfo>("Click Me", new ActionCell.Delegate<ContactInfo>() {
            @Override
            public void execute(ContactInfo contact) {
                Window.alert("You clicked " + contact.getFullName());
            }
        }), "Action", new GetValue<ContactInfo>() {
            @Override
            public ContactInfo getValue(ContactInfo contact) {
                return contact;
            }
        }, null);

        // ButtonCell.
        addColumn(new ButtonCell(), "Button", new GetValue<String>() {
            @Override
            public String getValue(ContactInfo contact) {
                return "Click " + contact.getFirstName();
            }
        }, new FieldUpdater<ContactInfo, String>() {
            @Override
            public void update(int index, ContactInfo object, String value) {
                Window.alert("You clicked " + object.getFullName());
            }
        });

        // DateCell.
        DateTimeFormat dateFormat = DateTimeFormat.getFormat(PredefinedFormat.DATE_MEDIUM);
        addColumn(new DateCell(dateFormat), "Date", new GetValue<Date>() {
            @Override
            public Date getValue(ContactInfo contact) {
                return contact.getBirthday();
            }
        }, null);

        // DatePickerCell.
        addColumn(new DatePickerCell(dateFormat), "DatePicker", new GetValue<Date>() {
            @Override
            public Date getValue(ContactInfo contact) {
                return contact.getBirthday();
            }
        }, new FieldUpdater<ContactInfo, Date>() {
            @Override
            public void update(int index, ContactInfo object, Date value) {
                pendingChanges.add(new BirthdayChange(object, value));
            }
        });

        // NumberCell.
        Column<ContactInfo, Number> numberColumn = addColumn(new NumberCell(), "Number", new GetValue<Number>() {
            @Override
            public Number getValue(ContactInfo contact) {
                return contact.getAge();
            }
        }, null);
        numberColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LOCALE_END);

        // IconCellDecorator.
        addColumn(new IconCellDecorator<String>(images.contactsGroup(), new TextCell()), "Icon",
                new GetValue<String>() {
                    @Override
                    public String getValue(ContactInfo contact) {
                        return contact.getCategory().getDisplayName();
                    }
                }, null);

        // ImageCell.
        addColumn(new ImageCell(), "Image", new GetValue<String>() {
            @Override
            public String getValue(ContactInfo contact) {
                return "contact.jpg";
            }
        }, null);

        // SelectionCell.
        List<String> options = new ArrayList<String>();
        for (Category category : categories) {
            options.add(category.getDisplayName());
        }
        addColumn(new SelectionCell(options), "Selection", new GetValue<String>() {
            @Override
            public String getValue(ContactInfo contact) {
                return contact.getCategory().getDisplayName();
            }
        }, new FieldUpdater<ContactInfo, String>() {
            @Override
            public void update(int index, ContactInfo object, String value) {
                for (Category category : categories) {
                    if (category.getDisplayName().equals(value)) {
                        pendingChanges.add(new CategoryChange(object, category));
                        break;
                    }
                }
            }
        });

        // Create the UiBinder.
        Binder uiBinder = GWT.create(Binder.class);
        Widget widget = uiBinder.createAndBindUi(this);

        // Add handlers to redraw or refresh the table.
        redrawButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                contactList.redraw();
            }
        });
        commitButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                // Commit the changes.
                for (PendingChange<?> pendingChange : pendingChanges) {
                    pendingChange.commit();
                }
                pendingChanges.clear();

                // Push the changes to the views.
                ContactDatabase.get().refreshDisplays();
            }
        });

        return widget;
    }

    @Override
    protected void asyncOnInitialize(final AsyncCallback<Widget> callback) {
        GWT.runAsync(CwCellSampler.class, new RunAsyncCallback() {

            @Override
            public void onFailure(Throwable caught) {
                callback.onFailure(caught);
            }

            @Override
            public void onSuccess() {
                callback.onSuccess(onInitialize());
            }
        });
    }

    /**
     * Add a column with a header.
     * 
     * @param <C> the cell type
     * @param cell the cell used to render the column
     * @param headerText the header string
     * @param getter the value getter for the cell
     */
    @ShowcaseSource
    private <C> Column<ContactInfo, C> addColumn(Cell<C> cell, String headerText, final GetValue<C> getter,
            FieldUpdater<ContactInfo, C> fieldUpdater) {
        Column<ContactInfo, C> column = new Column<ContactInfo, C>(cell) {
            @Override
            public C getValue(ContactInfo object) {
                return getter.getValue(object);
            }
        };
        column.setFieldUpdater(fieldUpdater);
        if (cell instanceof AbstractEditableCell<?, ?>) {
            editableCells.add((AbstractEditableCell<?, ?>) cell);
        }
        contactList.addColumn(column, headerText);
        return column;
    }
}