gwtquery.plugins.droppable.client.celltablesample.CellTableSample.java Source code

Java tutorial

Introduction

Here is the source code for gwtquery.plugins.droppable.client.celltablesample.CellTableSample.java

Source

/*
 * Copyright 2010 The gwtquery plugins team.
 * 
 * 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 gwtquery.plugins.droppable.client.celltablesample;

import static com.google.gwt.query.client.GQuery.$;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.EditTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.SelectionCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Cursor;
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.resources.client.ImageResource;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.HasKeyboardPagingPolicy.KeyboardPagingPolicy;
import com.google.gwt.user.cellview.client.SimplePager.TextLocation;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.SelectionModel;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import gwtquery.plugins.draggable.client.DraggableOptions;
import gwtquery.plugins.draggable.client.DraggableOptions.RevertOption;
import gwtquery.plugins.draggable.client.events.DragStartEvent;
import gwtquery.plugins.draggable.client.events.DragStartEvent.DragStartEventHandler;
import gwtquery.plugins.droppable.client.celltablesample.ContactDatabase.Category;
import gwtquery.plugins.droppable.client.celltablesample.ContactDatabase.ContactInfo;
import gwtquery.plugins.droppable.client.events.DropEvent;
import gwtquery.plugins.droppable.client.events.DropEvent.DropEventHandler;
import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTable;
import gwtquery.plugins.droppable.client.gwt.DragAndDropColumn;
import gwtquery.plugins.droppable.client.gwt.DroppableWidget;

/**
 * Take the cell table example of the GWT showcase and make all cell droppable
 * and draggable
 * 
 * @author Julien Dramaix (julien.dramaix@gmail.com)
 * 
 */
public class CellTableSample implements EntryPoint {

    /**
     * The constants used in this Content Widget.
     */
    public static interface CwConstants extends Constants {
        @DefaultStringValue(value = "Address")
        String cwCellTableColumnAddress();

        @DefaultStringValue(value = "Category")
        String cwCellTableColumnCategory();

        @DefaultStringValue(value = "First Name")
        String cwCellTableColumnFirstName();

        @DefaultStringValue(value = "Last Name")
        String cwCellTableColumnLastName();

    }

    interface CellTableSampleUiBinder extends UiBinder<Widget, CellTableSample> {
    }

    /**
     * Template for the helper
     * 
     * @author Julien Dramaix (julien.dramaix@gmail.com)
     * 
     */
    static interface Templates extends SafeHtmlTemplates {
        Templates INSTANCE = GWT.create(Templates.class);

        @Template("<div id='dragHelper' style='border:1px solid black; background-color:#ffffff; color:black; width:150px;'></div>")
        SafeHtml outerHelper();
    }

    /**
     * The Cell used to render a {@link ContactInfo}.
     * 
     * Code coming from the GWT showcase
     * 
     */
    private static class ContactCell extends AbstractCell<ContactInfo> {

        /**
         * The html of the image used for contacts.
         * 
         */
        private final String imageHtml;

        public ContactCell(ImageResource image) {
            this.imageHtml = AbstractImagePrototype.create(image).getHTML();
        }

        @Override
        public void render(Context context, ContactInfo value, SafeHtmlBuilder sb) {
            // Value can be null, so do a null check..
            if (value == null) {
                return;
            }

            sb.appendHtmlConstant("<table>");

            // Add the contact image.
            sb.appendHtmlConstant("<tr><td rowspan='3'>");
            sb.appendHtmlConstant(imageHtml);
            sb.appendHtmlConstant("</td>");

            // Add the name and address.
            sb.appendHtmlConstant("<td style='font-size:95%;'>");
            sb.appendEscaped(value.getFullName());
            sb.appendHtmlConstant("</td></tr><tr><td>");
            sb.appendEscaped(value.getAddress());
            sb.appendHtmlConstant("</td></tr></table>");

        }
    }

    private static CellTableSampleUiBinder uiBinder = GWT.create(CellTableSampleUiBinder.class);

    /**
     * The main CellTable. Use a {@link DragAndDropCellTable} instead of a
     * {@link CellTable}
     */
    @UiField(provided = true)
    DragAndDropCellTable<ContactInfo> cellTable;

    /**
     * The delete button
     */
    @UiField(provided = true)
    Button deleteButton;

    /**
     * The droppable "contact to delete" cell list.
     */
    @UiField(provided = true)
    DroppableWidget<CellList<ContactInfo>> exportCellList;

    /**
     * The pager used to change the range of data.
     */
    @UiField(provided = true)
    SimplePager pager;

    /**
     * The undo button
     */
    @UiField(provided = true)
    Button undoButton;

    /**
     * An instance of the constants.
     */
    private final CwConstants constants;

    public CellTableSample() {
        constants = GWT.create(CwConstants.class);
    }

    /**
     * Initialize this example.
     */
    public void onModuleLoad() {
        Resource.INSTANCE.css().ensureInjected();

        createDragAndDropCellTable();
        createDroppableList();

        // Create the UiBinder.
        Widget w = uiBinder.createAndBindUi(this);
        RootPanel.get("sample").add(w);
    }

    /**
     * This method create the CellTable for the contacts
     */
    private void createDragAndDropCellTable() {

        // Create a DragAndDropCellTable.
        cellTable = new DragAndDropCellTable<ContactInfo>(ContactDatabase.ContactInfo.KEY_PROVIDER);
        // Create a Pager to control the table.
        SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
        pager = new SimplePager(TextLocation.CENTER, pagerResources, false, 0, true);
        pager.setDisplay(cellTable);

        // Add a selection model so we can select cells.
        final MultiSelectionModel<ContactInfo> selectionModel = new MultiSelectionModel<ContactInfo>(
                ContactDatabase.ContactInfo.KEY_PROVIDER);
        cellTable.setSelectionModel(selectionModel);

        // Attach a column sort handler to the ListDataProvider to sort the list.
        ListHandler<ContactInfo> sortHandler = new ListHandler<ContactInfo>(
                ContactDatabase.get().getDataProvider().getList());
        cellTable.addColumnSortHandler(sortHandler);

        // Initialize the columns.
        initTableColumns(selectionModel, sortHandler);

        // Add the CellList to the adapter in the database.
        ContactDatabase.get().addDataDisplay(cellTable);

        // fill the helper when the drag operation start
        cellTable.addDragStartHandler(new DragStartEventHandler() {

            public void onDragStart(DragStartEvent event) {
                ContactInfo contact = event.getDraggableData();
                Element helper = event.getHelper();
                SafeHtmlBuilder sb = new SafeHtmlBuilder();
                // reuse the contact cell to render the inner html of the drag helper.
                new ContactCell(Resource.INSTANCE.contact()).render(null, contact, sb);
                helper.setInnerHTML(sb.toSafeHtml().asString());

            }
        });

    }

    /**
     * Create a droppable CellList
     */
    private void createDroppableList() {
        // Create a ConcactCell
        ContactCell contactCell = new ContactCell(Resource.INSTANCE.contact());

        CellList<ContactInfo> cellList = new CellList<ContactInfo>(contactCell,
                ContactDatabase.ContactInfo.KEY_PROVIDER);
        cellList.addStyleName(Resource.INSTANCE.css().exportCellList());

        cellList.setPageSize(30);
        cellList.setKeyboardPagingPolicy(KeyboardPagingPolicy.INCREASE_RANGE);
        // temporary ListDataProvider to keep list of contacts to delete
        final ListDataProvider<ContactInfo> deleteContactList = new ListDataProvider<ContactInfo>();
        deleteContactList.addDataDisplay(cellList);

        // make the cell list droppable.
        exportCellList = new DroppableWidget<CellList<ContactInfo>>(cellList);

        // setup the drop operation
        exportCellList.setDroppableHoverClass(Resource.INSTANCE.css().droppableHover());
        exportCellList.setActiveClass(Resource.INSTANCE.css().droppableActive());
        exportCellList.addDropHandler(new DropEventHandler() {

            public void onDrop(DropEvent event) {
                ContactInfo contactToDelete = event.getDraggableData();
                // first remove the contact to the table
                ContactDatabase.get().removeContact(contactToDelete);
                // avoid doublon
                deleteContactList.getList().remove(contactToDelete);
                // add the contact to the delete list
                deleteContactList.getList().add(contactToDelete);

            }
        });

        // create delete button
        deleteButton = new Button("Delete contacts");
        deleteButton.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                deleteContactList.getList().clear();
                Window.alert("The contacts have been deleted");
            }
        });

        // create undo button
        undoButton = new Button("Undo");
        undoButton.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                for (ContactInfo c : deleteContactList.getList()) {
                    ContactDatabase.get().addContact(c);
                }
                deleteContactList.getList().clear();
            }
        });
    }

    /**
     * Init draggable operation for column
     * 
     * @param draggableOptions
     */
    private void initDragOperation(DragAndDropColumn<?, ?> column) {

        // retrieve draggableOptions on the column
        DraggableOptions draggableOptions = column.getDraggableOptions();
        // use template to construct the helper. The content of the div will be set
        // after
        draggableOptions.setHelper($(Templates.INSTANCE.outerHelper().asString()));
        // opacity of the helper
        draggableOptions.setOpacity((float) 0.8);
        // cursor to use during the drag operation
        draggableOptions.setCursor(Cursor.MOVE);
        // set the revert option
        draggableOptions.setRevert(RevertOption.ON_INVALID_DROP);
        // prevents dragging when user click on the category drop-down list
        draggableOptions.setCancel("select");
    }

    /**
     * Add the columns to the table.
     * 
     * Use {@link DragAndDropColumn} instead of {@link Column}
     * @param sortHandler 
     */
    private void initTableColumns(final SelectionModel<ContactInfo> selectionModel,
            ListHandler<ContactInfo> sortHandler) {

        DragAndDropColumn<ContactInfo, Boolean> checkColumn = new DragAndDropColumn<ContactInfo, Boolean>(
                new CheckboxCell(true, true)) {
            @Override
            public Boolean getValue(ContactInfo object) {
                // Get the value from the selection model.
                return selectionModel.isSelected(object);
            }
        };
        checkColumn.setFieldUpdater(new FieldUpdater<ContactInfo, Boolean>() {
            public void update(int index, ContactInfo object, Boolean value) {
                // Called when the user clicks on a checkbox.
                selectionModel.setSelected(object, value);
            }
        });
        checkColumn.setCellDraggableOnly();
        initDragOperation(checkColumn);
        cellTable.addColumn(checkColumn, SafeHtmlUtils.fromSafeConstant("<br>"));

        // First name.
        DragAndDropColumn<ContactInfo, String> firstNameColumn = new DragAndDropColumn<ContactInfo, String>(
                new EditTextCell()) {
            @Override
            public String getValue(ContactInfo object) {
                return object.getFirstName();
            }
        };
        firstNameColumn.setCellDraggableOnly();
        firstNameColumn.setSortable(true);
        sortHandler.setComparator(firstNameColumn, new Comparator<ContactInfo>() {
            public int compare(ContactInfo o1, ContactInfo o2) {
                return o1.getFirstName().compareTo(o2.getFirstName());
            }
        });

        initDragOperation(firstNameColumn);
        cellTable.addColumn(firstNameColumn, constants.cwCellTableColumnFirstName());
        firstNameColumn.setFieldUpdater(new FieldUpdater<ContactInfo, String>() {
            public void update(int index, ContactInfo object, String value) {
                // Called when the user changes the value.
                object.setFirstName(value);
                ContactDatabase.get().refreshDisplays();
            }
        });

        // Last name.
        DragAndDropColumn<ContactInfo, String> lastNameColumn = new DragAndDropColumn<ContactInfo, String>(
                new EditTextCell()) {
            @Override
            public String getValue(ContactInfo object) {
                return object.getLastName();
            }
        };
        lastNameColumn.setCellDraggableOnly();
        lastNameColumn.setSortable(true);
        sortHandler.setComparator(lastNameColumn, new Comparator<ContactInfo>() {
            public int compare(ContactInfo o1, ContactInfo o2) {
                return o1.getLastName().compareTo(o2.getLastName());
            }
        });

        initDragOperation(lastNameColumn);
        cellTable.addColumn(lastNameColumn, constants.cwCellTableColumnLastName());
        lastNameColumn.setFieldUpdater(new FieldUpdater<ContactInfo, String>() {
            public void update(int index, ContactInfo object, String value) {
                // Called when the user changes the value.
                object.setLastName(value);
                ContactDatabase.get().refreshDisplays();
            }
        });

        // Category.
        final Category[] categories = ContactDatabase.get().queryCategories();
        List<String> categoryNames = new ArrayList<String>();
        for (Category category : categories) {
            categoryNames.add(category.getDisplayName());
        }
        SelectionCell categoryCell = new SelectionCell(categoryNames);
        DragAndDropColumn<ContactInfo, String> categoryColumn = new DragAndDropColumn<ContactInfo, String>(
                categoryCell) {
            @Override
            public String getValue(ContactInfo object) {
                return object.getCategory().getDisplayName();
            }
        };
        categoryColumn.setCellDraggableOnly();
        initDragOperation(categoryColumn);
        cellTable.addColumn(categoryColumn, constants.cwCellTableColumnCategory());
        categoryColumn.setFieldUpdater(new FieldUpdater<ContactInfo, String>() {
            public void update(int index, ContactInfo object, String value) {
                for (Category category : categories) {
                    if (category.getDisplayName().equals(value)) {
                        object.setCategory(category);
                    }
                }
                ContactDatabase.get().refreshDisplays();
            }
        });

        // Address.
        DragAndDropColumn<ContactInfo, String> addressColumn = new DragAndDropColumn<ContactInfo, String>(
                new TextCell()) {
            @Override
            public String getValue(ContactInfo object) {
                return object.getAddress();
            }
        };
        cellTable.addColumn(addressColumn, constants.cwCellTableColumnAddress());
        addressColumn.setCellDraggableOnly();
        initDragOperation(addressColumn);
    }

}