Package com.google.gwt.user.cellview.client

Source Code of com.google.gwt.user.cellview.client.CellTable$ResourcesAdapter

/*
* 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.user.cellview.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style.TableLayout;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.dom.client.TableColElement;
import com.google.gwt.dom.client.TableElement;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.dom.client.TableSectionElement;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.CssResource.ImportedWithPrefix;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.resources.client.ImageResource.ImageOptions;
import com.google.gwt.resources.client.ImageResource.RepeatStyle;
import com.google.gwt.user.cellview.client.LoadingStateChangeEvent.LoadingState;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ProvidesKey;

import java.util.HashSet;
import java.util.Set;

/**
* A tabular view that supports paging and columns.
*
* <p>
* <h3>Columns</h3> The {@link Column} class defines the
* {@link com.google.gwt.cell.client.Cell} used to render a column. Implement
* {@link Column#getValue(Object)} to retrieve the field value from the row
* object that will be rendered in the {@link com.google.gwt.cell.client.Cell}.
* </p>
*
* <p>
* <h3>Headers and Footers</h3> A {@link Header} can be placed at the top
* (header) or bottom (footer) of the {@link CellTable}. You can specify a
* header as text using {@link #addColumn(Column, String)}, or you can create a
* custom {@link Header} that can change with the value of the cells, such as a
* column total. The {@link Header} will be rendered every time the row data
* changes or the table is redrawn. If you pass the same header instance (==)
* into adjacent columns, the header will span the columns.
* </p>
*
* <p>
* <h3>Examples</h3>
* <dl>
* <dt>Trivial example</dt>
* <dd>{@example com.google.gwt.examples.cellview.CellTableExample}</dd>
* <dt>Handling user input with trivial FieldUpdater example</dt>
* <dd>{@example com.google.gwt.examples.cellview.CellTableFieldUpdaterExample}</dd>
* <dt>Handling user input with complex FieldUpdater example</dt>
* <dd>{@example
* com.google.gwt.examples.cellview.CellTableFieldUpdaterExampleComplex}</dd>
* <dt>Pushing data with List Data Provider (backed by {@link List})</dt>
* <dd>{@example com.google.gwt.examples.view.ListDataProviderExample}</dd>
* <dt>Pushing data asynchronously with Async Data Provider</dt>
* <dd>{@example com.google.gwt.examples.view.AsyncDataProviderExample}</dd>
* <dt>Writing a custom data provider</dt>
* <dd>{@example com.google.gwt.examples.view.RangeChangeHandlerExample}</dd>
* <dt>Using a key provider to track objects as they change</dt>
* <dd>{@example com.google.gwt.examples.view.KeyProviderExample}</dd>
* </dl>
* </p>
*
* @param <T> the data type of each row
*/
public class CellTable<T> extends AbstractCellTable<T> {

  /**
   * Resources that match the GWT standard style theme.
   */
  public interface BasicResources extends Resources {
    /**
     * The styles used in this widget.
     */
    @Override
    @Source(BasicStyle.DEFAULT_CSS)
    BasicStyle cellTableStyle();
  }

  /**
   * A ClientBundle that provides images for this widget.
   */
  public interface Resources extends ClientBundle {
    /**
     * The background used for footer cells.
     */
    @Source("cellTableHeaderBackground.png")
    @ImageOptions(repeatStyle = RepeatStyle.Horizontal, flipRtl = true)
    ImageResource cellTableFooterBackground();

    /**
     * The background used for header cells.
     */
    @ImageOptions(repeatStyle = RepeatStyle.Horizontal, flipRtl = true)
    ImageResource cellTableHeaderBackground();

    /**
     * The loading indicator used while the table is waiting for data.
     */
    @ImageOptions(flipRtl = true)
    ImageResource cellTableLoading();

    /**
     * The background used for selected cells.
     */
    @Source("cellListSelectedBackground.png")
    @ImageOptions(repeatStyle = RepeatStyle.Horizontal, flipRtl = true)
    ImageResource cellTableSelectedBackground();

    /**
     * Icon used when a column is sorted in ascending order.
     */
    @Source("sortAscending.png")
    @ImageOptions(flipRtl = true)
    ImageResource cellTableSortAscending();

    /**
     * Icon used when a column is sorted in descending order.
     */
    @Source("sortDescending.png")
    @ImageOptions(flipRtl = true)
    ImageResource cellTableSortDescending();

    /**
     * The styles used in this widget.
     */
    @Source(Style.DEFAULT_CSS)
    Style cellTableStyle();
  }

  /**
   * Styles used by this widget.
   */
  @ImportedWithPrefix("gwt-CellTable")
  public interface Style extends CssResource {
    /**
     * The path to the default CSS styles used by this resource.
     */
    String DEFAULT_CSS = "com/google/gwt/user/cellview/client/CellTable.css";

    /**
     * Applied to every cell.
     */
    String cellTableCell();

    /**
     * Applied to even rows.
     */
    String cellTableEvenRow();

    /**
     * Applied to cells in even rows.
     */
    String cellTableEvenRowCell();

    /**
     * Applied to the first column.
     */
    String cellTableFirstColumn();

    /**
     * Applied to the first column footers.
     */
    String cellTableFirstColumnFooter();

    /**
     * Applied to the first column headers.
     */
    String cellTableFirstColumnHeader();

    /**
     * Applied to footers cells.
     */
    String cellTableFooter();

    /**
     * Applied to headers cells.
     */
    String cellTableHeader();

    /**
     * Applied to the hovered row.
     */
    String cellTableHoveredRow();

    /**
     * Applied to the cells in the hovered row.
     */
    String cellTableHoveredRowCell();

    /**
     * Applied to the keyboard selected cell.
     */
    String cellTableKeyboardSelectedCell();

    /**
     * Applied to the keyboard selected row.
     */
    String cellTableKeyboardSelectedRow();

    /**
     * Applied to the cells in the keyboard selected row.
     */
    String cellTableKeyboardSelectedRowCell();

    /**
     * Applied to the last column.
     */
    String cellTableLastColumn();

    /**
     * Applied to the last column footers.
     */
    String cellTableLastColumnFooter();

    /**
     * Applied to the last column headers.
     */
    String cellTableLastColumnHeader();

    /**
     * Applied to the loading indicator.
     */
    String cellTableLoading();

    /**
     * Applied to odd rows.
     */
    String cellTableOddRow();

    /**
     * Applied to cells in odd rows.
     */
    String cellTableOddRowCell();

    /**
     * Applied to selected rows.
     */
    String cellTableSelectedRow();

    /**
     * Applied to cells in selected rows.
     */
    String cellTableSelectedRowCell();

    /**
     * Applied to header cells that are sortable.
     */
    String cellTableSortableHeader();

    /**
     * Applied to header cells that are sorted in ascending order.
     */
    String cellTableSortedHeaderAscending();

    /**
     * Applied to header cells that are sorted in descending order.
     */
    String cellTableSortedHeaderDescending();

    /**
     * Applied to the table.
     */
    String cellTableWidget();
  }

  /**
   * Styles used by {@link BasicResources}.
   */
  @ImportedWithPrefix("gwt-CellTable")
  interface BasicStyle extends Style {
    /**
     * The path to the default CSS styles used by this resource.
     */
    String DEFAULT_CSS = "com/google/gwt/user/cellview/client/CellTableBasic.css";
  }

  /**
   * Adapter class to convert {@link Resources} to
   * {@link AbstractCellTable.Resources}.
   */
  private static class ResourcesAdapter implements AbstractCellTable.Resources {

    private final CellTable.Resources resources;
    private final StyleAdapter style;

    public ResourcesAdapter(CellTable.Resources resources) {
      this.resources = resources;
      this.style = new StyleAdapter(resources.cellTableStyle());
    }

    @Override
    public ImageResource sortAscending() {
      return resources.cellTableSortAscending();
    }

    @Override
    public ImageResource sortDescending() {
      return resources.cellTableSortDescending();
    }

    @Override
    public AbstractCellTable.Style style() {
      return style;
    }
  }

  /**
   * Adapter class to convert {@link Style} to {@link AbstractCellTable.Style}.
   */
  private static class StyleAdapter implements AbstractCellTable.Style {
    private final CellTable.Style style;

    public StyleAdapter(CellTable.Style style) {
      this.style = style;
    }

    @Override
    public String cell() {
      return style.cellTableCell();
    }

    @Override
    public String evenRow() {
      return style.cellTableEvenRow();
    }

    @Override
    public String evenRowCell() {
      return style.cellTableEvenRowCell();
    }

    @Override
    public String firstColumn() {
      return style.cellTableFirstColumn();
    }

    @Override
    public String firstColumnFooter() {
      return style.cellTableFirstColumnFooter();
    }

    @Override
    public String firstColumnHeader() {
      return style.cellTableFirstColumnHeader();
    }

    @Override
    public String footer() {
      return style.cellTableFooter();
    }

    @Override
    public String header() {
      return style.cellTableHeader();
    }

    @Override
    public String hoveredRow() {
      return style.cellTableHoveredRow();
    }

    @Override
    public String hoveredRowCell() {
      return style.cellTableHoveredRowCell();
    }

    @Override
    public String keyboardSelectedCell() {
      return style.cellTableKeyboardSelectedCell();
    }

    @Override
    public String keyboardSelectedRow() {
      return style.cellTableKeyboardSelectedRow();
    }

    @Override
    public String keyboardSelectedRowCell() {
      return style.cellTableKeyboardSelectedRowCell();
    }

    @Override
    public String lastColumn() {
      return style.cellTableLastColumn();
    }

    @Override
    public String lastColumnFooter() {
      return style.cellTableLastColumnFooter();
    }

    @Override
    public String lastColumnHeader() {
      return style.cellTableLastColumnHeader();
    }

    @Override
    public String oddRow() {
      return style.cellTableOddRow();
    }

    @Override
    public String oddRowCell() {
      return style.cellTableOddRowCell();
    }

    @Override
    public String selectedRow() {
      return style.cellTableSelectedRow();
    }

    @Override
    public String selectedRowCell() {
      return style.cellTableSelectedRowCell();
    }

    @Override
    public String sortableHeader() {
      return style.cellTableSortableHeader();
    }

    @Override
    public String sortedHeaderAscending() {
      return style.cellTableSortedHeaderAscending();
    }

    @Override
    public String sortedHeaderDescending() {
      return style.cellTableSortedHeaderDescending();
    }

    @Override
    public String widget() {
      return style.cellTableWidget();
    }
  }

  /**
   * The default page size.
   */
  private static final int DEFAULT_PAGESIZE = 15;

  private static Resources DEFAULT_RESOURCES;

  private static Resources getDefaultResources() {
    if (DEFAULT_RESOURCES == null) {
      DEFAULT_RESOURCES = GWT.create(Resources.class);
    }
    return DEFAULT_RESOURCES;
  }

  /**
   * Create the default loading indicator using the loading image in the
   * specified {@link Resources}.
   *
   * @param resources the resources
   * @return a widget loading indicator
   */
  private static Widget createDefaultLoadingIndicator(Resources resources) {
    ImageResource loadingImg = resources.cellTableLoading();
    return (loadingImg == null) ? null : new Image(loadingImg);
  }

  final TableColElement colgroup;
  private final SimplePanel emptyTableWidgetContainer = new SimplePanel();
  private final SimplePanel loadingIndicatorContainer = new SimplePanel();

  /**
   * A {@link DeckPanel} to hold widgets associated with various loading states.
   */
  private final DeckPanel messagesPanel = new DeckPanel();

  private final Style style;
  private final TableElement table;
  private final TableSectionElement tbody;
  private final TableSectionElement tbodyLoading;
  private final TableCellElement tbodyLoadingCell;
  private final TableSectionElement tfoot;
  private final TableSectionElement thead;

  /**
   * Constructs a table with a default page size of 15.
   */
  public CellTable() {
    this(DEFAULT_PAGESIZE);
  }

  /**
   * Constructs a table with the given page size.
   *
   * @param pageSize the page size
   */
  public CellTable(final int pageSize) {
    this(pageSize, getDefaultResources());
  }

  /**
   * Constructs a table with a default page size of 15, and the given
   * {@link ProvidesKey key provider}.
   *
   * @param keyProvider an instance of ProvidesKey<T>, or null if the record
   *          object should act as its own key
   */
  public CellTable(ProvidesKey<T> keyProvider) {
    this(DEFAULT_PAGESIZE, keyProvider);
  }

  /**
   * Constructs a table with the given page size with the specified
   * {@link Resources}.
   *
   * @param pageSize the page size
   * @param resources the resources to use for this widget
   */
  public CellTable(int pageSize, Resources resources) {
    this(pageSize, resources, null);
  }

  /**
   * Constructs a table with the given page size and the given
   * {@link ProvidesKey key provider}.
   *
   * @param pageSize the page size
   * @param keyProvider an instance of ProvidesKey<T>, or null if the record
   *          object should act as its own key
   */
  public CellTable(int pageSize, ProvidesKey<T> keyProvider) {
    this(pageSize, getDefaultResources(), keyProvider);
  }

  /**
   * Constructs a table with the given page size, the specified
   * {@link Resources}, and the given key provider.
   *
   * @param pageSize the page size
   * @param resources the resources to use for this widget
   * @param keyProvider an instance of ProvidesKey<T>, or null if the record
   *          object should act as its own key
   */
  public CellTable(final int pageSize, Resources resources, ProvidesKey<T> keyProvider) {
    this(pageSize, resources, keyProvider, createDefaultLoadingIndicator(resources));
  }

  /**
   * Constructs a table with the specified page size, {@link Resources}, key
   * provider, and loading indicator.
   *
   * @param pageSize the page size
   * @param resources the resources to use for this widget
   * @param keyProvider an instance of ProvidesKey<T>, or null if the record
   *          object should act as its own key
   * @param loadingIndicator the widget to use as a loading indicator, or null
   *          to disable
   */
  public CellTable(final int pageSize, Resources resources, ProvidesKey<T> keyProvider,
      Widget loadingIndicator) {
    super(Document.get().createTableElement(), pageSize, new ResourcesAdapter(resources),
        keyProvider);
    this.style = resources.cellTableStyle();
    this.style.ensureInjected();

    table = getElement().cast();
    table.setCellSpacing(0);
    colgroup = Document.get().createColGroupElement();
    table.appendChild(colgroup);
    thead = table.createTHead();
    // Some browsers create a tbody automatically, others do not.
    if (table.getTBodies().getLength() > 0) {
      tbody = table.getTBodies().getItem(0);
    } else {
      tbody = Document.get().createTBodyElement();
      table.appendChild(tbody);
    }
    table.appendChild(tbodyLoading = Document.get().createTBodyElement());
    tfoot = table.createTFoot();
    setStyleName(resources.cellTableStyle().cellTableWidget());

    // Attach the messages panel.
    {
      tbodyLoadingCell = Document.get().createTDElement();
      TableRowElement tr = Document.get().createTRElement();
      tbodyLoading.appendChild(tr);
      tr.appendChild(tbodyLoadingCell);
      tbodyLoadingCell.setAlign("center");
      tbodyLoadingCell.appendChild(messagesPanel.getElement());
      adopt(messagesPanel);
      messagesPanel.add(emptyTableWidgetContainer);
      messagesPanel.add(loadingIndicatorContainer);
      loadingIndicatorContainer.setStyleName(style.cellTableLoading());
    }

    // Set the loading indicator.
    setLoadingIndicator(loadingIndicator); // Can be null.

    // Sink events.
    Set<String> eventTypes = new HashSet<String>();
    eventTypes.add("mouseover");
    eventTypes.add("mouseout");
    CellBasedWidgetImpl.get().sinkEvents(this, eventTypes);
  }

  @Override
  public void addColumnStyleName(int index, String styleName) {
    ensureTableColElement(index).addClassName(styleName);
  }

  /**
   * Return the height of the table body.
   *
   * @return an int representing the body height
   */
  public int getBodyHeight() {
    return tbody.getClientHeight();
  }

  /**
   * Return the height of the table header.
   *
   * @return an int representing the header height
   */
  public int getHeaderHeight() {
    return thead.getClientHeight();
  }

  @Override
  public void removeColumnStyleName(int index, String styleName) {
    if (index >= colgroup.getChildCount()) {
      return;
    }
    ensureTableColElement(index).removeClassName(styleName);
  }

  /**
   * {@inheritDoc}
   *
   * <p>
   * The layout behavior depends on whether or not the table is using fixed
   * layout.
   * </p>
   *
   * @see #setTableLayoutFixed(boolean)
   */
  @Override
  public void setColumnWidth(Column<T, ?> column, String width) {
    // Overridden to add JavaDoc comments about fixed layout.
    super.setColumnWidth(column, width);
  }

  /**
   * {@inheritDoc}
   *
   * <p>
   * The layout behavior depends on whether or not the table is using fixed
   * layout.
   * </p>
   *
   * @see #setTableLayoutFixed(boolean)
   */
  @Override
  public void setColumnWidth(Column<T, ?> column, double width, Unit unit) {
    // Overridden to add JavaDoc comments about fixed layout.
    super.setColumnWidth(column, width, unit);
  }

  @Override
  public void setEmptyTableWidget(Widget widget) {
    emptyTableWidgetContainer.setWidget(widget);
    super.setEmptyTableWidget(widget);
  }

  @Override
  public void setLoadingIndicator(Widget widget) {
    loadingIndicatorContainer.setWidget(widget);
    super.setLoadingIndicator(widget);
  }

  /**
   * <p>
   * Enable or disable fixed table layout.
   * </p>
   *
   * <p>
   * <h1>Fixed Table Layout</h1>
   * When using the fixed table layout, cell contents are truncated as needed,
   * which allows you to set the exact width of columns and the table. The
   * default column width is 0 (invisible). In order to see all columns, you
   * must set the width of the table (recommended 100%), or set the width of
   * every column in the table. The following conditions are true for fixed
   * layout tables:
   * <ul>
   * <li>
   * If the widths of <b>all</b> columns are set, the width becomes a weight and
   * the columns are resized proportionally.</li>
   * <li>If the widths of <b>some</b> columns are set using absolute values
   * (PX), those columns are fixed and the remaining width is divided evenly
   * over the other columns. If there is no remaining width, the other columns
   * will not be visible.</li>
   * <li>If the width of some columns are set in absolute values (PX) and others
   * are set in relative values (PCT), the absolute columns will be fixed and
   * the remaining width is divided proportionally over the PCT columns. This
   * allows users to define how the remaining width is allocated.</li>
   * </ul>
   * </p>
   *
   * @param isFixed true to use fixed table layout, false not to
   * @see <a href="http://www.w3.org/TR/CSS2/tables.html#width-layout">W3C HTML
   *      Specification</a>
   */
  public void setTableLayoutFixed(boolean isFixed) {
    if (isFixed) {
      table.getStyle().setTableLayout(TableLayout.FIXED);
    } else {
      table.getStyle().clearTableLayout();
    }
  }

  /**
   * Set the width of the width and specify whether or not it should use fixed
   * table layout. See {@link #setTableLayoutFixed(boolean)} for more
   * information about fixed layout tables.
   *
   * @param width the width of the table
   * @param isFixedLayout true to use fixed width layout, false not to
   * @see #setTableLayoutFixed(boolean)
   * @see <a href="http://www.w3.org/TR/CSS2/tables.html#width-layout">W3C HTML
   *      Specification</a>
   */
  public final void setWidth(String width, boolean isFixedLayout) {
    super.setWidth(width);
    setTableLayoutFixed(isFixedLayout);
  }

  @Override
  protected void doSetColumnWidth(int column, String width) {
    if (width == null) {
      ensureTableColElement(column).getStyle().clearWidth();
    } else {
      ensureTableColElement(column).getStyle().setProperty("width", width);
    }
  }

  @Override
  protected void doSetHeaderVisible(boolean isFooter, boolean isVisible) {
    setVisible(isFooter ? tfoot : thead, isVisible);
  }

  @Override
  protected TableSectionElement getTableBodyElement() {
    return tbody;
  }

  @Override
  protected TableSectionElement getTableFootElement() {
    return tfoot;
  }

  @Override
  protected TableSectionElement getTableHeadElement() {
    return thead;
  }

  /**
   * Called when the loading state changes.
   *
   * @param state the new loading state
   */
  @Override
  protected void onLoadingStateChanged(LoadingState state) {
    Widget message = null;
    if (state == LoadingState.LOADING) {
      // Loading indicator.
      message = loadingIndicatorContainer;
    } else if (state == LoadingState.LOADED && getPresenter().isEmpty()) {
      // Empty table.
      message = emptyTableWidgetContainer;
    }

    // Switch out the message to display.
    if (message != null) {
      messagesPanel.showWidget(messagesPanel.getWidgetIndex(message));
    }

    // Adjust the colspan of the messages panel container.
    tbodyLoadingCell.setColSpan(Math.max(1, getColumnCount()));

    // Show the correct container.
    showOrHide(getChildContainer(), message == null);
    showOrHide(tbodyLoading, message != null);

    // Fire an event.
    super.onLoadingStateChanged(state);
  }

  @Override
  protected void refreshColumnWidths() {
    super.refreshColumnWidths();

    /*
     * Set the width to zero for all col elements that appear after the last
     * column. Clearing the width would cause it to take up the remaining width
     * in a fixed layout table.
     */
    int colCount = colgroup.getChildCount();
    for (int i = getColumnCount(); i < colCount; i++) {
      doSetColumnWidth(i, "0px");
    }
  }

  /**
   * Get the {@link TableColElement} at the specified index, creating it if
   * necessary.
   *
   * @param index the column index
   * @return the {@link TableColElement}
   */
  private TableColElement ensureTableColElement(int index) {
    // Ensure that we have enough columns.
    for (int i = colgroup.getChildCount(); i <= index; i++) {
      colgroup.appendChild(Document.get().createColElement());
    }
    return colgroup.getChild(index).cast();
  }
}
TOP

Related Classes of com.google.gwt.user.cellview.client.CellTable$ResourcesAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.