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

Source Code of com.extjs.gxt.ui.client.widget.tree.Tree

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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.PartFactory;
import com.extjs.gxt.ui.client.PartProvider;
import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.aria.FocusFrame;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.ContainerEvent;
import com.extjs.gxt.ui.client.event.TreeEvent;
import com.extjs.gxt.ui.client.util.KeyNav;
import com.extjs.gxt.ui.client.widget.Container;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.selection.Selectable;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
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.Accessibility;

/**
* A standard hierarchical tree widget. The tree contains a hierarchy of
* <code>TreeItems</code> that the user can open, close, and select.
*
* <p/>
* The root item cannot be displayed.
*
* <dt><b>Events:</b></dt>
*
* <dd><b>BeforeAdd</b> : TreeEvent(item, child, index)<br>
* <div>Fires before a item is added or inserted. Listeners can cancel the
* action by calling {@link BaseEvent#setCancelled(boolean)}.</div>
* <ul>
* <li>item : this</li>
* <li>child : the item being added</li>
* <li>index : the index at which the item will be added</li>
* </ul>
* </dd>
*
* <dd><b>BeforeRemove</b> : TreeEvent(item, child)<br>
* <div>Fires before a item is removed. Listeners can cancel the action by
* calling {@link BaseEvent#setCancelled(boolean)}.</div>
* <ul>
* <li>item : this</li>
* <li>child : the item being removed</li>
* </ul>
* </dd>
*
* <dd><b>BeforeExpand</b> : TreeEvent(item)<br>
* <div>Fires before a item is expanded. Listeners can cancel the action by
* calling {@link BaseEvent#setCancelled(boolean)}.</div>
* <ul>
* <li>item : this</li>
* </ul>
* </dd>
*
* <dd><b>BeforeCollapse</b> : TreeEvent(item)<br>
* <div>Fires before a item is collapsed. Listeners can cancel the action by
* calling {@link BaseEvent#setCancelled(boolean)}.</div>
* <ul>
* <li>item : this</li>
* </ul>
* </dd>
*
* <dd><b>Add</b> : TreeEvent(item, child, index)<br>
* <div>Fires after a item has been added or inserted.</div>
* <ul>
* <li>item : this</li>
* <li>child : the item that was added</li>
* <li>index : the index at which the item will be added</li>
* </ul>
* </dd>
*
* <dd><b>Remove</b> : TreeEvent(tree, item, child)<br>
* <div>Fires after a item has been removed.</div>
* <ul>
* <li>tree : this</li>
* <li>item : item</li>
* <li>child : the item being removed</li>
* </ul>
* </dd>
*
* <dd><b>BeforeSelect</b> : TreeEvent(tree, item)<br>
* <div>Fires before a item is selected. Listeners can cancel the action by
* calling {@link BaseEvent#setCancelled(boolean)}.</div>
* <ul>
* <li>tree : this</li>
* <li>item : the selected item</li>
* </ul>
* </dd>
*
* <dd><b>SelectionChange</b> : TreeEvent(tree, selected)<br>
* <div>Fires after the tree selection changes.</div>
* <ul>
* <li>tree : this</li>
* <li>selected : the selected items</li>
* </ul>
* </dd>
*
* <dd><b>Expand</b> : TreeEvent(tree, item)<br>
* <div>Fires after a item has been expanded.</div>
* <ul>
* <li>item : this</li>
* </ul>
* </dd>
*
* <dd><b>Collapse</b> : TreeEvent(tree, item)<br>
* <div>Fires after a item is collapsed.</div>
* <ul>
* <li>item : this</li>
* </ul>
* </dd>
*
* <dd><b>CheckChange</b> : TreeEvent(tree, item)<br>
* <div>Fires after a check state change.</div>
* <ul>
* <li>item : this</li>
* </ul>
* </dd>
*
* <dd><b>ContextMenu</b> : TreeEvent(tree)<br>
* <div>Fires before the tree's context menu is shown.</div>
* <ul>
* <li>component : this</li>
* </ul>
* </dd>
*
* <dd><b>KeyPress</b> : TreeEvent(tree, event)<br>
* <div>Fires when a key is pressed.</div>
* <ul>
* <li>event : dom event</li>
* </ul>
* </dd>
* </dl>
*
* <dl>
* <dt>Inherited Events:</dt>
* <dd>BoxComponent Move</dd>
* <dd>BoxComponent Resize</dd>
* <dd>Component Enable</dd>
* <dd>Component Disable</dd>
* <dd>Component BeforeHide</dd>
* <dd>Component Hide</dd>
* <dd>Component BeforeShow</dd>
* <dd>Component Show</dd>
* <dd>Component Attach</dd>
* <dd>Component Detach</dd>
* <dd>Component BeforeRender</dd>
* <dd>Component Render</dd>
* <dd>Component BrowserEvent</dd>
* <dd>Component BeforeStateRestore</dd>
* <dd>Component StateRestore</dd>
* <dd>Component BeforeStateSave</dd>
* <dd>Component SaveState</dd>
* </dl>
*
* <dl>
* <dt><b>CSS:</b></dt>
* <dd>.my-tree (the tree itself)</dd>
* <dd>.my-tree-item-text span (the tree item text)</dd>
* </dl>
*
* @deprecated see {@link TreePanel}
*/
public class Tree extends Container<TreeItem> implements Selectable<TreeItem> {

  /**
   * Check cascade enum.
   */
  public enum CheckCascade {
    CHILDREN, NONE, PARENTS;
  }

  /**
   * Check nodes enum.
   */
  public enum CheckNodes {
    BOTH, LEAF, PARENT;
  }

  /**
   * Joint enum.
   */
  public enum Joint {
    NONE(0), COLLAPSED(1), EXPANDED(2);

    private int value;

    private Joint(int value) {
      this.value = value;
    }

    public int value() {
      return value;
    }
  }

  public static final String DEFAULT_TREE_ITEM_ID = "tree.item.default";
  public static final String FAST_TREE_ITEM_ID = "tree.item.fast";
  static {
    PartFactory.registerProvider(new PartProvider() {
      public Object createPart(String id) {
        if (id.equals(DEFAULT_TREE_ITEM_ID)) {
          return new DefaultTreeItemUI();
        } else if (id.equals(FAST_TREE_ITEM_ID)) {
          return new FastTreeItemUI();
        }
        return null;
      }
    });
  }

  protected boolean isViewer;
  protected TreeItem root;
  protected TreeSelectionModel sm;
  private boolean animate = true;
  private boolean checkable;
  private CheckNodes checkNodes = CheckNodes.BOTH;
  private CheckCascade checkStyle = CheckCascade.PARENTS;
  private int indentWidth = 18;
  private Map<String, TreeItem> nodeHash;
  private TreeStyle style = new TreeStyle();
  private String treeItemPartId = DEFAULT_TREE_ITEM_ID;
  private String itemSelector = ".x-tree-item";

  /**
   * Returns the item selector.
   *
   * @return the item selector
   */
  public String getItemSelector() {
    return itemSelector;
  }

  /**
   * Sets the CSS selector used to retrieve tree items after bulk rendering
   * (defaults to '.x-tree-item').
   *
   * @param itemSelector the item selector
   */
  public void setItemSelector(String itemSelector) {
    this.itemSelector = itemSelector;
  }

  /**
   * Creates a new single select tree.
   */
  public Tree() {
    attachChildren = false;
    baseStyle = "my-tree";
    focusable = true;
    createRootItem();
    root.root = true;
    nodeHash = new HashMap<String, TreeItem>();
    setSelectionModel(new TreeSelectionModel());
  }

  /**
   * Collapses all item's.
   */
  public void collapseAll() {
    boolean anim = animate;
    if (anim) animate = false;
    root.setExpanded(false, true);
    if (anim) animate = true;
  }

  /**
   * Expands all item's.
   */
  public void expandAll() {
    boolean anim = animate;
    if (anim) animate = false;
    root.setExpanded(true, true);
    if (anim) animate = true;
  }

  /**
   * Expands a specified path. A path can be retrieved from a tree item with
   * {@link TreeItem#getPath()}.
   *
   * @param path the path to expand
   * @return <code>true</code> if all paths expanded
   */
  public boolean expandPath(String path) {
    if (path == null) return false;
    String[] ids = path.split(",");
    if (ids.length == 0) return false;
    if (ids[0].equals(root.getId())) {
      root.setExpanded(true);

      TreeItem current = root;
      for (int i = 1; i < ids.length; i++) {
        String id = ids[i];
        boolean match = false;
        for (int j = 0; j < current.getItemCount(); j++) {
          TreeItem child = current.getItem(j);
          if (!match && child.getId().equals(id)) {
            child.setExpanded(true);
            current = child;
            match = true;
            break;
          }
        }
        if (!match) {
          return false;
        }
      }

    }
    return true;
  }

  /**
   * Returns the tree whose element or child elements match the passed target.
   *
   * @param element the target element
   * @return the matching tree item or <code>null</code> if no match
   */
  public TreeItem findItem(Element element) {
    Element elem = fly(element).findParentElement(itemSelector, 15);
    if (elem != null) {
      String id = elem.getId();
      if (id != null && !id.equals("")) {
        TreeItem item = getItemById(id);
        return item;
      }
    }
    return null;
  }

  /**
   * Returns the total number of items contained in the tree excluding the root
   * item.
   *
   * @return the total item count
   */
  public int getAllItemCount() {
    return nodeHash.size();
  }

  /**
   * Returns all tree item's contained by the tree.
   *
   * @return all tree item's
   */
  public List<TreeItem> getAllItems() {
    List<TreeItem> temp = new ArrayList<TreeItem>();
    temp.add(root);
    temp.addAll(nodeHash.values());
    return temp;
  }

  /**
   * Returns true if animations are enabled.
   *
   * @return the animate state
   */
  public boolean getAnimate() {
    return animate;
  }

  /**
   * Returns true if check boxs are enabled.
   *
   * @return the checkbox state
   */
  public boolean getCheckable() {
    return checkable;
  }

  /**
   * Returns a list of id's for all checked items.
   *
   * @return the list of checked id's
   */
  public List<TreeItem> getChecked() {
    List<TreeItem> list = new ArrayList<TreeItem>();
    Iterator<TreeItem> it = nodeHash.values().iterator();
    while (it.hasNext()) {
      TreeItem item = it.next();
      if (item.isChecked()) {
        list.add(item);
      }
    }
    return list;
  }

  /**
   * Returns the child nodes value.
   *
   * @return the child nodes value
   */
  public CheckNodes getCheckNodes() {
    return checkNodes;
  }

  /**
   * The check style value.
   *
   * @return the check style
   */
  public CheckCascade getCheckStyle() {
    return checkStyle;
  }

  @Override
  public Menu getContextMenu() {
    // made public
    return super.getContextMenu();
  }

  /**
   * Returns the indent width.
   *
   * @return the indent width
   */
  public int getIndentWidth() {
    return indentWidth;
  }

  @Override
  public TreeItem getItem(int index) {
    return getRootItem().getItem(index);
  }

  /**
   * Returns the item by id.
   *
   * @param id the id of the element to return
   * @return the item
   */
  public TreeItem getItemById(String id) {
    return nodeHash.get(id);
  }

  /**
   * Returns the item icon style.
   *
   * @return the icon style
   * @deprecated see {@link TreeStyle#getLeafIconStyle()}
   */
  public String getItemIconStyle() {
    return style.getLeafIconStyle();
  }

  /**
   * Returns the node icon style.
   *
   * @return the icon style
   * @deprecated see {@link TreeStyle#getNodeCloseIconStyle()}
   */
  public String getNodeIconStyle() {
    return style.getNodeCloseIconStyle();
  }

  /**
   * Returns the open node icon style.
   *
   * @return the icon style
   * @deprecated see {@link TreeStyle#getNodeOpenIconStyle()}
   */
  public String getOpenNodeIconStyle() {
    return style.getNodeOpenIconStyle();
  }

  /**
   * Returns the tree's root item. The root item cannot be displayed.
   *
   * @return the root item
   */
  public TreeItem getRootItem() {
    return root;
  }

  /**
   * Returns the selected item.
   *
   * @return the item
   */
  public TreeItem getSelectedItem() {
    return (TreeItem) sm.getSelectedItem();
  }

  /**
   * Returns the selected items.
   *
   * @return the selected items
   */
  public List<TreeItem> getSelectedItems() {
    return sm.getSelectedItems();
  }

  public SelectionMode getSelectionMode() {
    return sm.getSelectionMode();
  }

  /**
   * Returns the tree's selection model.
   *
   * @return the selection model
   */
  public TreeSelectionModel getSelectionModel() {
    return sm;
  }

  /**
   * Returns the tree's style.
   *
   * @return the tree style
   */
  public TreeStyle getStyle() {
    return style;
  }

  /**
   * Returns the tree item part id.
   *
   * @return the part id
   */
  public String getTreeItemPartId() {
    return treeItemPartId;
  }

  @Override
  public void onComponentEvent(ComponentEvent ce) {
    super.onComponentEvent(ce);
    TreeEvent te = (TreeEvent) ce;
    if (te.getItem() != null) {
      te.getItem().onComponentEvent(te);
    }

    int type = ce.getEventTypeInt();
    switch (type) {
      case Event.ONFOCUS:
        onFocus(ce);
        break;
    }
  }

  protected void onFocus(ComponentEvent ce) {
    if (GXT.isFocusManagerEnabled()) {
      FocusFrame.get().frame(this);
    }
  }

  public void onSelectChange(TreeItem item, boolean select) {
    item.getUI().onSelectedChange(select);
  }

  @Override
  public boolean removeAll() {
    getRootItem().removeAll();
    nodeHash.clear();
    return true;
  }

  /**
   * Sets whether expand /collapse should be animated (defaults to true).
   *
   * @param animate the animate state
   */
  public void setAnimate(boolean animate) {
    this.animate = animate;
  }

  /**
   * Sets whether checkboxes are used in the tree.
   *
   * @param checkable true for checkboxes
   */
  public void setCheckable(boolean checkable) {
    this.checkable = checkable;
  }

  /**
   * Sets which tree items will display a check box (defaults to BOTH).
   * <p>
   * Valid values are:
   * <ul>
   * <li>BOTH - both nodes and leafs</li>
   * <li>PARENT - only nodes with children</li>
   * <li>LEAF - only leafs</li>
   * </ul>
   *
   * @param checkNodes the child nodes value
   */
  public void setCheckNodes(CheckNodes checkNodes) {
    this.checkNodes = checkNodes;
  }

  /**
   * Sets the cascading behavior for check tree (defaults to PARENTS).
   * <p>
   * Valid values are:
   * <ul>
   * <li>NONE - no cascading</li>
   * <li>PARENTS - cascade to parents</li>
   * <li>CHILDREN - cascade to children</li>
   * </ul>
   *
   * @param checkStyle the child style
   */
  public void setCheckStyle(CheckCascade checkStyle) {
    this.checkStyle = checkStyle;
  }

  @Override
  public void setContextMenu(Menu menu) {
    super.setContextMenu(menu);
  }

  /**
   * Sets the number of pixels child items are indented. Default value is 18.
   *
   * @param indentWidth the indent width
   */
  public void setIndentWidth(int indentWidth) {
    this.indentWidth = indentWidth;
  }

  /**
   * Sets the global icon style for leaf tree items. Individual tree items can
   * override this value by setting the the item's icon style.
   *
   * @param itemImageStyle the image style
   * @deprecated see {@link TreeStyle#setLeafIconStyle(String)}
   */
  public void setItemIconStyle(String itemImageStyle) {
    style.setLeafIconStyle(itemImageStyle);
  }

  /**
   * The global icon style for tree items with children (defaults to
   * 'tree-folder'). Individual tree items can override this value by setting
   * the the item's icon style.
   *
   * @param nodeIconStyle the node icon style
   * @deprecated see {@link TreeStyle#setNodeCloseIconStyle(String)}
   */
  public void setNodeIconStyle(String nodeIconStyle) {
    style.setNodeCloseIconStyle(nodeIconStyle);
  }

  /**
   * Sets the global icon style for expanded tree items (defaults to
   * 'tree-folder-open'). Individual tree items can override this value by
   * setting the the item's icon style.
   *
   * @param openNodeIconStyle the open node icon style
   * @deprecated see {@link TreeStyle#setNodeOpenIconStyle(String)}
   */
  public void setOpenNodeIconStyle(String openNodeIconStyle) {
    style.setNodeOpenIconStyle(openNodeIconStyle);
  }

  public void setSelectedItem(TreeItem item) {
    sm.select(item, false);
  }

  public void setSelectedItems(List<TreeItem> items) {
    sm.select(items, false);
  }

  /**
   * Sets the table's selection mode.
   *
   * @param mode the selection mode
   */
  public void setSelectionMode(SelectionMode mode) {
    setSelectionModel(new TreeSelectionModel(mode));
  }

  /**
   * Sets the tree's selection model.
   *
   * @param sm the tree selection model
   */
  public void setSelectionModel(TreeSelectionModel sm) {
    assert sm != null;
    if (this.sm != null) {
      this.sm.bind(null);
    }
    this.sm = sm;
    sm.bind(this);
  }

  /**
   * Sets the part id used to obtain new tree item ui instances (defaults to
   * {@value #DEFAULT_TREE_ITEM_ID}.
   *
   * @param treeItemPartId the tree item part id
   */
  public void setTreeItemPartId(String treeItemPartId) {
    this.treeItemPartId = treeItemPartId;
  }

  @Override
  protected ComponentEvent createComponentEvent(Event event) {
    return new TreeEvent(this, event == null ? null : findItem(DOM.eventGetTarget(event)));
  }

  @SuppressWarnings("rawtypes")
  @Override
  protected ContainerEvent createContainerEvent(TreeItem item) {
    return new TreeEvent(this, item);
  }

  protected void createRootItem() {
    root = new RootTreeItem(this);
    root.tree = this;
  }

  @Override
  protected void onRender(Element target, int index) {
    setElement(DOM.createDiv(), target, index);
    super.onRender(target, index);

    root.render(getElement());

    if (!root.childrenRendered) {
      root.renderChildren();
    }

    addStyleName("x-ftree-no-lines x-ftree-arrows");

    disableTextSelection(true);

    if (GXT.isFocusManagerEnabled()) {
      new KeyNav<ComponentEvent>(this) {
        @Override
        public void onDown(ComponentEvent ce) {
          if (getSelectedItems().size() == 0 && getRootItem().getItemCount() > 0) {
            setSelectedItem(getRootItem().getItem(0));
          }
        }
      };
      setAnimate(false);
    }

    el().setTabIndex(0);
    el().setElementAttribute("hideFocus", "true");

    Accessibility.setRole(getElement(), Accessibility.ROLE_TREE);

    sinkEvents(Event.ONCLICK | Event.ONDBLCLICK | Event.KEYEVENTS | Event.MOUSEEVENTS | Event.FOCUSEVENTS);
  }

  void registerItem(TreeItem item) {
    nodeHash.put(item.getId(), item);
  }

  void unregisterItem(TreeItem item) {
    int count = item.getItemCount();
    for (int i = 0; i < count; i++) {
      unregisterItem(item.getItem(i));
    }
    nodeHash.remove(item.getId());
  }
}
TOP

Related Classes of com.extjs.gxt.ui.client.widget.tree.Tree

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.