com.googlecode.mgwt.ui.client.widget.list.celllist.GroupingCellList.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.mgwt.ui.client.widget.list.celllist.GroupingCellList.java

Source

/*
 * Copyright 2014 Daniel Kurka
 *
 * 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.googlecode.mgwt.ui.client.widget.list.celllist;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.logical.shared.HasSelectionHandlers;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.uibinder.client.UiFactory;
import com.googlecode.mgwt.ui.client.widget.list.celllist.CellListAppearance.CellListCss;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * A grouping cell list renders a number of groups with their children
 *
 * @author Daniel Kurka
 *
 * @param <G> the type of the model for the header
 * @param <T> the type if the model for the content
 */
public class GroupingCellList<G, T> extends CellList<T> implements HasSelectionHandlers<T> {

    public static final GroupingCellListAppearance DEFAULT_APPEARANCE = GWT
            .create(GroupingCellListAppearance.class);

    private final Cell<G> header;
    private final Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    private final Map<Integer, T> modelMap = new HashMap<Integer, T>();

    private GroupingCellListAppearance groupAppearance;

    private HeaderTemplate headerTemplate;

    /**
     * The cellgroup interface
     *
     * @author Daniel Kurka
     *
     * @param <G> the type of the model for the header
     * @param <T> the type if the model for the content
     */
    public interface CellGroup<G, T> {
        /**
         * get the name of the group
         *
         * @return the name of the group
         */
        public String getKey();

        /**
         * get the group header model
         *
         * @return the group header model
         */
        public G getGroup();

        /**
         * get the group content models
         *
         * @return the group content models
         */
        public List<T> getMember();
    }

    /**
     * The standard implementation of {@link GroupingCellList.CellGroup}
     *
     * @author Daniel Kurka
     *
     * @param <G> the type of the model for the header
     * @param <T> the type if the model for the content
     */
    public static class StandardCellGroup<G, T> implements CellGroup<G, T> {

        protected final String key;
        protected final G group;
        protected final List<T> member;

        /**
         * Construct a {@link GroupingCellList.StandardCellGroup}
         *
         * @param key the key to use
         * @param group the group model to use
         * @param member the list of content models for this group
         */
        public StandardCellGroup(String key, G group, List<T> member) {
            this.key = key;
            this.group = group;
            this.member = member;
        }

        @Override
        public String getKey() {
            return key;
        }

        @Override
        public G getGroup() {
            return group;
        }

        @Override
        public List<T> getMember() {
            return member;
        }

    }

    public interface HeaderTemplate {
        SafeHtml li(SafeHtml cellContents, String classes);
    }

    /**
     * Construct a cell list with a given cell for content and for the header
     *
     * @param cell the cell for content
     * @param header the cell for the headers
     */
    public GroupingCellList(Cell<T> cell, Cell<G> header) {
        this(cell, header, DEFAULT_APPEARANCE);
    }

    /**
     * Construct a cell list with a given cell for content, for the header and a given css
     *
     * @param cell the cell for content
     * @param header the cell for the headers
     * @param css the css to use
     */
    public GroupingCellList(Cell<T> cell, Cell<G> header, GroupingCellListAppearance groupAppearance) {
        super(cell, groupAppearance);
        this.groupAppearance = groupAppearance;
        this.header = header;
        headerTemplate = this.groupAppearance.getHeaderTemplate();
    }

    /**
     * render a given set of models
     *
     * @param groups the model to render
     */
    public void renderGroup(List<CellGroup<G, T>> groups) {
        SafeHtmlBuilder sb = new SafeHtmlBuilder();

        int count = 0;

        map.clear();
        modelMap.clear();

        int groupCounter = 0;
        int renderedGroups = 0;

        for (CellGroup<G, T> cellGroup : groups) {

            if (cellGroup.getMember().isEmpty()) {
                groupCounter++;
                continue;
            }

            // render header of group
            SafeHtmlBuilder headerBuilder = new SafeHtmlBuilder();
            header.render(headerBuilder, cellGroup.getGroup());

            sb.append(headerTemplate.li(headerBuilder.toSafeHtml(), this.groupAppearance.css().listHeadElement()));

            // render members of group
            List<T> models = cellGroup.getMember();
            for (T model : models) {
                SafeHtmlBuilder cellBuilder = new SafeHtmlBuilder();

                String clazz = this.groupAppearance.css().entry() + " ";
                if (cell.canBeSelected(model)) {
                    clazz += this.groupAppearance.css().canbeSelected() + " ";
                }

                cell.render(cellBuilder, model);

                sb.append(entryTemplate.li(count, clazz, cellBuilder.toSafeHtml()));

                modelMap.put(count, model);

                count++;
            }

            map.put(renderedGroups, groupCounter);

            renderedGroups++;
            groupCounter++;

        }

        final String html = sb.toSafeHtml().asString();

        getElement().setInnerHTML(html);

        if (count > 0) {
            String innerHTML = getElement().getInnerHTML();
            if ("".equals(innerHTML.trim())) {
                fixBug(html);
            }
        }
    }

    /**
     * get the css selector for header elements
     *
     * @return the css selector for header elements
     */
    public String getHeaderSelector() {
        return "li." + this.groupAppearance.css().listHeadElement();
    }

    /**
     * get the css used by this {@link GroupingCellList}
     *
     * @return the css used by this {@link GroupingCellList}
     */
    public CellListCss getListCss() {
        return this.groupAppearance.css();
    }

    /**
     * get the mapping of index to content
     *
     * @return the mapping of index to content
     */
    public Map<Integer, Integer> getMapping() {
        return map;
    }

    /**
     * render a header and return the value as html
     *
     * @param group the header to render
     * @return the string value
     */
    public String renderGroupHeader(G group) {
        SafeHtmlBuilder headerBuilder = new SafeHtmlBuilder();
        header.render(headerBuilder, group);
        return headerBuilder.toSafeHtml().asString();
    }

    @Override
    protected void fireSelectionAtIndex(int index, Element targetElement) {
        T t = modelMap.get(index);
        if (t != null) {
            SelectionEvent.fire(this, t);
        }
    }

    @Override
    @UiFactory
    public CellListAppearance getAppearance() {
        return super.getAppearance();
    }

    @Override
    public HandlerRegistration addSelectionHandler(SelectionHandler<T> handler) {
        return addHandler(handler, SelectionEvent.getType());
    }
}