[prev in list] [next in list] [prev in thread] [next in thread]
List: ecs-dev
Subject: cvs commit: jakarta-ecs/src/java/org/apache/ecs/examples HtmlTree.java
From: rdonkin () apache ! org
Date: 2002-01-10 22:34:05
[Download RAW message or body]
rdonkin 02/01/10 14:34:05
Modified: src/java/org/apache/ecs/examples HtmlTree.java
Log:
Christian Brensing <horombo@gmx.de> submitted an improved version of his ecs example
Revision Changes Path
1.2 +900 -640 jakarta-ecs/src/java/org/apache/ecs/examples/HtmlTree.java
Index: HtmlTree.java
===================================================================
RCS file: /home/cvs/jakarta-ecs/src/java/org/apache/ecs/examples/HtmlTree.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- HtmlTree.java 6 Nov 2001 23:09:49 -0000 1.1
+++ HtmlTree.java 10 Jan 2002 22:34:05 -0000 1.2
@@ -1,640 +1,900 @@
-/*
- * Copyright (c) 1999 The Java Apache Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the Java Apache
- * Project. <http://java.apache.org/>"
- *
- * 4. The names "Java Apache Element Construction Set", "Java Apache ECS" and
- * "Java Apache Project" must not be used to endorse or promote products
- * derived from this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- * "Java Apache Element Construction Set" nor "Java Apache ECS" appear
- * in their names without prior written permission of the
- * Java Apache Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the Java Apache
- * Project. <http://java.apache.org/>"
- *
- * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Java Apache Project. For more information
- * on the Java Apache Project please see <http://java.apache.org/>.
- *
- */
-
-package org.apache.ecs.examples;
-
-import java.io.*;
-import java.util.*;
-import javax.swing.tree.*;
-import org.apache.ecs.xml.*;
-import org.apache.ecs.html.*;
-
-/**
- * This JavaBean returns the hierarchical structure described in a
- * javax.swing.tree.DefaultMutableTreeNode as valid XHTML. This class
- * is a very simple counterpart of the javax.swing.JTree with the
- * exception that the external Controller is integrated into this View.
- * If you want your tree elements (nodes and leafs) to be marked with an
- * anchor, you'll have to make sure that the name of your node contains
- * such an anchor.
- *
- * <p>You can use this class in a JavaServerPage like this:</p>
- *
- * <p><blockquote>
- * <p>...template text...</p>
- * <p><code>
- * <%-- Get the bean from the request scope or
- * create a new one if none exits --%><br />
- * <jsp:useBean id="tree" scope="request"
- * class="org.apache.ecs.examples.HtmlTree">
- * <blockquote>
- * <p><%-- Read the path from the request --%><br />
- * <jsp:setProperty name="tree"
- * property="path" param="path" /></p>
- * <p><%-- Set bean properties --%><br />
- * <jsp:setProperty name="tree"
- * property="rootVisible" value="true" /><br />
- * <jsp:setProperty name="tree"
- * property="indentation" value="2" /><br />
- * <jsp:setProperty name="tree"
- * property="openIcon" value="open.gif" /><br />
- * <jsp:setProperty name="tree"
- * property="closedIcon" value="closed.gif" /><br />
- * <jsp:setProperty name="tree"
- * property="leafIcon" value="leaf.gif" /></p>
- * <p><%-- Workaround for Netscape
- * and Opera browsers --%><br />
- * <jsp:setProperty name="tree"
- * property="action" value="tree.jsp" /></p>
- * </blockquote>
- * </jsp:useBean>
- * </code></p>
- * <p>...template text...</p>
- * <p><code>
- * <%-- Get the XHTML output from the bean --%><br />
- * <jsp:getProperty name="tree" property="html" />
- * </code></p>
- * </blockquote></p>
- *
- * Although this class is just an example of using parts of the Element
- * Construction Set, you can use it quite well in real web applications.
- *
- * @version 1.0, 2001/10/30
- * @author <a href="mailto:horombo@gmx.de">Christian Brensing</a>
- */
-public class HtmlTree implements Serializable {
-
- /**
- * Number of blank spaces around each hierarchical level
- * will be indented in relation to its parent node.
- * Default is 2.
- */
- protected int indentation = 2;
-
- /**
- * Path to the requested node to be displayed,
- * described as colon separated integer values.
- * Default is an empty String.
- */
- protected String path = new String();
-
- /**
- * Parameter name used to build the query string for the
- * anchor that acts as the Controller for opening and
- * closing nodes. Default is "path".
- */
- protected String parameterName = new String("path");
-
- /**
- * Array that stores the index of each node
- * read from the path property.
- */
- private int[] pathArray = new int[0];
-
- /**
- * Icon for displaying leafs.
- * Default is an empty String.
- */
- protected String leafIcon = new String();
-
- /**
- * Icon for displaying open nodes.
- * Default is an empty String.
- */
- protected String openIcon = new String();
-
- /**
- * Icon for displaying closed nodes.
- * Default is an empty String.
- */
- protected String closedIcon = new String();
-
- /**
- * Context path of a web resource for the workaround
- * of a strange behaviour of Netscape and Opera
- * browsers. Default is an empty String.
- */
- protected String action = new String();
-
- /**
- * True if the root node is displayed, false if
- * its children are the highest visible nodes.
- * Default is true.
- */
- protected boolean rootVisible = true;
-
- /**
- * The node that defines the tree displayed by this object.
- * Default is a sample model.
- */
- protected DefaultMutableTreeNode root = getDemoModel();
-
- /**
- * Stores the requested node to be displayed.
- * Default is the root node.
- */
- private DefaultMutableTreeNode displayNode = root;
-
- /**
- * Returns a HtmlTree with a sample model.
- */
- public HtmlTree() {
- } // Constructor
-
- /**
- * Returns a HtmlTree with the specified DefaultMutableTreeNode
- * as its root. If the DefaultMutableTreeNode is <tt>null</tt>,
- * a sample model is set automatically.
- *
- * @param root a DefaultMutableTreeNode object
- */
- public HtmlTree(DefaultMutableTreeNode root) {
-
- setRoot(root);
-
- } // Constructor
-
- /**
- * Sets the root node that will provide the data. If the
- * specified DefaultMutableTreeNode is <tt>null</tt>,
- * a sample model is set automatically.
- *
- * @param root a DefaultMutableTreeNode object
- */
- public void setRoot(DefaultMutableTreeNode root) {
-
- // Check property
- if (root == null) { root = getDemoModel(); }
-
- // Set property
- this.root = root;
-
- } // setRoot
-
- /**
- * Sets the path - described as colon separated integer values -
- * to the requested node to be displayed.
- *
- * @param path the path to the requested node to be displayed
- */
- public void setPath(String path) {
-
- // Check property
- if (path == null) { path = new String(); }
-
- // Set property
- this.path = path;
-
- // Tokenize the path
- StringTokenizer st = new StringTokenizer(path,":");
-
- // Reset path array
- pathArray = new int[st.countTokens()];
-
- // Save value of each token in the array
- if (st.countTokens() > 0) {
- for (int i = 0; i <= st.countTokens(); i++) {
- pathArray[i] = Integer.
- parseInt(st.nextToken().trim());
- } // next i
- } // end if
-
- } // setPath
-
- /**
- * Returns a path constructed from the path array for the
- * specified level.
- *
- * @param level the distance from the node to the root node.
- * @return the path for the specified level
- */
- private String getPath(int level) {
-
- // New StringBuffer for the path generation
- StringBuffer autoPath = new StringBuffer();
-
- // For each node
- for (int i = 0; i < level; i++) {
-
- // Add node index (read from the path array)
- autoPath.append(pathArray[i]);
-
- // Add path separator (colon)
- if (i < (level - 1)) { autoPath.append(":"); }
-
- } // next i
-
- // Return generated path
- return autoPath.toString();
-
- } // getPath
-
- /**
- * Sets the name of the parameter used to build the query
- * string for the anchor that acts as the Controller for
- * opening and closing nodes. You only have to set this
- * name when the default name "path" is already
- * used by your web application.
- *
- * @param parameterName the name of the parameter used to
- * build the query string
- */
- public void setParameterName(String parameterName) {
-
- // Check property
- if (parameterName == null ||
- parameterName.equals("")) {
- parameterName = new String("path"); }
-
- // Set property
- this.parameterName = parameterName;
-
- } // setParameterName
-
- /**
- * Returns the name of the parameter used to build the
- * query string for the anchor that acts as the Controller
- * for opening and closing nodes.
- *
- * @return the name of the parameter
- */
- public String getParameterName() {
-
- return parameterName;
-
- } // getParameterName
-
- /**
- * Determines whether or not the root node is visible.
- *
- * @param rootVisible true if the root node of the tree
- * is to be displayed
- */
- public void setRootVisible(boolean rootVisible) {
-
- this.rootVisible = rootVisible;
-
- } // setRootVisible
-
- /**
- * Returns true if the root node of the tree is displayed.
- *
- * @return true if the root node of the tree is displayed
- */
- public boolean isRootVisible() {
-
- return rootVisible;
-
- } // isRootVisible
-
- /**
- * Sets the number of blank spaces around each hierarchical
- * level will be indented in relation to its parent node.
- *
- * @param indentation the number of blank spaces
- */
- public void setIndentation(int indentation) {
-
- this.indentation = indentation;
-
- } // setIndentation
-
- /**
- * Sets the icon for displaying open nodes.
- *
- * @param openIcon the URI of an image file
- */
- public void setOpenIcon(String openIcon) {
-
- this.openIcon = openIcon;
-
- } // setOpenIcon
-
- /**
- * Sets the icon for displaying closed nodes.
- *
- * @param closedIcon the URI of an image file
- */
- public void setClosedIcon(String closedIcon) {
-
- this.closedIcon = closedIcon;
-
- } // setClosedIcon
-
- /**
- * Sets the icon for displaying leafs.
- *
- * @param leafIcon the URI of an image file
- */
- public void setLeafIcon(String leafIcon) {
-
- this.leafIcon = leafIcon;
-
- } // setLeafIcon
-
- /**
- * Workaround of a strange behaviour of Netscape and Opera browsers.
- * In these browsers the relative URL containg only the query string
- * with the path information (e.g. "?path=0:1") are not
- * translated correctly into an absoulte URL. By setting a context
- * path, on which to append the query string, this behaviour should
- * be fixed.
- *
- * @param action the context path of a web resource (e.g. a JSP-File)
- */
- public void setAction(String action) {
-
- this.action = action;
-
- } // setAction
-
- /**
- * Returns the name of the currently expanded node to
- * be displayed.
- *
- * @return the name of the node to be displayed
- */
- public String getNodeName() {
-
- return expand().toString();
-
- } // getNodeName
-
- /**
- * Constructs a valid XHTML <img>-tag from the specified icon.
- * Although this method uses the xml-package to generate a valid tag,
- * the xhtml-package would provide the same functionality.
- *
- * @param icon the URI of an image file
- * @return a valid XHTML <img>-tag
- */
- private String getImg(String icon) {
-
- // New <img>
- XML img = new XML("img",false);
-
- // Check specified icon property
- if (icon == null) { icon = new String(); }
-
- // Set src attribute
- img.addAttribute("src",icon);
-
- // return <img>
- return img.toString();
-
- } // getImg
-
- /**
- * Expands the tree by following the specified path
- * and returns the requested node to be displayed
- *
- * @return the requested node to be displayed
- */
- private DefaultMutableTreeNode expand() {
-
- // Reset node to be displayed
- displayNode = root;
-
- // Iterate trough the path array
- for (int i = 0; i < pathArray.length; i++) {
- displayNode = (DefaultMutableTreeNode)
- displayNode.getChildAt(pathArray[i]);
- } // next i
-
- // Return node to be displayed
- return displayNode;
-
- } // expand
-
- /**
- * Returns the hierarchical structure described in the specified root
- * node as valid XHTML. For perfomance reasons all parent nodes of the
- * requested node are collapsed. The source code does not contain any
- * formatting tags or attributes. I recommend that you use Cascading
- * Style Sheets instead. For this purpose, the tree elements are marked
- * with the class attribute values "tree", "parent"
- * and "child".
- *
- * @return the hierarchical structure within a <table>-tag
- */
- public String getHtml() {
-
- // Expand the tree
- displayNode = expand();
-
- // New <table>
- Table table = new Table();
- table.setClass("tree");
-
- // Reset auto indentation
- int autoIndentation = 0;
-
- // Initialize ancestor node with the first
- // child of the node to be displayed
- TreeNode ancestor = displayNode.getFirstChild();
-
- // Read all ancestors into an array
- ArrayList list = new ArrayList();
- while ((ancestor = ancestor.getParent())
- != null) { list.add(ancestor); }
-
- // For each ancestor (ordered desc beginning at the root)
- for (int index = list.size(); index > 0; index--) {
-
- // Get current ancestor
- DefaultMutableTreeNode parent =
- (DefaultMutableTreeNode)list.
- get(index-1);
-
- // Displays the ancestor if it's not the root
- // or the isRootVisible property is set to true
- if (!parent.isRoot() || rootVisible) {
-
- // New <td>
- TD td = new TD();
- td.setClass("parent");
-
- // Generate href for this ancestor (the
- // level is decreased by one to provide
- // an anchor to its parent node)
- String href = action.concat("?").
- concat(parameterName).concat("=").
- concat(getPath(parent.getLevel()-1));
-
- // Add indentation to <td>
- for (int i = 0; i < autoIndentation; i++)
- { td.addElement(" "); }
-
- // Add icon with <a> to <td>
- td.addElement(new A(href,getImg(openIcon)));
-
- // Add ancestor with <nobr> to <td>
- td.addElement(new NOBR(parent.toString()));
-
- // Add <td> to <tr> to <table>
- table.addElement(new TR(td));
-
- // Increment auto indentation
- autoIndentation = autoIndentation + indentation;
-
- } // end if rootVisible
-
- } // next index
-
- // For each child
- for (int index = 0; index < displayNode.getChildCount(); index++) {
-
- // New <td>
- TD td = new TD();
- td.setClass("child");
-
- // Get current child
- DefaultMutableTreeNode child =
- (DefaultMutableTreeNode)displayNode.
- getChildAt(index);
-
- // Generate path == path + child index
- String autoPath = getPath(child.getLevel()-1).
- concat(":").concat(String.valueOf(index));
-
- // Generate href for this child
- String href = action.concat("?").
- concat(parameterName).concat("=").
- concat(autoPath);
-
- // Add indentation to <td>
- for (int i = 0; i < autoIndentation; i++)
- { td.addElement(" "); }
-
- // New <img> with default leaf icon
- String img = getImg(leafIcon);
-
- // Set closed node icon, if child is not a leaf
- if (!child.isLeaf()) { img = getImg(closedIcon); }
-
- // Add icon with <a> (not for leafs) to <td>
- if (!child.isLeaf()) {td.addElement(new A(href,img)); }
-
- // Add icon without <a> (leafs only) to <td>
- if (child.isLeaf()) { td.addElement(img); }
-
- // Add child with <nobr> to <td>
- td.addElement(new NOBR(child.toString()));
-
- // Add <td> to <tr> to <table>
- table.addElement(new TR(td));
-
- } // next index
-
- // Return <table>
- return table.toString();
-
- } // getHtml
-
- /**
- * Returns a sample tree model.
- *
- * @return a DefaultMutableTreeNode with a sample tree model
- */
- private DefaultMutableTreeNode getDemoModel() {
-
- // New root node
- DefaultMutableTreeNode root =
- new DefaultMutableTreeNode("Root");
-
- // First level
- for (int i = 1; i <= 5; i++) {
-
- // New node
- DefaultMutableTreeNode child =
- new DefaultMutableTreeNode("Folder-" + i);
-
- // Add node to root
- root.add(child);
-
- // Second level
- for (int j = 1; j <= 3; j++) {
-
- // New node
- DefaultMutableTreeNode subchild =
- new DefaultMutableTreeNode("Subfolder-" + j);
-
- // Add node to parent node
- child.add(subchild);
-
- // Third level
- for (int k = 1; k <= 3; k++) {
-
- // New anchor
- A a = new A("http://jakarta.apache.org");
- a.setTarget("target").addElement("Document-" + k);
-
- // New node (leaf)
- DefaultMutableTreeNode document =
- new DefaultMutableTreeNode(a.toString());
-
- // Add node to parent node
- subchild.add(document);
-
- } // next k
-
- } // next j
-
- } // next i
-
- // Return root node
- return root;
-
- } // getDemoModel
-
-} // HtmlTree
+/*
+ * Copyright (c) 1999 The Java Apache Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the Java Apache
+ * Project. <http://java.apache.org/>"
+ *
+ * 4. The names "Java Apache Element Construction Set", "Java Apache ECS" and
+ * "Java Apache Project" must not be used to endorse or promote products
+ * derived from this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ * "Java Apache Element Construction Set" nor "Java Apache ECS" appear
+ * in their names without prior written permission of the
+ * Java Apache Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the Java Apache
+ * Project. <http://java.apache.org/>"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Java Apache Project. For more information
+ * on the Java Apache Project please see <http://java.apache.org/>.
+ *
+ */
+
+package org.apache.ecs.examples;
+
+import java.io.*;
+import java.util.*;
+import javax.swing.tree.*;
+import org.apache.ecs.xml.*;
+import org.apache.ecs.html.*;
+
+/**
+ * This JavaBean returns the hierarchical structure described in a
+ * javax.swing.tree.DefaultMutableTreeNode as valid XHTML. This class
+ * is a very simple counterpart of the javax.swing.JTree with the
+ * exception that the external Controller is integrated into this View.
+ * If you want your tree elements (nodes and leafs) to be marked with an
+ * anchor, you'll have to make sure that the name of your node contains
+ * such an anchor.
+ *
+ * <p>A specific node in a tree can be identified by a path, described as
+ * colon separated integer values (e.g. "0:1"). Unlike Swing's
+ * JTree component, this JavaBean expands only the requested node, leaving
+ * all its parent nodes collapsed. An <i>expanded</i> node is one displays
+ * its children. A <i>collapsed</i> node is one which hides them.</p>
+ *
+ * <p>You can use this class in a JavaServerPage like this:</p>
+ *
+ * <p><blockquote>
+ * <p>...template text...</p>
+ * <p><code>
+ * <%-- Get the bean from the request scope or
+ * create a new one if none exists --%><br />
+ * <jsp:useBean id="tree" scope="request"
+ * class="org.apache.ecs.examples.HtmlTree">
+ * <blockquote>
+ * <p><%-- Read the path from the request --%><br />
+ * <jsp:setProperty name="tree"
+ * property="path" param="path" /></p>
+ * <p><%-- Set UI properties --%><br />
+ * <jsp:setProperty name="tree"
+ * property="rootVisible" value="true" /><br />
+ * <jsp:setProperty name="tree"
+ * property="indentation" value="2" /><br />
+ * <jsp:setProperty name="tree"
+ * property="openIcon" value="open.gif" /><br />
+ * <jsp:setProperty name="tree"
+ * property="closedIcon" value="closed.gif" /><br />
+ * <jsp:setProperty name="tree"
+ * property="leafIcon" value="leaf.gif" /></p>
+ * <p><%-- Workaround for Netscape
+ * and Opera browsers --%><br />
+ * <jsp:setProperty name="tree"
+ * property="action" value="tree.jsp" /></p>
+ * </blockquote>
+ * </jsp:useBean>
+ * </code></p>
+ * <p>...template text...</p>
+ * <p><code>
+ * <%-- Get the XHTML output from the bean --%><br />
+ * <jsp:getProperty name="tree" property="html" />
+ * </code></p>
+ * </blockquote></p>
+ *
+ * Although this class is just an example of using parts of the Element
+ * Construction Set, you can use it quite well in real web applications.
+ *
+ * @version 1.1, 2001/12/30, added ability to use a DefaultTreeModel as the
+ * data model, added some useful methods including
+ * one for basic HTML encoding, improved javadoc
+ * comments and fixed minor bugs
+ * @version 1.0, 2001/10/30, initial release
+ * @author <a href="mailto:horombo@gmx.de">Christian Brensing</a>
+ */
+public class HtmlTree implements Serializable
+{
+ /**
+ * Number of blank spaces around each hierarchical level
+ * will be indented in relation to its parent node.
+ * Default is 2.
+ */
+ protected int indentation = 2;
+
+ /**
+ * Path to the requested node to be displayed,
+ * described as colon separated integer values.
+ * Default is an empty String.
+ */
+ protected String path = "";
+
+ /**
+ * Parameter name used to build the query string for the
+ * anchor that acts as the Controller for opening and
+ * closing nodes. Default is "path".
+ */
+ protected String parameterName = "path";
+
+ /**
+ * Array that stores the index of each node
+ * read from the path property.
+ */
+ private int[] pathArray = new int[0];
+
+ /**
+ * Icon for displaying leafs.
+ * Default is an empty String.
+ */
+ protected String leafIcon = "";
+
+ /**
+ * Icon for displaying open nodes.
+ * Default is an empty String.
+ */
+ protected String openIcon = "";
+
+ /**
+ * Icon for displaying closed nodes.
+ * Default is an empty String.
+ */
+ protected String closedIcon = "";
+
+ /**
+ * Context path of a web resource for the workaround
+ * of a strange behaviour of Netscape and Opera
+ * browsers. Default is an empty String.
+ */
+ protected String action = "?";
+
+ /**
+ * True if the root node is displayed, false if
+ * its children are the highest visible nodes.
+ * Default is true.
+ */
+ protected boolean rootVisible = true;
+
+ /**
+ * The node that defines the tree displayed by this object.
+ * Default is a sample model.
+ */
+ protected DefaultMutableTreeNode root = getDefaultTreeModel();
+
+ /**
+ * Stores the requested node to be displayed.
+ * Default is the root node.
+ */
+ protected DefaultMutableTreeNode displayNode = root;
+
+ /**
+ * Returns a HtmlTree with a sample model.
+ */
+ public HtmlTree()
+ {
+ // do nothing
+ }
+
+ /**
+ * Returns a HtmlTree with the specified DefaultMutableTreeNode
+ * as its root. If the DefaultMutableTreeNode is <tt>null</tt>,
+ * a sample model is set automatically.
+ *
+ * @param root a DefaultMutableTreeNode object
+ */
+ public HtmlTree(DefaultMutableTreeNode root)
+ {
+ setRoot(root);
+ }
+
+ /**
+ * Returns a HtmlTree with the specified DefaultTreeModel as
+ * its model. If the specified DefaultTreeModel is <tt>null</tt>,
+ * a sample model is set automatically.
+ *
+ * @param model a DefaultTreeModel object
+ */
+ public HtmlTree(DefaultTreeModel model)
+ {
+ setModel(model);
+ }
+
+ /**
+ * Sets the root node that will provide the data. If the
+ * specified DefaultMutableTreeNode is <tt>null</tt>,
+ * a sample model is set automatically.
+ *
+ * @param root a DefaultMutableTreeNode object
+ */
+ public void setRoot(DefaultMutableTreeNode root)
+ {
+ // Check property
+ if (root == null)
+ {
+ root = getDefaultTreeModel();
+ }
+
+ // Set property
+ this.root = root;
+ }
+
+ /**
+ * Returns the node that defines the tree displayed
+ * by this object.
+ *
+ * @return the root node that provides the data
+ */
+ public DefaultMutableTreeNode getRoot()
+ {
+ return root;
+ }
+
+ /**
+ * Sets the tree model that will provide the data. If the
+ * specified DefaultTreeModel is <tt>null</tt>, a sample
+ * model is set automatically.
+ *
+ * @param model a DefaultTreeModel object
+ */
+ public void setModel(DefaultTreeModel model)
+ {
+ if (model != null)
+ {
+ setRoot((DefaultMutableTreeNode)
+ model.getRoot());
+ }
+ else
+ {
+ setRoot(null);
+ }
+ }
+
+ /**
+ * Returns the model that defines the tree displayed
+ * by this object.
+ *
+ * @return the model that provides the data
+ */
+ public DefaultTreeModel getModel()
+ {
+ return new DefaultTreeModel(root);
+ }
+
+ /**
+ * Sets the path - described as colon separated integer values -
+ * to the requested node to be displayed.
+ *
+ * @param path the path to the requested node to be displayed
+ */
+ public void setPath(String path)
+ {
+ try
+ {
+ // Tokenize the path
+ pathArray = getPathResolved(path);
+
+ // Set path property
+ this.path = path;
+ }
+ catch (NumberFormatException nfe)
+ {
+ // Reset path property
+ this.path = "";
+ }
+ }
+
+ /**
+ * Returns the path to the requested node.
+ *
+ * @return the path to the requested node
+ */
+ public String getPath()
+ {
+ return path;
+ }
+
+ /**
+ * Returns a path constructed from the path array for the
+ * specified level.
+ *
+ * @param level the distance from the node to the root node.
+ * @return the path for the specified level
+ */
+ public String getPath(int level)
+ {
+ // Check property
+ if (level > pathArray.length)
+ {
+ level = pathArray.length;
+ }
+
+ // New StringBuffer for the path generation
+ StringBuffer autoPath = new StringBuffer();
+
+ // For each node
+ for (int i = 0; i < level; i++)
+ {
+ // Add node index (read from the path array)
+ autoPath.append(pathArray[i]);
+
+ // Add path separator (colon)
+ if (i < (level - 1))
+ {
+ autoPath.append(":");
+ }
+ }
+
+ // Return generated path
+ return autoPath.toString();
+ }
+
+ /**
+ * Returns an array that stores the index of each
+ * node read from the specified path.
+ *
+ * @return an array of node indices
+ * @throws java.lang.NumberFormatException if the specified
+ * path does not consist of colon separated integer values
+ */
+ public static int[] getPathResolved(String path)
+ throws NumberFormatException
+ {
+ try
+ {
+ // Initialize the token array
+ int[] returnArray = new int[0];
+
+ // Tokenize the path
+ StringTokenizer st = new StringTokenizer(path,":");
+
+ // Reset the array with the number of tokens
+ returnArray = new int[st.countTokens()];
+
+ // Save value of each token in the array
+ if (st.countTokens() > 0)
+ {
+ for (int i = 0; i < returnArray.length; i++)
+ {
+ returnArray[i] = Integer.parseInt
+ (st.nextToken().trim());
+ }
+ }
+
+ // Return path array
+ return returnArray;
+ }
+ catch (Exception e)
+ {
+ // Wrap the exception in a NumberFormatException
+ throw new NumberFormatException(e.getMessage());
+ }
+ }
+
+ /**
+ * Sets the name of the parameter used to build the query
+ * string for the anchor that acts as the Controller for
+ * opening and closing nodes. You only have to set this
+ * name if the default name "path" is already
+ * used by your web application.
+ *
+ * @param parameterName the name of the parameter used
+ * to build the query string
+ */
+ public void setParameterName(String parameterName)
+ {
+ // Check property
+ if (parameterName == null
+ || parameterName.equals(""))
+ {
+ parameterName = "path";
+ }
+
+ // Set property
+ this.parameterName = parameterName;
+ }
+
+ /**
+ * Returns the name of the parameter used to build the
+ * query string for the anchor that acts as the Controller
+ * for opening and closing nodes.
+ *
+ * @return the name of the parameter
+ */
+ public String getParameterName()
+ {
+ return parameterName;
+ }
+
+ /**
+ * Determines whether or not the root node is visible.
+ *
+ * @param rootVisible true if the root node of the tree
+ * is to be displayed
+ */
+ public void setRootVisible(boolean rootVisible)
+ {
+ this.rootVisible = rootVisible;
+ }
+
+ /**
+ * Returns true if the root node of the tree is displayed.
+ *
+ * @return true if the root node of the tree is displayed
+ */
+ public boolean isRootVisible()
+ {
+ return rootVisible;
+ }
+
+ /**
+ * Sets the number of blank spaces around each hierarchical
+ * level will be indented in relation to its parent node.
+ *
+ * @param indentation the number of blank spaces
+ */
+ public void setIndentation(int indentation)
+ {
+ this.indentation = indentation;
+ }
+
+ /**
+ * Returns the number of blank spaces around each
+ * hierarchical level is indented in relation to
+ * its parent node.
+ *
+ * @return the number of blank spaces
+ */
+ public int getIndentation()
+ {
+ return indentation;
+ }
+
+ /**
+ * Returns the name of the currently expanded node.
+ *
+ * @return the name of the node
+ */
+ public String getNodeName()
+ {
+ return displayNode.toString();
+ }
+
+ /**
+ * Returns the number of rows that are currently
+ * being displayed.
+ *
+ * @return the number of rows
+ */
+ public int getRowCount()
+ {
+ // Get level of the node to be displayed
+ int rowCount = displayNode.getLevel();
+
+ // Add number of children
+ rowCount = rowCount + displayNode.getChildCount();
+
+ // Increment by 1 if the root node is being displayed
+ if (rootVisible)
+ {
+ rowCount++;
+ }
+
+ // Return number of rows
+ return rowCount;
+ }
+
+ /**
+ * Sets the icon for displaying open nodes.
+ *
+ * @param openIcon the URI of an image file
+ */
+ public void setOpenIcon(String openIcon)
+ {
+ this.openIcon = openIcon;
+ }
+
+ /**
+ * Sets the icon for displaying closed nodes.
+ *
+ * @param closedIcon the URI of an image file
+ */
+ public void setClosedIcon(String closedIcon)
+ {
+ this.closedIcon = closedIcon;
+ }
+
+ /**
+ * Sets the icon for displaying leafs.
+ *
+ * @param leafIcon the URI of an image file
+ */
+ public void setLeafIcon(String leafIcon)
+ {
+ this.leafIcon = leafIcon;
+ }
+
+ /**
+ * Workaround of a strange behaviour of Netscape and Opera browsers.
+ * In these browsers the relative URL containg only the query string
+ * with the path information (e.g. "?path=0:1") are not
+ * translated correctly into an absoulte URL. By setting a context
+ * path, on which to append the query string, this behaviour should
+ * be fixed.
+ *
+ * @param action the context path of a web resource (e.g. a JSP-File)
+ */
+ public void setAction(String action)
+ {
+ // Check property
+ if (action == null)
+ {
+ action = "";
+ }
+
+ // If the specified context path already contains
+ // a query string, append an ampersand character
+ // for further parameter concatenation
+ if (action.indexOf("=") != -1)
+ {
+ action = action + "&";
+ }
+ else
+ {
+ action = action + "?";
+ }
+
+ // Set property
+ this.action = action;
+ }
+
+ /**
+ * Constructs a valid XHTML <img>-tag from the specified icon.
+ * Although this method uses the xml-package to generate a valid tag,
+ * the xhtml-package would provide the same functionality.
+ *
+ * @param icon the URI of an image file
+ * @return a valid XHTML <img>-tag
+ */
+ public String getImg(String icon)
+ {
+ // New <img>
+ XML img = new XML("img",false);
+
+ // Check specified icon property
+ if (icon == null)
+ {
+ icon = "";
+ }
+
+ // Set src attribute
+ img.addAttribute("src",icon);
+
+ // return <img>
+ return img.toString();
+ }
+
+ /**
+ * Expands the tree by following the specified path
+ * and returns the requested node to be displayed.
+ *
+ * @return the requested node to be displayed
+ */
+ public DefaultMutableTreeNode getRequestedNode()
+ {
+ // Reset node to be displayed
+ displayNode = root;
+
+ // Iterate trough the path array
+ for (int i = 0; i < pathArray.length; i++)
+ {
+ if (displayNode.getDepth() > 1)
+ {
+ displayNode = (DefaultMutableTreeNode)
+ displayNode.getChildAt(pathArray[i]);
+ }
+ }
+
+ // Return node to be displayed
+ return displayNode;
+ }
+
+ /**
+ * Returns the hierarchical structure described in the specified root
+ * node as valid XHTML. For perfomance reasons all parent nodes of the
+ * requested node are collapsed. The source code does not contain any
+ * formatting tags or attributes. I recommend that you use Cascading
+ * Style Sheets instead. For this purpose, the tree elements are marked
+ * with the class attribute values "tree", "parent"
+ * and "child".
+ *
+ * <p>A sample Style Sheet would look like this:</p>
+ *
+ * <p><blockquote>
+ * <code>
+ * a { color: black; text-decoration: none; }<br />
+ * a:hover { color: black; text-decoration: underline; }<br />
+ * img { margin-right: 5px; vertical-align: middle; border: none; }<br />
+ * table { font: normal 8pt Arial,Helvetica,sans-serif; }</br />
+ * td.parent { font-weight: bold; }<br />
+ * </code>
+ * </blockquote></p>
+ *
+ * @return the hierarchical structure within a <table>-tag
+ */
+ public String getHtml()
+ {
+ // Expand the tree
+ displayNode = getRequestedNode();
+
+ // New <table>
+ Table table = new Table();
+ table.setClass("tree");
+
+ // Reset auto indentation
+ int autoIndentation = 0;
+
+ // Initialize ancestor node with the first child of
+ // the node to be displayed (for parent recursion)
+ TreeNode ancestor = displayNode.getFirstChild();
+
+ // Read all ancestors into an array
+ ArrayList list = new ArrayList();
+ while ((ancestor = ancestor.getParent()) != null)
+ {
+ list.add(ancestor);
+ }
+
+ // For each ancestor (ordered desc beginning at the root)
+ for (int i = list.size(); i > 0; i--)
+ {
+ // Get current ancestor
+ DefaultMutableTreeNode parent =
+ (DefaultMutableTreeNode)list.get(i-1);
+
+ // Displays the ancestor if it's not the root
+ // or the rootVisible property is set to true
+ if (!parent.isRoot() || rootVisible)
+ {
+ // New <td>
+ TD td = new TD();
+ td.setClass("parent");
+
+ // Generate href for this ancestor (the
+ // level is decreased by one to provide
+ // an anchor to its parent node)
+ String href = action + parameterName
+ + "=" + getPath(parent.getLevel()-1);
+
+ // Add indentation to <td>
+ for (int j = 0; j < autoIndentation; j++)
+ {
+ td.addElement(" ");
+ }
+
+ // Add icon with <a> to <td>
+ td.addElement(new A(href,getImg(openIcon)));
+
+ // Add ancestor with <nobr> to <td>
+ td.addElement(new NOBR(parent.toString()));
+
+ // Add <td> to <tr> to <table>
+ table.addElement(new TR(td));
+
+ // Increment auto indentation
+ autoIndentation = autoIndentation + indentation;
+ }
+ }
+
+ // For each child
+ for (int i = 0; i < displayNode.getChildCount(); i++)
+ {
+ // New <td>
+ TD td = new TD();
+ td.setClass("child");
+
+ // Get current child
+ DefaultMutableTreeNode child =
+ (DefaultMutableTreeNode)displayNode
+ .getChildAt(i);
+
+ // Generate path == path + child index
+ String autoPath = getPath(child
+ .getLevel()-1) + ":" + i;
+
+ // Trim leading colon
+ if (autoPath.startsWith(":"))
+ {
+ autoPath = autoPath.substring(1);
+ }
+
+ // Generate href for this child
+ String href = action + parameterName
+ + "=" + autoPath;
+
+ // Add indentation to <td>
+ for (int j = 0; j < autoIndentation; j++)
+ {
+ td.addElement(" ");
+ }
+
+ // New <img> with default leaf icon
+ String img = getImg(leafIcon);
+
+ // Set closed node icon, if child is not a leaf
+ if (!child.isLeaf())
+ {
+ img = getImg(closedIcon);
+ }
+
+ // Add icon with <a> (not for leafs) to <td>
+ if (!child.isLeaf())
+ {
+ td.addElement(new A(href,img));
+ }
+
+ // Add icon without <a> (leafs only) to <td>
+ if (child.isLeaf())
+ {
+ td.addElement(img);
+ }
+
+ // Add child with <nobr> to <td>
+ td.addElement(new NOBR(child.toString()));
+
+ // Add <td> to <tr> to <table>
+ table.addElement(new TR(td));
+ }
+
+ // Return <table>
+ return table.toString();
+ }
+
+ /**
+ * Overrides <tt>toString()</tt> to print something meaningful.
+ * Returns the hierarchical structure described in the specified
+ * root node as valid XHTML.
+ *
+ * @see #getHtml
+ */
+ public String toString()
+ {
+ return getHtml();
+ }
+
+ /**
+ * Creates and returns a sample tree model. Used primarily
+ * during the design of the JavaServerPage to show something
+ * interesting.
+ *
+ * @return a DefaultMutableTreeNode with a sample tree model
+ */
+ protected static DefaultMutableTreeNode getDefaultTreeModel()
+ {
+ // New root node
+ DefaultMutableTreeNode root =
+ new DefaultMutableTreeNode("Root");
+
+ // First level
+ for (int i = 1; i <= 5; i++)
+ {
+ // New node
+ DefaultMutableTreeNode folder =
+ new DefaultMutableTreeNode("Folder-" + i);
+
+ // Add node to root
+ root.add(folder);
+
+ // Second level
+ for (int j = 1; j <= 3; j++)
+ {
+ // New node
+ DefaultMutableTreeNode subfolder =
+ new DefaultMutableTreeNode("Subfolder-" + j);
+
+ // Add node to parent node
+ folder.add(subfolder);
+
+ // Third level
+ for (int k = 1; k <= 3; k++)
+ {
+ // New anchor
+ A a = new A("http://jakarta.apache.org");
+ a.setTarget("target").addElement("Document-" + k);
+
+ // New node (leaf)
+ DefaultMutableTreeNode document =
+ new DefaultMutableTreeNode(a.toString());
+
+ // Add node to parent node
+ subfolder.add(document);
+ }
+ }
+ }
+
+ // Return root node
+ return root;
+ }
+
+ /**
+ * Returns the specified string encoded into a format suitable for
+ * HTML. All single-quote, double-quote, greater-than, less-than
+ * and ampersand characters are replaced with their corresponding
+ * HTML Character Entity codes. You can use this method to encode
+ * the designated node names before appending this node to your
+ * tree model. Please don't encode node names that already include
+ * a valid tag, because they are equally converted and thus won't
+ * be displayed by the browser.
+ *
+ * @param in the String to encode
+ * @return the encoded String
+ */
+ public static String encodeToHtml(String in)
+ {
+ // New StringBuffer for output concatenation
+ StringBuffer out = new StringBuffer();
+
+ // For each character in the input string
+ for (int i = 0; in != null && i < in.length(); i++)
+ {
+ // Get the current character
+ char c = in.charAt(i);
+
+ // Encode this character
+ if (c == '\'')
+ {
+ out.append("'");
+ }
+ else if (c == '\"')
+ {
+ out.append(""");
+ }
+ else if (c == '<')
+ {
+ out.append("<");
+ }
+ else if (c == '>')
+ {
+ out.append(">");
+ }
+ else if (c == '&')
+ {
+ out.append("&");
+ }
+ else
+ {
+ out.append(c);
+ }
+ }
+
+ // Return encoded string
+ return out.toString();
+ }
+}
\ No newline at end of file
--
To unsubscribe, e-mail: <mailto:ecs-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ecs-dev-help@jakarta.apache.org>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic