com.googlecode.mgwt.ui.client.widget.list.widgetlist.WidgetList.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.mgwt.ui.client.widget.list.widgetlist.WidgetList.java

Source

/*
 * Copyright 2010 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.widgetlist;

import com.google.gwt.core.shared.GWT;
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.uibinder.client.UiChild;
import com.google.gwt.uibinder.client.UiFactory;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.Widget;
import com.googlecode.mgwt.dom.client.event.tap.HasTapHandlers;
import com.googlecode.mgwt.dom.client.event.tap.TapEvent;
import com.googlecode.mgwt.dom.client.event.tap.TapHandler;
import com.googlecode.mgwt.dom.client.recognizer.TapRecognizer;
import com.googlecode.mgwt.ui.client.widget.list.celllist.CellList;
import com.googlecode.mgwt.ui.client.widget.touch.TouchWidgetImpl;

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

/**
 * A list that can contain widgets
 *
 * This class renders widgets into a list. The same thing is done by {@link CellList} much more
 * efficient.
 *
 * <b>Note:</b> Normally you should be using {@link CellList}. Only if you really need Widgets
 * inside the list (which won't be the case most of the time) you should be using WidgetList.
 *
 * The reference for styling can be found in CellList as well.
 *
 *
 * @author Daniel Kurka
 */
public class WidgetList extends Composite implements HasWidgets, HasSelectionHandlers<Integer> {

    public static class WidgetListEntry extends Composite implements AcceptsOneWidget, HasTapHandlers {

        private static final TouchWidgetImpl IMPL = GWT.create(TouchWidgetImpl.class);

        @UiField
        public Panel container;
        // UiBinder needs this field
        private WidgetListAppearance appearance;

        public WidgetListEntry(WidgetListAppearance appearance) {
            this.appearance = appearance;
            initWidget(this.appearance.uiBinderEntry().createAndBindUi(this));
            IMPL.addTouchHandler(container, new TapRecognizer(this));
        }

        @Override
        public void setWidget(IsWidget w) {
            container.add(w);
        }

        @Override
        public HandlerRegistration addTapHandler(TapHandler handler) {
            return addHandler(handler, TapEvent.getType());
        }

        @UiFactory
        public WidgetListAppearance getAppearance() {
            return appearance;
        }
    }

    private static class Entry {
        WidgetListEntry entry;
        HandlerRegistration handlerRegistration;

        public Entry(WidgetListEntry entry, HandlerRegistration handlerRegistration) {
            this.entry = entry;
            this.handlerRegistration = handlerRegistration;
        }
    }

    private static final WidgetListAppearance DEFAULT_APPEARANCE = GWT.create(WidgetListAppearance.class);

    private int childCount;
    private List<WidgetListEntry> children = new ArrayList<WidgetListEntry>();

    @UiField
    public ComplexPanel container;

    @UiField
    public Panel headerContainer;

    private Map<Widget, Entry> map;

    private WidgetListAppearance appearance;

    private Widget header;

    public WidgetList() {
        this(DEFAULT_APPEARANCE);
    }

    public WidgetList(WidgetListAppearance appearance) {
        this.appearance = appearance;
        initWidget(this.appearance.uiBinder().createAndBindUi(this));
        map = new HashMap<Widget, Entry>();
    }

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

    @Override
    public void add(Widget w) {

        final WidgetListEntry widgetListEntry = new WidgetListEntry(this.appearance);
        widgetListEntry.setWidget(w);
        HandlerRegistration handlerRegistration = widgetListEntry.addTapHandler(new TapHandler() {
            @Override
            public void onTap(TapEvent event) {
                SelectionEvent.fire(WidgetList.this, container.getWidgetIndex(widgetListEntry));
            }
        });
        if (childCount == 0) {
            widgetListEntry.addStyleName(this.appearance.css().widgetListEntryFirstChild());
        }
        map.put(w, new Entry(widgetListEntry, handlerRegistration));
        container.add(widgetListEntry);
        children.add(widgetListEntry);

        if (childCount > 0) {
            children.get(childCount - 1).removeStyleName(this.appearance.css().widgetListEntryLastChild());
        }
        widgetListEntry.addStyleName(this.appearance.css().widgetListEntryLastChild());

        childCount++;

    }

    @Override
    public void clear() {
        container.clear();
        for (Entry entry : map.values()) {
            entry.handlerRegistration.removeHandler();
        }
        map.clear();
        children.clear();
        childCount = 0;
        if (header != null) {
            add(header);
        }
    }

    @Override
    public Iterator<Widget> iterator() {
        return map.keySet().iterator();
    }

    @Override
    public boolean remove(Widget w) {
        Entry entry = map.remove(w);
        if (entry == null)
            return false;
        // did we remove the last child?
        if (children.get(childCount - 1) == entry.entry) {
            // are there others in the list?
            if (childCount - 2 >= 0) {
                children.get(childCount - 2).addStyleName(this.appearance.css().widgetListEntryLastChild());
            }
        }

        // did we remove the first child
        if (children.get(0) == entry.entry) {
            if (children.size() > 1) {
                children.get(1).addStyleName(this.appearance.css().widgetListEntryFirstChild());
            }
        }
        childCount--;
        children.remove(entry);
        entry.handlerRegistration.removeHandler();
        return container.remove(entry.entry);
    }

    /**
     * Should the list be displayed with rounded corners
     *
     * @param round true to display with rounded corners
     */
    public void setRound(boolean round) {
        if (round) {
            addStyleName(this.appearance.css().round());
        } else {
            removeStyleName(this.appearance.css().round());
        }
    }

    public int getWidgetCount() {
        return childCount;
    }

    public void setSelectAble(int index, boolean group) {
        if (group) {
            children.get(index).addStyleName(this.appearance.css().widgetListEntrySelectedable());
        } else {
            children.get(index).removeStyleName(this.appearance.css().widgetListEntrySelectedable());
        }
    }

    @UiChild(limit = 1, tagname = "header")
    public void setHeader(Widget header) {
        headerContainer.setVisible(header != null);
        headerContainer.clear();
        if (header != null) {
            headerContainer.add(header);
        }
    }

    @UiFactory
    public WidgetListAppearance getAppearance() {
        return appearance;
    }
}