Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2011 JBoss, by Red Hat, 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 org.jboss.errai.ui.client.widget;
 
 import java.util.List;
 
 import  javax.enterprise.context.Dependent;
 
 import  org.jboss.errai.common.client.api.Assert;
 import  org.jboss.errai.common.client.util.CreationalCallback;
 import  org.jboss.errai.databinding.client.BindableListChangeHandler;
 import  org.jboss.errai.databinding.client.BindableListWrapper;
 import  org.jboss.errai.ioc.client.container.IOC;
 import  org.jboss.errai.ioc.client.container.SyncToAsyncBeanManagerAdapter;
 import  org.jboss.errai.ioc.client.container.async.AsyncBeanDef;
 import  org.jboss.errai.ioc.client.container.async.AsyncBeanManager;
 
 import  com.google.gwt.event.dom.client.ChangeEvent;
 import  com.google.gwt.event.dom.client.ChangeHandler;
 import  com.google.gwt.event.logical.shared.ValueChangeEvent;
 import  com.google.gwt.event.logical.shared.ValueChangeHandler;
 import  com.google.gwt.event.shared.HandlerRegistration;
 import  com.google.gwt.user.client.ui.ComplexPanel;
 import  com.google.gwt.user.client.ui.Composite;
 import  com.google.gwt.user.client.ui.FlowPanel;
 import  com.google.gwt.user.client.ui.HasValue;
 import  com.google.gwt.user.client.ui.InsertPanel;
 import  com.google.gwt.user.client.ui.IsWidget;
 import  com.google.gwt.user.client.ui.Widget;

A type of widget that displays and manages a child widget for each item in a list of model objects. The widget instances are managed by Errai's IOC container and are arranged in a ComplexPanel. By default, a FlowPanel is used, but an alternative can be specified using ListWidget(ComplexPanel).

Parameters:
<M> the model type
<W> the item widget type, needs to implement HasModel for associating the widget instance with the corresponding model instance.
Author(s):
Christian Sadilek <csadilek@redhat.com>
 
 public abstract class ListWidget<M, W extends HasModel<M> & IsWidget> extends Composite 
   implements HasValue<List<M>>, BindableListChangeHandler<M> {
 
   private final ComplexPanel panel;
   private BindableListWrapper<M> items;
 
   private int pendingCallbacks;
 
   private boolean valueChangeHandlerInitialized;
 
   protected ListWidget() {
     this(new FlowPanel());
   }
 
   protected ListWidget(ComplexPanel panel) {
     this. = Assert.notNull(panel);
     initWidget(panel);
   }
  
  
Returns the class object for the item widget type <W> to look up new instances of the widget using the client-side bean manager.

Returns:
the item widget type.
 
   protected abstract Class<W> getItemWidgetType();

  
Called after all item widgets have been rendered. By default, this is a NOOP, but subclasses can add behaviour if needed.

Using the standard synchronous bean manager this method is invoked before setItems(List) returns. However, when using the asynchronous bean manager and declaring

Parameters:
items the rendered item list. Every change to this list will update the corresponding rendered item widgets.
LoadAsync:
on the item widget, this method might be called after setItems(List) returns and after the corresponding JavaScript code has been downloaded.
  protected void onItemsRendered(List<M> items) {
  }

  
Returns the panel that contains all item widgets.

Returns:
the item widget panel, never null.
  protected ComplexPanel getPanel() {
    return ;
  }

  
Sets the list of model objects. A widget instance of type <W> will be added to the panel for each object in the list. The list will be wrapped in an BindableListWrapper to make direct changes to the list observable.

If the standard synchronous bean manager is used it is guaranteed that all widgets have been added to the panel when this method returns. In case the asynchronous bean manager is used this method might return before the widgets have been added to the panel. See onItemsRendered(List).

Parameters:
items The list of model objects. If null or empty all existing child widgets will be removed.
  public void setItems(List<M> items) {
    boolean changed = this. != items;
    if (items instanceof BindableListWrapper) {
      this. = (BindableListWrapper<M>) items;
    }
    else {
      if (items != null) {
        this. = new BindableListWrapper<M>(items);
      }
      else {
        this. = new BindableListWrapper<M>(new ArrayList<M>());
      }
    }
    if (changed) {
      this..addChangeHandler(this);
      init();
    }
  }
  private void init() {
    // The AsyncBeanManager API works in both synchronous and asynchronous IOC mode
    AsyncBeanManager bm = IOC.getAsyncBeanManager();
    // In the case that this method is executed before the first call has
    // successfully processed all of its callbacks, we must cancel those
    // uncompleted callbacks in flight to prevent duplicate data in the
    // ListWidget.
    for (WidgetCreationalCallback callback : ) {
      callback.discard();
    }
    .clear();
     = 0;
    // clean up the old widgets before we add new ones (this will eventually
    // become a feature of the framework: ERRAI-375)
    Iterator<Widget> it = .iterator();
    while (it.hasNext()) {
      bm.destroyBean(it.next());
      it.remove();
    }
    if ( == null)
      return;
     = .size();
    AsyncBeanDef<W> itemBeanDef = bm.lookupBean(getItemWidgetType());
    if (!itemBeanDef.getScope().equals(Dependent.class))
      throw new InvalidBeanScopeException("ListWidget cannot contain ApplicationScoped widgets");
    for (final M item : ) {
      final WidgetCreationalCallback callback = new WidgetCreationalCallback(item);
      .add(callback);
      itemBeanDef.newInstance(callback);
    }
  }

  
Returns the widget at the specified index.

Parameters:
index the index to be retrieved
Returns:
the widget at the specified index
Throws:
IndexOutOfBoundsException if the index is out of range
  @SuppressWarnings("unchecked")
  public W getWidget(int index) {
    return (W) .getWidget(index);
  }

  
Returns the widget currently displaying the provided model.

Parameters:
model the model displayed by the widget
Returns:
the widget displaying the provided model instance, null if no widget was found for the model.
  public W getWidget(M model) {
    int index = .indexOf(model);
    return getWidget(index);
  }
  
  
Returns the number of widgets currently being displayed.

Returns:
the number of widgets.
  public int getWidgetCount() {
    return getPanel().getWidgetCount();
  }
  public HandlerRegistration addValueChangeHandler(ValueChangeHandler<List<M>> handler) {
       = true;
      addDomHandler(new ChangeHandler() {
        @Override
        public void onChange(ChangeEvent event) {
          ValueChangeEvent.fire(ListWidget.thisgetValue());
        }
      }, ChangeEvent.getType());
    }
    return addHandler(handler, ValueChangeEvent.getType());
  }
  public List<M> getValue() {
    if ( == null) {
       = new BindableListWrapper<M>(new ArrayList<M>());
      .addChangeHandler(this);
    }
    return ;
  }
  public void setValue(List<M> value) {
    setValue(valuefalse);
  }
  public void setValue(List<M> valueboolean fireEvents) {
    List<M> oldValue = getValue();
    setItems(value);
    if (fireEvents) {
      ValueChangeEvent.fireIfNotEqual(thisoldValuevalue);
    }
  }

  
A callback invoked by the AsyncBeanManager or SyncToAsyncBeanManagerAdapter when the widget instance was created. It will associate the corresponding model instance with the widget and add the widget to the panel.
  private class WidgetCreationalCallback implements CreationalCallback<W> {
    private boolean discard;
    private final M item;
    private WidgetCreationalCallback(M item) {
      this. = item;
    }
    @Override
    public void callback(W widget) {
      if (!) {
        widget.setModel();
        .add(widget);
        if (-- == 0) {
          onItemsRendered();
        }
      }
    }
    public void discard() {
      this. = true;
    }
  }
  public void onItemAdded(List<M> oldList, M item) {
    addWidget(item);
  }
  public void onItemAddedAt(List<M> oldListint index, M item) {
    if ( instanceof InsertPanel) {
      addWidgetAt(index.get(index));
    }
    else {
      for (int i = indexi < .size(); i++) {
        addAndReplaceWidget(indexi);
      }
    }
  }
  public void onItemsAdded(List<M> oldListCollection<? extends M> items) {
    for (M m : items) {
      addWidget(m);
    }
  }
  public void onItemsAddedAt(List<M> oldListint indexCollection<? extends M> item) {
    if ( instanceof InsertPanel.ForIsWidget) {
      for (int i = indexi < index + item.size(); i++) {
        addWidgetAt(i.get(i));
      }
    }
    else {
      for (int i = indexi < .size(); i++) {
        addAndReplaceWidget(indexi);
      }
    }
  }
  public void onItemsCleared(List<M> oldList) {
    AsyncBeanManager bm = IOC.getAsyncBeanManager();
    Integer widgetCount = .getWidgetCount();
    Collection<Widget> widgets = new ArrayList<Widget>(widgetCount);
    for (int i = 0; i < widgetCounti++) {
      widgets.add(.getWidget(i));
    }
    .clear();
    Iterator<Widget> itr = widgets.iterator();
    while (itr.hasNext()) {
      Widget w = (Widget) itr.next();
      bm.destroyBean(w);
    }
  }
  public void onItemRemovedAt(List<M> oldListint index) {
    Widget widget = .getWidget(index);
    .remove(index);
    IOC.getAsyncBeanManager().destroyBean(widget);
  }
  public void onItemsRemovedAt(List<M> oldListList<Integerindexes) {
    for (Integer index : indexes) {
      Widget widget = .getWidget(index);
      .remove(index);
      IOC.getAsyncBeanManager().destroyBean(widget);
    }
  }
  public void onItemChanged(List<M> oldListint index, M item) {
    for (int i = indexi < .size(); i++) {
      addAndReplaceWidget(indexi);
    }
  }
  private void addAndReplaceWidget(final int startIndexfinal int index) {
    if (index < .getWidgetCount()) {
      .remove(startIndex);
    }
    addWidget(.get(index));
  }
  
  private void addWidget(final M m) {
    AsyncBeanDef<W> itemBeanDef = IOC.getAsyncBeanManager().lookupBean(getItemWidgetType());
    itemBeanDef.getInstance(new CreationalCallback<W>() {
      @Override
      public void callback(W widget) {
        widget.setModel(m);
        .add(widget);
      }
    });
  }
  private void addWidgetAt(final int indexfinal M m) {
    if (!( instanceof InsertPanel.ForIsWidget)) {
      throw new RuntimeException("Method only supported for panels that implement: "
              + InsertPanel.ForIsWidget.class.getName());
    }
    AsyncBeanDef<W> itemBeanDef = IOC.getAsyncBeanManager().lookupBean(getItemWidgetType());
    itemBeanDef.getInstance(new CreationalCallback<W>() {
      @Override
      public void callback(W widget) {
        widget.setModel(m);
        ((InsertPanel.ForIsWidget) ).insert(widgetindex);
      }
    });
  }
New to GrepCode? Check out our FAQ X