Java tutorial
/** * 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.lsp.views; import com.google.gwt.core.client.GWT; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.google.livingstories.client.ContentItemTypesBundle; import com.google.livingstories.client.ContentRpcService; import com.google.livingstories.client.ContentRpcServiceAsync; import com.google.livingstories.client.DisplayContentItemBundle; import com.google.livingstories.client.FilterSpec; import com.google.livingstories.client.LivingStoryRpcService; import com.google.livingstories.client.LivingStoryRpcServiceAsync; import com.google.livingstories.client.lsp.ContentRenderer; import com.google.livingstories.client.lsp.FilterWidget; import com.google.livingstories.client.lsp.LspContentItemListWidget; import com.google.livingstories.client.lsp.Page; import com.google.livingstories.client.lsp.RecentEventsList; import com.google.livingstories.client.lsp.ThemeListWidget; import com.google.livingstories.client.lsp.event.BlockToggledEvent; import com.google.livingstories.client.lsp.event.EventBus; import com.google.livingstories.client.ui.AnchoredPanel; import com.google.livingstories.client.ui.FCCommentsBox; import com.google.livingstories.client.ui.UpdateCountWidget; import com.google.livingstories.client.util.HistoryManager; import com.google.livingstories.client.util.LivingStoryControls; import com.google.livingstories.client.util.LivingStoryData; import com.google.livingstories.client.util.HistoryManager.HistoryPages; import java.util.Map; /** * Page that displays the summary and the content grid. */ public class OverviewPage extends Page { private static OverviewPageUiBinder uiBinder = GWT.create(OverviewPageUiBinder.class); interface OverviewPageUiBinder extends UiBinder<Widget, OverviewPage> { } private static final String SCROLL_POSITION_STATE = "sp"; private final ContentRpcServiceAsync contentService = GWT.create(ContentRpcService.class); private final LivingStoryRpcServiceAsync livingStoryService = GWT.create(LivingStoryRpcService.class); @UiField Label title; @UiField UpdateCountWidget updateCount; @UiField SimplePanel summary; @UiField ThemeListWidget themeList; @UiField FilterWidget filterList; @UiField LspContentItemListWidget contentItemList; @UiField AnchoredPanel rightPanel; @UiField RecentEventsList recentEvents; @UiField FCCommentsBox comments; private HandlerRegistration toggleEventHandler; public OverviewPage() { initWidget(uiBinder.createAndBindUi(this)); title.setText(LivingStoryData.getLivingStoryTitle()); updateCount.load(LivingStoryData.getLivingStoryId(), LivingStoryData.getLastVisitDate()); summary.add(new ContentRenderer(LivingStoryData.getSummary(), true, true)); recentEvents.load(); livingStoryService.getThemeInfoForLivingStory(LivingStoryData.getLivingStoryId(), new AsyncCallback<Map<Long, ContentItemTypesBundle>>() { @Override public void onFailure(Throwable caught) { } @Override public void onSuccess(Map<Long, ContentItemTypesBundle> results) { themeList.load(results); filterList.load(results, themeList.getSelectedThemeId()); } }); exportMethods(); } /** * Sets off an asynchronous call that fills in data for the event list. In some circumstances, * can do its work synchronously. */ public void update(FilterSpec filter, Long focusedContentItemId) { FilterSpec oldFilter = filterList.getFilter(); if (!filter.equals(oldFilter)) { boolean simpleReversal = !contentItemList.hasMore() && filter.isReverseOf(oldFilter); filterList.setFilter(filter); if (simpleReversal) { contentItemList.doSimpleReversal(filter.oldestFirst); } else { contentService.getDisplayContentItemBundle(LivingStoryData.getLivingStoryId(), filter, focusedContentItemId, null, new ContentItemCallback(focusedContentItemId)); contentItemList.clear(); contentItemList.beginLoading(); beginLoading(); } } else if (focusedContentItemId != null) { highlightEvent(focusedContentItemId, false); } } @Override public void changeState(String key, String value) { if (key.equals(SCROLL_POSITION_STATE)) { Window.scrollTo(0, Integer.valueOf(value)); repositionAnchoredPanel(); } } @Override public void onShow() { repositionAnchoredPanel(); } @Override protected void onLoad() { super.onLoad(); toggleEventHandler = EventBus.INSTANCE.addHandler(BlockToggledEvent.TYPE, new BlockToggledEvent.Handler() { @Override public void onToggle(BlockToggledEvent e) { if (e.isOpened() && e.shouldSetHistory()) { // Set this content item as the focused contentitem in the history. // When the user navigates away from this and then clicks back, this item will // appear expanded, and the viewport will be scrolled to its position. HistoryManager.newToken(HistoryPages.OVERVIEW, LivingStoryControls.getCurrentFilterSpec().getFilterParams(), String.valueOf(e.getContentItemId())); } } }); } @Override public void onUnload() { super.onUnload(); if (toggleEventHandler != null) { toggleEventHandler.removeHandler(); toggleEventHandler = null; } } private class ContentItemCallback implements AsyncCallback<DisplayContentItemBundle> { private Long focusedContentItemId; public ContentItemCallback() { this(null); } public ContentItemCallback(Long focusedContentItemId) { this.focusedContentItemId = focusedContentItemId; } public void onFailure(Throwable t) { contentItemList.showError(); } public void onSuccess(DisplayContentItemBundle bundle) { themeList.setSelectedThemeId(bundle.getAdjustedFilterSpec().themeId); if (!filterList.getFilter().equals(bundle.getAdjustedFilterSpec())) { filterList.setFilter(bundle.getAdjustedFilterSpec()); contentItemList.clear(); } contentItemList.finishLoading(bundle); if (focusedContentItemId != null) { contentItemList.goToContentItem(focusedContentItemId); } finishLoading(); comments.loadCommentsBox("LSID:" + LivingStoryData.getLivingStoryId()); rightPanel.setVisible(true); } } /** * "Jumps to" the event indicated by contentItemId, scrolling it into view and opening its * contents. * Only works for event and standalone narrative content items. * Sets a history token when called. */ public void highlightEvent(int contentItemId) { // Save the current scroll position in the history so that when the user clicks 'back', // they're scrolled back here. HistoryManager.changeState(SCROLL_POSITION_STATE, String.valueOf(Window.getScrollTop())); highlightEvent(contentItemId, true); } /** * Internal version of highlightEvent. Lets the update() method above select an * event without setting an extra history token. */ private void highlightEvent(long contentItemId, boolean setHistoryToken) { boolean finished = contentItemList.goToContentItem(contentItemId); if (!finished) { contentService.getDisplayContentItemBundle(LivingStoryData.getLivingStoryId(), filterList.getFilter(), contentItemId, contentItemList.getNextDateInSequence(), new ContentItemCallback(contentItemId)); } if (setHistoryToken) { // Set this content item as the focused item in the history. // When the user navigates away from this and then clicks back, this content item will // appear expanded, and the viewport will be scrolled to its position. HistoryManager.newToken(HistoryPages.OVERVIEW, LivingStoryControls.getCurrentFilterSpec().getFilterParams(), String.valueOf(contentItemId)); } } public void getMoreContentItems() { contentService.getDisplayContentItemBundle(LivingStoryData.getLivingStoryId(), filterList.getFilter(), null, contentItemList.getNextDateInSequence(), new ContentItemCallback()); contentItemList.beginLoading(); } public void repositionAnchoredPanel() { rightPanel.reposition(); } public FilterSpec getCurrentFilterSpec() { return filterList.getFilter(); } private native void exportMethods() /*-{ var instance = this; $wnd.goToContentItem = function(contentItemId) { instance.@com.google.livingstories.client.lsp.views.OverviewPage::highlightEvent(I) .call(instance, contentItemId); } $wnd.repositionAnchoredPanel = function(contentItemId) { instance.@com.google.livingstories.client.lsp.views.OverviewPage::repositionAnchoredPanel() .call(instance); } $wnd.getMoreContentItems = function() { instance.@com.google.livingstories.client.lsp.views.OverviewPage::getMoreContentItems() .call(instance); } $wnd.getCurrentFilterSpec = function() { return instance. @com.google.livingstories.client.lsp.views.OverviewPage::getCurrentFilterSpec() .call(instance); } }-*/; }