com.google.livingstories.client.ui.ContentItemListBox.java Source code

Java tutorial

Introduction

Here is the source code for com.google.livingstories.client.ui.ContentItemListBox.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.livingstories.client.ui;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.livingstories.client.ContentItemType;
import com.google.livingstories.client.BaseContentItem;
import com.google.livingstories.client.ContentRpcService;
import com.google.livingstories.client.ContentRpcServiceAsync;
import com.google.livingstories.client.util.Constants;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Widget that loads a list of content items based on an living story id, and has a built-in
 * filtering mechanism.
 * The underlying storage for the content items is a LinkedHashMap. To get incrementally-added items
 * to appear at the top of the list, rather than at the bottom, the order in which items are
 * stored in the LinkedHashMap is actually opposite to the display order.
 */
public class ContentItemListBox extends Composite {
    /**
     * Create a remote service proxy to talk to the server-side content persisting service.
     */
    private final ContentRpcServiceAsync contentService = GWT.create(ContentRpcService.class);

    private ItemList<BaseContentItem> itemList;
    protected EnumDropdown<ContentItemType> filter;
    private Map<Long, BaseContentItem> loadedContentItemsMap = new LinkedHashMap<Long, BaseContentItem>();

    public ContentItemListBox(final boolean multiSelect) {
        filter = EnumDropdown.newInstance(ContentItemType.class, "All");
        filter.addChangeHandler(new ChangeHandler() {
            @Override
            public void onChange(ChangeEvent event) {
                refresh();
            }
        });

        HorizontalPanel filterPanel = new HorizontalPanel();
        filterPanel.add(new Label("Filter:"));
        filterPanel.add(filter);

        itemList = new ItemList<BaseContentItem>(multiSelect) {
            @Override
            public void loadItems() {
                if (!loadedContentItemsMap.isEmpty()) {
                    // loads the items in reverse order from how they're stored.
                    List<BaseContentItem> contentItems = new ArrayList<BaseContentItem>(
                            loadedContentItemsMap.values());
                    Collections.reverse(contentItems);

                    for (BaseContentItem contentItem : contentItems) {
                        if (testContentItem(contentItem)) {
                            String content = contentItem.getDisplayString();
                            if (content.length() > Constants.CONTENT_SNIPPET_LENGTH) {
                                content = content.substring(0, Constants.CONTENT_SNIPPET_LENGTH).concat("...");
                            }
                            addItem(content, String.valueOf(contentItem.getId()));
                        }
                    }
                }
            }
        };

        VerticalPanel contentPanel = new VerticalPanel();
        contentPanel.add(filterPanel);
        contentPanel.add(itemList);
        initWidget(contentPanel);
    }

    /**
     * Tests whether a content item should be included in the displayed list, based on the filter
     * setting.
     */
    protected boolean testContentItem(BaseContentItem contentItem) {
        ContentItemType type = filter.getSelectedConstant();
        return type == null || contentItem.getContentItemType().equals(type) || isSelected(contentItem);
    }

    public void loadItemsForLivingStory(Long livingStoryId) {
        itemList.setSelectedIndex(-1);
        loadedContentItemsMap.clear();
        contentService.getContentItemsForLivingStory(livingStoryId, false,
                new AsyncCallback<List<BaseContentItem>>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        itemList.clear();
                        itemList.addItem("Callback failed, please try again");
                    }

                    @Override
                    public void onSuccess(List<BaseContentItem> result) {
                        // Put result on loadedAContentItemsMap in reverse order. Can't use useful
                        // Google Collections stuff for it, so:
                        for (int i = result.size() - 1; i >= 0; i--) {
                            BaseContentItem contentItem = result.get(i);
                            loadedContentItemsMap.put(contentItem.getId(), contentItem);
                        }
                        refresh();
                    }
                });
    }

    public void setVisibleItemCount(int count) {
        itemList.setVisibleItemCount(count);
    }

    public void addSelectionChangeHandler(ChangeHandler handler) {
        itemList.addChangeHandler(handler);
    }

    public void addFilterChangeHandler(ChangeHandler handler) {
        filter.addChangeHandler(handler);
    }

    public void clear() {
        itemList.clear();
    }

    public void refresh() {
        itemList.refresh();
    }

    public Long getSelectedContentItemId() {
        return itemList.hasSelection() ? Long.valueOf(itemList.getSelectedItemValue()) : null;
    }

    public BaseContentItem getSelectedContentItem() {
        return itemList.hasSelection() ? loadedContentItemsMap.get(getSelectedContentItemId()) : null;
    }

    public List<String> getSelectedItems() {
        return itemList.getSelectedItems();
    }

    public List<String> getSelectedValues() {
        return itemList.getSelectedItemValues();
    }

    public void setSelectedContentItemIds(Set<Long> selectedContentItemIds) {
        for (int i = 0; i < itemList.getItemCount(); i++) {
            itemList.setItemSelected(i, selectedContentItemIds.contains(Long.valueOf(itemList.getValue(i))));
        }
    }

    public List<BaseContentItem> getSelectedContentitems() {
        List<BaseContentItem> result = new ArrayList<BaseContentItem>();
        for (String contentItemId : itemList.getSelectedItemValues()) {
            result.add(loadedContentItemsMap.get(Long.valueOf(contentItemId)));
        }
        return result;
    }

    public Map<Long, BaseContentItem> getLoadedContentItemsMap() {
        return loadedContentItemsMap;
    }

    public void addOrUpdateContentItem(BaseContentItem contentItem) {
        boolean isAdd = !loadedContentItemsMap.containsKey(contentItem.getId());
        loadedContentItemsMap.put(contentItem.getId(), contentItem);
        // Change the filter if necessary so that the added/updated content item
        // is visible and selectable.
        if (filter.getSelectedConstant() != null
                && !contentItem.getContentItemType().equals(filter.getSelectedConstant())) {
            filter.selectConstant(null);
        }
        itemList.refresh();
        itemList.selectItemWithValue(String.valueOf(contentItem.getId()));
        if (isAdd) {
            itemList.fireEvent(new ChangeEvent() {
            });
        }
    }

    public void addContentItems(List<BaseContentItem> contentItems) {
        // Add to loadedContentItemsMap in reverse order to how the items were specified.
        for (int i = contentItems.size() - 1; i >= 0; i--) {
            BaseContentItem contentItem = contentItems.get(i);
            loadedContentItemsMap.put(contentItem.getId(), contentItem);
        }
        itemList.refresh();
    }

    public void removeContentItem(long contentItemId) {
        itemList.removeItemWithValue(String.valueOf(contentItemId));
        loadedContentItemsMap.remove(contentItemId);
    }

    private boolean isSelected(BaseContentItem contentItem) {
        if (itemList.isMultipleSelect()) {
            for (String value : itemList.getSelectedItemValues()) {
                if (Long.valueOf(value).equals(contentItem.getId())) {
                    return true;
                }
            }
            return false;
        } else {
            return itemList.getSelectedItemValue() != null
                    && Long.valueOf(itemList.getSelectedItemValue()).equals(contentItem.getId());
        }
    }
}