Package net.mygwt.ui.client.viewer

Source Code of net.mygwt.ui.client.viewer.TreeViewer

/*******************************************************************************
* Copyright (c) 2000, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*     Darrell Meyer <darrell@mygwt.net> - derived implementation
*     Tom Schindl <tom.schindl@bestsolution.at> - bugfix in issues: 40
*******************************************************************************/
package net.mygwt.ui.client.viewer;

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

import net.mygwt.ui.client.Events;
import net.mygwt.ui.client.event.BaseEvent;
import net.mygwt.ui.client.event.Listener;
import net.mygwt.ui.client.widget.Component;
import net.mygwt.ui.client.widget.tree.Tree;
import net.mygwt.ui.client.widget.tree.TreeItem;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Widget;

/**
* An interface to content providers for tree-structure-oriented viewers.
*
* <p>
* This code is based on JFace API from the Eclipse Project.
* </p>
*
* @see TreeViewer
*/
public class TreeViewer extends Viewer implements ICheckable {

  private Tree tree;
  private boolean async, checkable;
  private ListenerList checkChangeListener;

  /**
   * Creates a new tree viewer instance.
   *
   * @param tree the underlying tree widget
   */
  public TreeViewer(Tree tree) {
    this.tree = tree;
    hookWidget(tree);
    tree.addListener(Events.BeforeExpand, new Listener() {
      public void handleEvent(BaseEvent be) {
        TreeItem item = (TreeItem) be.widget;
        Object loaded = item.getData("loaded");
        if (loaded == null) {
          be.doit = false;
          loadChildren(item, true);
        }
      }
    });
  }

  /**
   * Adds the given child element to this viewer as a child of the given parent
   * element.
   *
   * @param parent the parent element
   * @param child the child element
   */
  public void add(Object parent, Object child) {
    TreeItem p = (TreeItem) findItem(parent);
    internalAdd(p, child, p.getItemCount());
  }

  public void addCheckStateListener(ICheckStateListener listener) {
    if (checkChangeListener == null) {
      checkChangeListener = new ListenerList();
    }
    checkChangeListener.add(listener);
  }

  public Widget findItem(Object elem) {
    TreeItem[] items = tree.getAllItems();
    for (int i = 0; i < items.length; i++) {
      TreeItem item = items[i];
      if (item.getData() == elem) {
        return item;
      }
    }
    return null;
  }

  public boolean getChecked(Object element) {
    TreeItem item = (TreeItem) findItem(element);

    if (item != null) {
      return item.isChecked();
    }

    return false;
  }

  /**
   * Returns the viewer's tree widget.
   *
   * @return the tree
   */
  public Tree getTree() {
    return tree;
  }

  public Widget getWidget() {
    return tree;
  }

  /**
   * Inserts the given element as a new child element of the given parent
   * element at the given position.
   *
   * @param parent the parent element
   * @param child the child element
   * @param position the insert position
   */
  public void insert(Object parent, Object child, int position) {
    TreeItem p = (TreeItem) findItem(parent);
    internalAdd(p, child, position);
  }

  /**
   * Refreshes this viewer starting with the given element.
   *
   * @param elem the element
   */
  public void refresh(Object elem) {
    TreeItem item = (TreeItem) findItem(elem);
    if (item != null) {
      if (item.getData("loaded") != null) {
        int count = item.getItemCount();
        for (int i = 0; i < count; i++) {
          item.remove(item.getItem(0));
        }
        item.setData("loaded", null);
        loadChildren(item, item.isExpanded());
      }
    }
  }

  /**
   * Removes the given element from the viewer.
   *
   * @param element the element to be removed
   */
  public void remove(Object element) {
    TreeItem item = (TreeItem) findItem(element);
    if (item != null) {
      TreeItem parent = item.getParentItem();
      parent.remove(item);
      removeElement(item.getData());
      item.setData(null);
    }
  }

  public void removeCheckStateListener(ICheckStateListener listener) {
    if (checkChangeListener != null) {
      checkChangeListener.remove(listener);
    }
  }

  /**
   * Selects the elements.
   *
   * @param elem the element to be selected
   */
  public void select(Object elem) {
    TreeItem item = (TreeItem) findItem(elem);
    tree.getSelectionModel().select(item);
  }

  public boolean setChecked(Object element, boolean state) {
    TreeItem item = (TreeItem) findItem(element);

    if (item != null) {
      item.setChecked(state);
      return true;
    }

    return false;
  }

  public void setContentProvider(IContentProvider contentProvider) {
    super.setContentProvider(contentProvider);
    if (contentProvider instanceof IAsyncTreeContentProvider) {
      async = true;
    }
    if (contentProvider instanceof ICheckable) {
      checkable = true;
    }
  }

  /**
   * Sets the expanded state for the element.
   *
   * @param element the element
   * @param expanded the expand state
   */
  public void setExpanded(Object element, boolean expanded) {
    TreeItem item = (TreeItem) findItem(element);
    if (item != null) {
      item.setExpanded(expanded);
    }
  }

  public void setSelection(ISelection selection, boolean reveal) {
    List selected = selection.toList();
    tree.getSelectionModel().deselectAll();
    TreeItem[] items = tree.getAllItems();
    for (int i = 0; i < items.length; i++) {
      TreeItem item = items[i];
      Object elem = item.getData();
      if (selected.contains(elem)) {
        tree.getSelectionModel().select(item);
      }
    }
  }

  public void update() {
    TreeItem[] items = tree.getAllItems();
    for (int i = 0; i < items.length; i++) {
      TreeItem item = items[i];
      updateInternal(item);
    }
  }

  public void update(Object elem) {
    TreeItem item = (TreeItem) findItem(elem);
    if (item != null) {
      updateInternal(item);
    }
  }

  protected void add(Object elem) {

  }

  protected List getSelectedFromWidget() {
    ArrayList elems = new ArrayList();
    TreeItem[] items = tree.getSelection();
    for (int i = 0; i < items.length; i++) {
      TreeItem item = items[i];
      elems.add(item.getData());
    }
    return elems;
  }

  protected void hookWidget(Component widget) {
    super.hookWidget(widget);
    widget.addListener(Events.CheckChange, new Listener() {

      public void handleEvent(BaseEvent be) {
        fireCheckStateChanged(be);
      }
    });
  }

  protected void insert(Object elem, int index) {
    // do nothing
  }

  protected void onInputReceived(Object input) {
    renderTree();
  }

  private Object[] filterChildren(Object parent, Object[] elems) {
    List temp = new ArrayList();
    for (int i = 0; i < elems.length; i++) {
      if (isOrDecendantSelected(elems[i])) {
        temp.add(elems[i]);
      }
    }
    return temp.toArray();
  }

  private void fireCheckStateChanged(BaseEvent be) {
    if (checkChangeListener != null) {
      TreeItem item = (TreeItem) be.item;

      CheckStateChangedEvent evt = new CheckStateChangedEvent(this, item.getData(),
          item.isChecked());
      Iterator it = checkChangeListener.iterator();

      while (it.hasNext()) {
        ((ICheckStateListener) it.next()).checkStateChanged(evt);
      }
    }
  }

  private void internalAdd(TreeItem parent, Object elem, int position) {
    // if the parent is not expanded force reload
    if (!parent.isExpanded()) {
      parent.setData("loaded", null);
      parent.setLeaf(false);
      parent.getUI().updateJoint();
      return;
    }
    if (!isFiltered(parent, elem)) {
      renderItem(parent, elem, position);
      if (getSorter() != null) {
        sortChildren(parent);
      }
    }
  }

  /**
   * Returns <code>true</code> if the element or any child elements is not
   * filetered.
   *
   * @param elem the element
   * @return the select state
   */

  private boolean isOrDecendantSelected(Object elem) {
    if (!isFiltered(null, elem)) {
      return true;
    }
    ITreeContentProvider cp = (ITreeContentProvider) getContentProvider();
    Object[] children = cp.getChildren(elem);
    for (int i = 0; i < children.length; i++) {
      boolean result = isOrDecendantSelected(children[i]);
      if (result) {
        return true;
      }
    }

    return false;
  }

  private void loadChildren(final TreeItem item, boolean expand) {
    if (!async) {
      ITreeContentProvider cp = (ITreeContentProvider) getContentProvider();
      Object[] children = cp.getChildren(item.getData());

      children = filterChildren(item, children);
      sortElements(children);

      for (int i = 0; i < children.length; i++) {
        renderItem(item, children[i], i);
      }
      item.setData("loaded", "true");
      item.setExpanded(expand);

    } else {
      IAsyncTreeContentProvider acp = (IAsyncTreeContentProvider) getContentProvider();
      item.getUI().onLoadingChange(true);
      acp.getChildren(item.getData(), new IAsyncContentCallback() {

        public void setElements(Object[] children) {
          item.getUI().onLoadingChange(false);
          children = filterChildren(item, children);
          sortElements(children);
          for (int i = 0; i < children.length; i++) {
            renderItem(item, children[i], -1);
          }
          item.setData("loaded", "true");
          if (item.hasChildren()) {
            item.setExpanded(true);
          } else {
            item.setLeaf(true);
            item.getUI().updateJoint();
          }

        }
      });
    }

  }

  private void renderItem(TreeItem parent, Object elem, int position) {
    boolean hasChildren = false;
    if (async) {
      hasChildren = ((IAsyncTreeContentProvider) getContentProvider()).hasChildren(elem);
    } else {
      hasChildren = ((ITreeContentProvider) getContentProvider()).hasChildren(elem);
    }

    ILabelProvider lp = (ILabelProvider) getLabelProvider();

    TreeItem item = new TreeItem();
    item.setData(elem);
    item.setText(lp.getText(elem));
    item.setIconStyle(lp.getIconStyle(elem));
    item.setLeaf(!hasChildren);
   
    if (checkable) {
      item.setChecked(((ICheckable)getContentProvider()).getChecked(elem));
    }
   
    if (position == -1) {
      parent.add(item);
    } else {
      parent.insert(item, position);
    }
  }

  private void renderTree() {
    TreeItem root = tree.getRootItem();
    root.setData(input);

    int count = root.getItemCount();
    for (int i = 0; i < count; i++) {
      root.remove(root.getItem(0));
    }

    Object[] elems = elements;
    elems = sortElements(elems);
    for (int i = 0; i < elems.length; i++) {
      Object elem = elems[i];
      if (getFilters().length > 0) {
        if (isOrDecendantSelected(elem)) {
          renderItem(root, elem, -1);
        }
      } else {
        renderItem(root, elem, -1);
      }
    }
  }

  private void sortChildren(TreeItem parent) {
    Object[] elems = new Object[parent.getItemCount()];
    Element p = parent.getContainer();
    for (int i = 0; i < elems.length; i++) {
      TreeItem item = parent.getItem(i);
      DOM.removeChild(p, item.getElement());
      elems[i] = item.getData();
    }
    sortElements(elems);

    for (int i = 0; i < elems.length; i++) {
      TreeItem item = (TreeItem) findItem(elems[i]);
      Element elem = item.getElement();
      DOM.appendChild(p, elem);
    }

  }

  private void updateInternal(TreeItem item) {
    ILabelProvider lp = (ILabelProvider) getLabelProvider();
    Object elem = item.getData();
    item.setText(lp.getText(elem));
    item.setIconStyle(lp.getIconStyle(elem));
  }
}
TOP

Related Classes of net.mygwt.ui.client.viewer.TreeViewer

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.