| /* |
| * 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.gwt.sample.dynatablerf.client.widgets; |
| |
| import com.google.gwt.core.client.GWT; |
| import com.google.gwt.editor.client.adapters.EditorSource; |
| import com.google.gwt.editor.client.adapters.ListEditor; |
| import com.google.gwt.event.shared.EventBus; |
| import com.google.gwt.event.shared.HandlerRegistration; |
| import com.google.gwt.resources.client.CssResource; |
| import com.google.gwt.sample.dynatablerf.client.FavoritesManager; |
| import com.google.gwt.sample.dynatablerf.client.events.MarkFavoriteEvent; |
| import com.google.gwt.sample.dynatablerf.shared.PersonProxy; |
| import com.google.gwt.uibinder.client.UiBinder; |
| import com.google.gwt.uibinder.client.UiField; |
| import com.google.gwt.user.client.ui.Composite; |
| import com.google.gwt.user.client.ui.FlowPanel; |
| import com.google.gwt.user.client.ui.Widget; |
| import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver; |
| import com.google.web.bindery.requestfactory.shared.EntityProxyId; |
| import com.google.web.bindery.requestfactory.shared.Receiver; |
| import com.google.web.bindery.requestfactory.shared.RequestFactory; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| |
| /** |
| * Displays Person objects that the user has selected as a favorite. This |
| * demonstrates a read-only "editor" that receives update notifications. |
| */ |
| public class FavoritesWidget extends Composite { |
| |
| interface Binder extends UiBinder<Widget, FavoritesWidget> { |
| } |
| |
| /** |
| * A driver that accepts a List of PersonProxy objects, controlled by a |
| * ListEditor of PersonProxy instances, displayed using NameLabels. |
| */ |
| interface Driver extends RequestFactoryEditorDriver<List<PersonProxy>, // |
| ListEditor<PersonProxy, NameLabel>> { |
| } |
| |
| interface Style extends CssResource { |
| String favorite(); |
| } |
| |
| /** |
| * This is used by the ListEditor to control the state of the UI. |
| */ |
| private class NameLabelSource extends EditorSource<NameLabel> { |
| @Override |
| public NameLabel create(int index) { |
| NameLabel label = new NameLabel(eventBus); |
| label.setStylePrimaryName(style.favorite()); |
| container.insert(label, index); |
| return label; |
| } |
| |
| @Override |
| public void dispose(NameLabel subEditor) { |
| subEditor.removeFromParent(); |
| subEditor.cancelSubscription(); |
| } |
| |
| @Override |
| public void setIndex(NameLabel editor, int index) { |
| container.insert(editor, index); |
| } |
| } |
| |
| @UiField |
| FlowPanel container; |
| |
| @UiField |
| Style style; |
| |
| /** |
| * This list is a facade provided by the ListEditor. Structural modifications |
| * to this list (e.g. add(), set(), remove()) will trigger UI update events. |
| */ |
| private final List<PersonProxy> displayedList; |
| private final EventBus eventBus; |
| private final RequestFactory factory; |
| private final FavoritesManager manager; |
| private HandlerRegistration subscription; |
| |
| public FavoritesWidget(EventBus eventBus, RequestFactory factory, |
| FavoritesManager manager) { |
| this.eventBus = eventBus; |
| this.factory = factory; |
| this.manager = manager; |
| |
| // Create the UI |
| initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this)); |
| |
| // Create the driver which manages the data-bound widgets |
| Driver driver = GWT.<Driver> create(Driver.class); |
| |
| // Use a ListEditor that uses our NameLabelSource |
| ListEditor<PersonProxy, NameLabel> editor = ListEditor.of(new NameLabelSource()); |
| |
| // Configure the driver |
| ListEditor<PersonProxy, NameLabel> listEditor = editor; |
| driver.initialize(eventBus, factory, listEditor); |
| |
| // Notice the backing list is essentially anonymous. |
| driver.display(new ArrayList<PersonProxy>()); |
| |
| // Modifying this list triggers widget creation and destruction |
| displayedList = listEditor.getList(); |
| } |
| |
| @Override |
| protected void onLoad() { |
| // Subscribe to notifications from the FavoritesManager |
| subscription = manager.addMarkFavoriteHandler(new MarkFavoriteEvent.Handler() { |
| public void onMarkFavorite(MarkFavoriteEvent event) { |
| FavoritesWidget.this.onMarkFavorite(event); |
| } |
| }); |
| |
| // Initialize the UI with the existing list of favorites |
| for (EntityProxyId<PersonProxy> id : manager.getFavoriteIds()) { |
| onMarkFavorite(new MarkFavoriteEvent(id, true)); |
| } |
| } |
| |
| @Override |
| protected void onUnload() { |
| subscription.removeHandler(); |
| } |
| |
| private void onMarkFavorite(MarkFavoriteEvent event) { |
| EntityProxyId<PersonProxy> id = event.getId(); |
| if (id == null) { |
| return; |
| } |
| |
| // EntityProxies should be compared by stable id |
| PersonProxy found = null; |
| for (PersonProxy displayed : displayedList) { |
| if (displayed.stableId().equals(id)) { |
| found = displayed; |
| break; |
| } |
| } |
| |
| if (event.isFavorite() && found == null) { |
| factory.find(id).to(new Receiver<PersonProxy>() { |
| @Override |
| public void onSuccess(PersonProxy response) { |
| displayedList.add(response); |
| sortDisplayedList(); |
| } |
| }).fire(); |
| } else if (!event.isFavorite() && found != null) { |
| displayedList.remove(found); |
| sortDisplayedList(); |
| } |
| } |
| |
| private void sortDisplayedList() { |
| // Sorting the list of PersonProxies will also change the UI display |
| Collections.sort(displayedList, new Comparator<PersonProxy>() { |
| public int compare(PersonProxy o1, PersonProxy o2) { |
| // Newly-created records may have null names |
| String name1 = o1.getName() == null ? "" : o1.getName(); |
| String name2 = o2.getName() == null ? "" : o2.getName(); |
| return name1.compareToIgnoreCase(name2); |
| } |
| }); |
| } |
| } |