Package com.extjs.gxt.ui.client.widget.table

Source Code of com.extjs.gxt.ui.client.widget.table.TableView

/*
* Ext GWT - Ext for GWT
* Copyright(c) 2007, 2008, Ext JS, LLC.
* licensing@extjs.com
*
* http://extjs.com/license
*/
package com.extjs.gxt.ui.client.widget.table;

import java.util.Collections;
import java.util.Comparator;

import com.extjs.gxt.ui.client.Events;
import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.XDOM;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.TableEvent;
import com.extjs.gxt.ui.client.widget.ComponentHelper;
import com.extjs.gxt.ui.client.widget.tips.ToolTip;
import com.extjs.gxt.ui.client.widget.tips.ToolTipConfig;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Widget;

/**
* This class encapsulates the user interface of a {@link Table}.
*/
public class TableView {

  private static String bodyHTML;

  static {
    StringBuffer sb = new StringBuffer();
    sb.append("<div style='overflow: hidden;'>");
    sb.append("<div style='overflow: scroll;'>");
    sb.append("<div class='my-tbl-data'></div>");
    sb.append("</div></div>");
    bodyHTML = sb.toString();
  }

  public static native void markRendered(TableItem item) /*-{
   item.@com.extjs.gxt.ui.client.widget.Component::rendered = true;
   }-*/;

  // styles
  protected String baseStyle = "my-tbl-item";
  protected String overStyle = baseStyle + "-over";
  protected String selStyle = baseStyle + "-sel";
  protected String cellStyle = baseStyle + "-" + "cell";
  protected String cellOverflowStyle = cellStyle + "-" + "overflow";
  protected String textStyle = cellStyle + "-text";
  protected String widgetStyle = cellStyle + "-widget";
  protected String rowSelector = ".my-tbl-item";

  protected String cellSelector = ".my-tbl-item-cell";
  protected TableColumnModel cm;
  protected El dataEl, scrollEl;
  protected Table table;
  protected int scrollBarWidth;

  private TableItem overItem;
  private int overCol;
  private ToolTip toolTip;
  private boolean enableCellTooltips;

  public void applyCellStyles(TableItem item) {
    if (item.cellStyles != null) {
      for (int i = 0; i < item.cellStyles.length; i++) {
        setCellStyle(item, i, item.cellStyles[i]);
      }
    }
  }

  public void bulkRender() {
    int count = table.getItemCount();
    int cols = cm.getColumnCount();

    TableColumn[] columns = new TableColumn[cols];
    int[] widths = new int[cols];
    String[] align = new String[cols];
    for (int i = 0; i < columns.length; i++) {
      columns[i] = cm.getColumn(i);
      widths[i] = cm.getWidthInPixels(i) - (table.getVerticalLines() && !XDOM.isVisibleBox ? 1 : 0);
      columns[i].lastWidth = widths[i];
      HorizontalAlignment ha = columns[i].getAlignment();
      switch (ha) {
        case LEFT:
          align[i] = "left";
          break;
        case CENTER:
          align[i] = "center";
          break;
        case RIGHT:
          align[i] = "right";
          break;
      }
    }

    StringBuffer sb = new StringBuffer();

    for (int i = 0; i < count; i++) {
      TableItem item = table.getItem(i);
      item.init(table);
      markRendered(item);
      Object[] values = item.getValues();
      Object[] styles = item.getCellStyles();
      Object[] svalues = new Object[cols];
      String[] tips = item.getCellToolTips();
      if (tips != null) {
        enableCellTooltips = true;
      }
      for (int k = 0; k < cols; k++) {
        svalues[k] = table.getRenderedValue(item, k, values[k]);
      }

      sb.append("<div class=my-tbl-item><table cellpadding=0 cellspacing=0 tabIndex=1><tr>");
      for (int j = 0; j < cols; j++) {
        String display = columns[j].isHidden() ? "none" : "static";
        String tip = tips == null ? "" : "qtip='" + tips[j] + "'";
        sb.append("<td " + tip + " class='" + cellStyle + " my-tbl-td-" + j + "' style='display: "
            + display + ";width: " + widths[j] + "px' index=" + j + "><div class='"
            + cellOverflowStyle + " my-tbl-td-inner-" + j + "' style='width:" + widths[j]
            + "'><div class='my-tbl-td-cell-" + j + " " + textStyle
            + (styles == null ? "" : " " + styles[j]) + "' style='text-align:" + align[j] + "'>"
            + svalues[j] + "</div></div></td>");

      }
      sb.append("</tr></table></div>");
    }

    dataEl.dom.setInnerHTML(sb.toString());

    Element[] elems = dataEl.select(".my-tbl-item");
    int ct = table.getItemCount();
    for (int i = 0; i < ct; i++) {
      TableItem item = table.getItem(i);
      item.setElement(elems[i]);
      applyCellStyles(item);
    }

  }

  public void clearHoverStyles() {
    int count = table.getItemCount();
    for (int i = 0; i < count; i++) {
      TableItem item = table.getItem(i);
      onHighlightRow(item, false);
    }
  }

  public void doSort(int index, final SortDir direction) {
    TableColumn column = table.getColumn(index);
    final Comparator comparator = direction.comparator(column.getComparator());
    final int col = index;
    Collections.sort(table.getItems(), new Comparator() {
      public int compare(Object arg0, Object arg1) {
        TableItem item1 = (TableItem) arg0;
        TableItem item2 = (TableItem) arg1;
        Object o1 = item1.getValue(col);
        Object o2 = item2.getValue(col);
        return comparator.compare(o1, o2);
      }
    });

    reorderItems();
    updateIndexes(0);
  }

  public El getDataEl() {
    return dataEl;
  }

  public El getScrollEl() {
    return scrollEl;
  }

  public Element getTextCellElement(TableItem item, int cell) {
    return getTextCellInternal(item.getElement(), cell);
  }

  public native Element getTextCellInternal(Element elem, int column) /*-{
   return elem.firstChild.firstChild.firstChild.childNodes[column].firstChild.firstChild;
   }-*/;

  public void init(final Table table) {
    this.table = table;
    this.cm = table.getColumnModel();

    Listener l = new Listener<TableEvent>() {

      public void handleEvent(TableEvent be) {
        switch (be.type) {
          case Events.HeaderChange: {
            TableColumn c = cm.getColumn(be.columnIndex);
            table.getTableHeader().getColumnUI(be.columnIndex).onTextChange(c.getText());
            break;
          }
          case Events.WidthChange:
            table.getTableHeader().resizeColumn(be.columnIndex, true);
            break;
          case Events.HiddenChange: {
            TableColumn c = cm.getColumn(be.columnIndex);
            table.getTableHeader().showColumn(be.columnIndex, !c.isHidden());
            break;
          }
        }
      }

    };

    cm.addListener(Events.HeaderChange, l);
    cm.addListener(Events.WidthChange, l);
    cm.addListener(Events.HiddenChange, l);

  }

  protected void onItemEvent(TableEvent te) {
    TableItem item = te.item;
    int col = te.cellIndex;

    if (enableCellTooltips) {
      switch (te.type) {
        case Event.ONMOUSEOVER:
        case Event.ONMOUSEOUT:
          if (item != null && col != -1) {
            Element cell = getCell(item, col);
            if (cell != null) {
              if (overItem == item && overCol == col) {
                return;
              }
              overItem = item;
              overCol = col;
              String tip = cell.getAttribute("qtip");
              if (tip.equals("null")) {
                tip = null;
              }
              if (toolTip == null) {
                toolTip = table.getToolTip();
                if (toolTip == null) {
                  toolTip = new ToolTip(table);
                }
              }

              ToolTipConfig config = toolTip.getConfig();
              config.setText(tip);
              config.setTarget(cell);
              config.setEnabled(tip != null);
              toolTip.update(config);
            }
          }
          break;
      }
    }
  }

  protected Element getCell(TableItem item, int cell) {
    return item.el().select("td.my-tbl-item-cell")[cell];
  }

  public void onHighlightRow(TableItem item, boolean highlight) {
    if (highlight) {
      item.addStyleName(overStyle);
    } else {
      item.removeStyleName(overStyle);
    }
  }

  public void onSelectItem(TableItem item, boolean select) {
    if (select) {
      item.addStyleName(selStyle);
    } else {
      item.removeStyleName(selStyle);
      item.removeStyleName(overStyle);
    }
  }

  public void removeItem(TableItem item) {
    int idx = table.indexOf(item);
    if (item.isRendered()) {
      item.el().removeFromParent();
    }
    updateIndexes(idx);
  }

  public void render() {
    scrollBarWidth = XDOM.getScrollBarWidth();

    Element div = DOM.createDiv();

    div.setInnerHTML(bodyHTML.toString());
    scrollEl = new El(El.fly(div).getSubChild(2));
    dataEl = scrollEl.firstChild();
    DOM.appendChild(table.getElement(), DOM.getFirstChild(div));

    if (table.getVerticalLines()) {
      table.addStyleName("my-tbl-vlines");
    }

    if (!GXT.isIE) {
      DOM.setElementPropertyInt(table.getElement(), "tabIndex", 0);
    }

    DOM.sinkEvents(scrollEl.dom, Event.ONSCROLL);

    if (!GXT.isGecko) {
      table.disableTextSelection(true);
    }

    table.el().addEventsSunk(Event.ONCLICK | Event.ONDBLCLICK | Event.MOUSEEVENTS | Event.KEYEVENTS);
  }

  public void renderItem(TableItem item, int index) {
    item.setStyleName(baseStyle);
    item.init(table);

    int cols = cm.getColumnCount();
    Object[] values = item.getValues();
    Object[] styles = item.getCellStyles();
    String[] tips = item.getCellToolTips();
    Object[] svalues = new Object[cols];
    if (tips != null) {
      enableCellTooltips = true;
    }
    for (int i = 0; i < cols; i++) {
      if (!item.hasWidgets && values[i] instanceof Widget) {
        item.hasWidgets = true;
        if (table.bulkRender) {
          throw new RuntimeException(
              "Bulk rendering must be disabled when adding widgets to table items");
        }
      }
      svalues[i] = table.getRenderedValue(item, i, values[i]);
    }

    StringBuffer sb = new StringBuffer();
    sb.append("<table cellpadding=0 cellspacing=0 tabIndex=1><tr>");
    for (int i = 0; i < cols; i++) {
      TableColumn c = cm.getColumn(i);
      String display = c.isHidden() ? "none" : "static";
      int w = table.getColumnModel().getWidthInPixels(c.index);
      if (!XDOM.isVisibleBox) {
        w -= table.getVerticalLines() ? 1 : 0;
      }
      HorizontalAlignment align = c.getAlignment();
      String salign = "left";
      if (align == HorizontalAlignment.CENTER) {
        salign = "center";
      } else if (align == HorizontalAlignment.RIGHT) {
        salign = "right";
      }
      String tip = tips == null ? "" : "qtip='" + tips[i] + "'";
      sb.append("<td " + tip + " class=" + cellStyle + " style='display: " + display + ";width: "
          + w + "px' index=" + i + "><div class=" + cellOverflowStyle + " style='width:" + w
          + "'><div class='" + textStyle + (styles == null ? "" : " " + styles[i])
          + "' style='text-align:" + salign + "'>" + svalues[i] + "</div></div></td>");
    }
    sb.append("</tr></table>");

    item.render(dataEl.dom, index);
    item.getElement().setInnerHTML(sb.toString());

    if (item.hasWidgets) {
      for (int i = 0; i < cols; i++) {
        if (values[i] instanceof Widget) {
          Widget w = (Widget) values[i];
          Element text = getTextCellElement(item, i);
          El textEl = El.fly(text);
          textEl.dom.setInnerHTML("");
          textEl.dom.setClassName(widgetStyle);
          textEl.dom.appendChild(w.getElement());
          if (table.isAttached()) {
            ComponentHelper.doAttach(w);
          }
        }
      }
    }
    applyCellStyles(item);

    item.cellsRendered = true;

    updateIndexes(index);
  }

  public void renderItems() {
    if (table.getBulkRender()) {
      bulkRender();
    } else {
      int count = table.getItemCount();
      for (int i = 0; i < count; i++) {
        TableItem item = table.getItem(i);
        renderItem(item, i);
      }

    }
    updateIndexes(0);
  }

  public void renderItemValue(TableItem item, int index, Object value) {
    Element textElem = getTextCellElement(item, index);
    if (textElem != null) {
      Element child = DOM.getChild(textElem, 0);
      if (child != null) {
        DOM.removeChild(textElem, DOM.getChild(textElem, 0));
      }
      DOM.setInnerHTML(textElem, "");
      if (value instanceof Widget) {
        Widget widget = (Widget) value;
        XDOM.setStyleName(textElem, widgetStyle);
        DOM.appendChild(textElem, widget.getElement());
        if (table.isAttached()) {
          ComponentHelper.doAttach(widget);
        }
      } else {
        String s = table.getRenderedValue(item, index, value);
        textElem.setInnerHTML(s);
      }
    }
    applyCellStyles(item);
  }

  /**
   * Sorts the table items based on the current order.
   */
  public void reorderItems() {
    dataEl.removeChildren();
    int numRows = table.getItemCount();
    for (int i = 0; i < numRows; i++) {
      TableItem item = table.getItem(i);
      dataEl.dom.appendChild(item.getElement());
    }
    table.getSelectionModel().refresh();
  }

  public void resize() {
    if (table != null && table.isRendered()) {
      int width = table.getOffsetWidth();
      int headerHeight = table.getTableHeader().getOffsetHeight();
      int bodyHeight = table.getOffsetHeight() - headerHeight;
      int bodyWidth = width;

      if (table.isAutoHeight()) {
        scrollEl.setHeight("auto");
        dataEl.setHeight("auto");
        bodyHeight = dataEl.getHeight();
        bodyHeight += table.el().getBorderWidth("tb");
      }

      int columnModelWidth = cm.getTotalWidth();
      dataEl.setWidth(Math.max(width, columnModelWidth));
      table.getTableHeader().setWidth(columnModelWidth);

      bodyHeight -= table.el().getBorderWidth("tb");
      bodyWidth -= table.el().getBorderWidth("lr");

      if (dataEl.getHeight() < bodyHeight) {
        scrollEl.setStyleAttribute("overflowY", "hidden");
      } else {
        scrollEl.setStyleAttribute("overflowY", "auto");
      }

      if (table.getHorizontalScroll()) {
        scrollEl.setStyleAttribute("overflowX", "auto");
        if (columnModelWidth < width) {
          scrollEl.setStyleAttribute("overflowX", "hidden");
          table.getTableHeader().el().setLeft(0);
          scrollEl.setScrollLeft(0);
        }
      }

      if (table.isAutoHeight()) {
        bodyHeight = -1;
      }
      scrollEl.setSize(bodyWidth, bodyHeight);
    }
  }

  public void resizeCells(int columnIndex) {
    TableColumn c = cm.getColumn(columnIndex);
    int w = cm.getWidthInPixels(c.index);
    if (!XDOM.isVisibleBox) {
      w -= table.getVerticalLines() ? 1 : 0;
    }
    if (c.lastWidth != 0 && c.lastWidth == w) {
      return;
    }
    c.lastWidth = w;

    int rows = table.getItemCount();
    for (int j = 0; j < rows; j++) {
      TableItem item = table.getItem(j);
      sizeCell(item.getElement(), columnIndex, w);
      if (j == 0) {
        showColumn(item.getElement(), !c.isHidden(), columnIndex);
      }
    }
  }

  public void setCellStyle(TableItem item, int index, String style) {
    if (item.cellsRendered) {
      Element cell = getTextCellElement(item, index);
      XDOM.setStyleName(cell, textStyle + " " + style);
    }
  }

  public native void showColumn(Element elem, boolean show, int index) /*-{
   var tbl = elem.firstChild;
   var cell = tbl.firstChild.firstChild.childNodes[index]
   cell.style.display = show ? '' : 'none';
   }-*/;

  public void showColumn(int index, boolean show) {
    int count = table.getItemCount();
    for (int i = 0; i < count; i++) {
      showColumn(table.getItem(i).getElement(), show, index);
    }
  }

  public native void sizeCell(Element elem, int index, int width) /*-{
   var tbl = elem.firstChild;
   var cell = tbl.firstChild.firstChild.childNodes[index];
   cell.style.width = width;
   cell.firstChild.style.width = width;
   }-*/;

  public void sort(int index, SortDir direction) {
    doSort(index, direction);
  }

  protected Element findCell(Element elem) {
    if (elem == null) {
      return null;
    }
    return fly(elem).findParentElement(cellSelector, 3);
  }

  protected int findCellIndex(Element elem) {
    Element cell = findCell(elem);
    if (cell != null) {
      return getCellIndex(cell);
    }
    return -1;
  }

  protected Element findRow(Element el) {
    if (el == null) {
      return null;
    }
    return fly(el).findParentElement(rowSelector, 10);
  }

  protected int findRowIndex(Element elem) {
    Element r = findRow(elem);
    return r != null ? r.getPropertyInt("rowIndex") : -1;
  }

  protected El fly(Element elem) {
    return El.fly(elem);
  }

  protected int getCellIndex(Element elem) {
    if (elem != null) {
      String index = elem.getAttribute("index");
      if (index.length() != 0) {
        return Integer.parseInt(index);
      }
    }
    return -1;
  }

  private void updateIndexes(int start) {
    int count = table.getItemCount();
    for (int i = start; i < count; i++) {
      TableItem item = table.getItem(i);
      item.getElement().setPropertyInt("rowIndex", i);
    }
  }

}
TOP

Related Classes of com.extjs.gxt.ui.client.widget.table.TableView

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.