ServerTreeRenderer.java :  » Content-Management-System » TransferCM » com » methodhead » tree » Java Open Source

Java Open Source » Content Management System » TransferCM 
TransferCM » com » methodhead » tree » ServerTreeRenderer.java
/* 
 * Copyright (C) 2006 Methodhead Software LLC.  All rights reserved.
 * 
 * This file is part of TransferCM.
 * 
 * TransferCM is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * TransferCM is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * TransferCM; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
 * Fifth Floor, Boston, MA  02110-1301  USA
 */

package com.methodhead.tree;

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

import javax.swing.tree.TreeNode;

/**
 * <p>
 *   A <tt>TreeRenderer</tt> for trees whose state is maintained on the server.
 *   The renderer only renders those nodes that are visible, and a request must
 *   be made to open or close a node.  A mechanism must exist on the server
 *   side to handle those requests.  While more elaborate to implement, this
 *   approach makes it possible maintain a tree's state across requests.
 * </p>
 */
public class ServerTreeRenderer
extends TreeRenderer {

  // constructors /////////////////////////////////////////////////////////////

  // constants ////////////////////////////////////////////////////////////////

  // classes //////////////////////////////////////////////////////////////////

  // methods //////////////////////////////////////////////////////////////////

  /**
   *
   */
  public String renderTree(
    FoldingTreeNode root )
  throws
    TreeException {

    if ( openUrl_ == null )
      throw new TreeException( "openUrl has not been set." );

    if ( closeUrl_ == null )
      throw new TreeException( "closeUrl has not been set." );

    //
    // set defaults
    //
    if ( getClosedHandleImage() == null )
      closedHandleImageHtml_ = "+";
    else
      closedHandleImageHtml_ =
        "<img border=\"0\" src=\"" + getClosedHandleImage() + "\">";

    if ( getOpenedHandleImage() == null )
      openedHandleImageHtml_ = "-";
    else
      openedHandleImageHtml_ =
        "<img border=\"0\" src=\"" + getOpenedHandleImage() + "\">";

    //
    // get visible nodes
    //
    List nodes = new ArrayList();
    getVisibleNodes( nodes, root );

    //
    // get maximum visible level
    //
    int maxVisibleLevel = getMaxLevel( nodes );

    //
    // render the tree
    //
    StringBuffer buf = new StringBuffer();
    renderHeader( buf );
    
    for ( Iterator iter = nodes.iterator(); iter.hasNext(); ) {
      FoldingTreeNode node = ( FoldingTreeNode )iter.next();
      renderNode( buf, maxVisibleLevel, node );
    }

    renderFooter( buf );

    //
    // return the html
    //
    return buf.toString();
  }

  /**
   * Transforms the tree into a list of nodes that should be displayed.
   */
  protected void getVisibleNodes(
    List rows,
    FoldingTreeNode node ) {

    if ( !node.isRoot() || !isRootHidden() )
      rows.add( node );

    if ( !node.isLeaf() && node.getOpened() )
      for ( int i = 0; i < node.getChildCount(); i++ )
        getVisibleNodes( rows, ( FoldingTreeNode )node.getChildAt( i ) );
  }

  /**
   * Returns the level of the deepest level node in <tt>nodes</tt>.
   */
  protected int getMaxLevel(
    List nodes ) {

    int level = 0;
    for ( Iterator iter = nodes.iterator(); iter.hasNext(); ) {
      FoldingTreeNode node = ( FoldingTreeNode )iter.next();

      int tmp = node.getLevel();

      if ( tmp > level )
        level = tmp;
    }

    return level;
  }

  /**
   * Renders the header of the tree: a <tt>table</tt> tag.
   */
  protected void renderHeader(
    StringBuffer buf )
  throws
    TreeException {

    buf.append( "<table>\n" );
  }

  /**
   * Renders the footer of the tree.
   */
  protected void renderFooter(
    StringBuffer buf )
  throws
    TreeException {

    buf.append( "</table>\n" );
  }

  /**
   * Renders a node.
   */
  protected void renderNode(
    StringBuffer buf,
    int maxVisibleLevel,
    FoldingTreeNode node ) {

    //
    // if the root is hidden, it throws off most of these calculations by one;
    // find this offset peppered through the code below
    //
    int hiddenRootOffset = 0;
    if ( isRootHidden() )
      hiddenRootOffset = 1;

    //
    // scratch strings
    //
    String s = null;
    String t = null;

    buf.append( "<tr>" );

    //
    // insert an empty cell for each level deep the node is
    //
    for ( int i = hiddenRootOffset; i < node.getLevel(); i++ )
      buf.append( "<td>&nbsp;</td>" );

    //
    // render open/close link; leaf?
    //
    if ( node.isLeaf() ) {
      buf.append(
        "<td>&nbsp;</td>" );
    }
    else {
      //
      // opened?
      //
      if ( !node.getOpened() )
        buf.append(
          "<td><a href=\"" + openUrl_ + 
          node.hashCode() + "\">" + closedHandleImageHtml_ + "</a></td>" );

      //
      // closed
      //
      else
        buf.append(
          "<td><a href=\"" + closeUrl_ + 
          node.hashCode() + "\">" + openedHandleImageHtml_ + "</a></td>" );
    }

    //
    // render icon
    //
    Map iconImages = getIconImages();

    if ( iconImages != null ) {

      s = ( String )iconImages.get( node.getIconHint() );

      if ( s == null )
        s = ( String )iconImages.get( DEFAULT_ICON );

      if ( s == null ) {
        buf.append( "<td>&nbsp;</td>" );
      }
      else {
        if ( node.getUrl() == null )
          buf.append( "<td><img src=\"" + s + "\"></td>" );
        else
          buf.append(
            "<td><a href=\"" + node.getUrl() + "\"><img border=\"0\" src=\"" +
            s + "\"></a></td>" );
      }
    }

    //
    // render label
    //
    if ( node.getUrl() == null )
      buf.append(
        "<td width=\"100%\" colspan=\"" +
        ( maxVisibleLevel - node.getLevel() + 1 ) + "\">" +
        node.getLabel() + "</td>" );
    else
      buf.append(
        "<td width=\"100%\" colspan=\"" +
        ( maxVisibleLevel - node.getLevel() + 1 ) +
        "\"><a href=\"" + node.getUrl() + "\">" + node.getLabel() +
        "</a></td>" );

    buf.append( "</tr>\n" );
  }

  // properties ///////////////////////////////////////////////////////////////

  /**
   * Sets the url to open a node; the hash code of the node to be opened will
   * be appended to the end of this url.
   */
  public void setOpenUrl( String openUrl ) {
    openUrl_ = openUrl;
  }

  /**
   * Sets the url to close a node; the hash code of the node to be closed will
   * be appended to the end of this url.
   */
  public void setCloseUrl( String closeUrl ) {
    closeUrl_ = closeUrl;
  }

  // attributes ///////////////////////////////////////////////////////////////

  protected String openUrl_ = null;
  protected String closeUrl_ = null;

  private String openedHandleImageHtml_ = null;
  private String closedHandleImageHtml_ = null;
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.