JSP树型标签 Tree Tag 用户指南

来源:互联网 发布:免费朗读软件 编辑:程序博客网 时间:2024/05/01 12:36
介绍:
      Tree Tag 是一个可定制的能在JSP中动态生成树型结构的标签,可以在http://www.jenkov.com下载,他类似在windows浏览器中的树型控制,你可以在JSP中用几乎所有类型的结构,Tree Tag着重考虑一下情况:
      " 动态建树,例如基于数据库的记录,文件系统的文件
      " 树规模大,这意味这可以的节点必须重建或重新载入
      " 每个节点的信息必须可以定制的
      " 每个节点的外观必须能完全定制的
      " 树节点的外观依赖节点类型,例如用户显示图片,其他的用户组显示箭头,同一棵树的外观可以变化
      为了实现,Tree Tag的类必用MVC设计模式实现,标签lib中由一个tree model api组成,然后Tree Tag是JSP中显示tree model,
      这个想法能使几乎解决所有我们目前收到的问题和建议,下面看看它怎么用。
安装:
      步骤:
            1:把jenkov-prizetags-bin-x.x.x.jar放在WEB工程的 WEB-INF/lib目录下
            2:解压 treetag.tld文件到WEB工程的 WEB-INF,treetag.tld在JAR包的META-INF目录下
            3:JSP中声明使用

基本步骤:3步
            1:建立树模型,放入session
            2:指出树型标签将要在哪个session变量中显示
            3:定制外观
(一)树模型
标签库中的标签需要树模型的支持,树模型没有什么神秘,下面是它的例子:

ITree tree = new Tree();

//参数说明(node's id , node's name , node's type)
ITreeNode root = new TreeNode(“rootId” , “Servers” , “root”);
ITreeNode server1 = new TreeNode(“server1Id”, “Exchange Server”, “server”);
ITreeNode server2 = new TreeNode(“server2Id”, “Notes Server” , “server”);
root.addChild(server1);
root.addChild(server2);
tree.setRoot(root);

session.setAttribute("tree.model", tree);

//原型说明:
      void javax.servlet.http.HttpSession.setAttribute(String arg0, Object arg1);
      先建树,树的实例含哪些结点是被展开或选择.这些信息并不放在节点上,然后,建立根节点,和两个子节点,最后,根被加在树上,在此,当然能给树加更多的层次,这里为了简洁,不赘述.
      最后一行不属于树模型的建造,它只是把树模型存放在一个地方以利用树标签能够找到.把树模型存在SESSION属性中是大众方法.当然,你最好不要每接到一个页面请求就重新生成树模型,否则,包含展开和被选节点的状态将被不断的覆盖.正确的做法:先检查session变量,看是否树模型已经存入,若否,则新建并存入.否则,什么事情都不要做.
(二)树型标签:
      要想用标签显示树型结构,则需要稍微了解下树型模型.一旦你了解了,你就能用他们做更多的结构出来.格式:
指向树模型:
      首先,选择要显示的模型,他们通常存在session属性中,所以标签需要知道session属性的名字:下示:

<%@ taglib uri="/WEB-INF/treetag.tld" prefix="tree" %>
<tree:tree tree="tree.model">
</tree:tree>

      标签的作用在于发现树和读取可用的节点,它本身并不设计树,也不显示任何树模型的数据.每颗树标签以<tree:tree ...>开始,以</tree:tree>结束.这些嵌套的标签需要知道怎么发现可用节点.所以为了可用,你必须在 <tree:tree ...>标签中指定,指定时,需要说明节点属性:

<tree:tree tree="tree.model" node="tree.node">
</tree:tree>
      现在<tree:tree ...>标签将按读取过来的顺序存放节点,并把他们作为一个request属性存放,而不是session属性.他们被放在关键字"tree.node"下,嵌套的标签和脚本通过以下方式发现节点:

<%ITreeIteratorElement nodeElement = (ITreeIteratorElement) request.getAttribute("tree.node");%>

      现在你能通过脚本打印节点ID和别的节点的信息:

<%=nodeElement.getId()%>
<%=nodeElement.getNode().getType()%>
... etc.
显示节点名称:
标签<tree:nodeName ...> 显示读取到的树型节点的名称

<tree:tree tree="tree.model" node="tree.node">
<tree:nodeName node="tree.node"/>
</tree:tree>

这样,它将在浏览器中显示:
-------------------
Servers
-------------------
它一点都不象树,不是吗?那是因为我们之前没有做一些格式定制的工作.因此现在它只显示了根节点.

添加展开操作:
为了能顺序显示子节点,第一步是要给每个可用的节点添加展开操作.这样我们才能展开根节点并查看2个增加过的子节点.这些可用通过使用通用标签 <tree:nodeMatch ...>来实现.
<tree:tree tree="tree.model" node="tree.node">
 <tree:nodeMatch node="tree.node">
  <img src="../images/collapsedMidNode.gif" border="0">
 </tree:nodeMatch>
 <tree:nodeName node="tree.node"/>
</tree:tree>
这样,它将在浏览器中显示:
--------------------
| +-Servers
--------------------
现在离完美还甚远,下一步是激活展开操作.刚才你使不能单击打开它的,只有一个图象,而没有链接.激活它的最简单的方法是给图片添加一个标准的HTML链接.<tree:tree ...>标签能侦测到节点展开的请求参数. 通常,<tree:tree ...>标签检查这个请求是否含有"expand"参数.如果有,<tree:tree ...>标签将假定参数的值是要展开的节点的ID. <tree:tree ...>标签将调用自己的ITree实例的ITree.expand(nodeId)方法来展开节点.
简而言之,生成一个回到包含树型标签的页面链接,需要的条件:一个请求参数,展开操作,欲展开的节点ID.总观:
<tree:tree tree="tree.model" node="tree.node">
 <tree:nodeMatch node="tree.node">
  <a href="myTree.jsp?expand=rootId"><img
  src="../images/collapsedMidNode.gif" border="0"></a>
 </tree:nodeMatch>
 <tree:nodeName node="tree.node"/>
</tree:tree>
然而,上面的链接并不是动态的,它只能展开根结点,而不管下一个节点是否将被显示.为了能动态的链接,它其实需要得到每个读到的节点的ID。这些都是<tree:nodeId ...>标签的作用:例子:
<tree:tree tree="tree.model" node="tree.node">
 <tree:nodeMatch node="tree.node">
  <a href="myTree.jsp?expand=<B><tree:nodeId node='tree.node'/></B>"><img
  src="../images/collapsedMidNode.gif" border="0"></a>
 </tree:nodeMatch>
 <tree:nodeName node="tree.node"/>
</tree:tree>
这样,点击根节点它将在浏览器中显示:
--------------------------------------------------
| +-Servers  +-Exchange Server  +-Notes Server
--------------------------------------------------
注意:<a ...>与<img ...>之间没有空格。<img ...>与</a>之间也没有。如果你移动<img ...>标签到下一行,一个空格将出现在图象前,这个空格将是链接的一部分,然而这样看起来并不舒服。
垂直分放节点:
这个链接现在可以激活,点开它后,它的两个子节点也是可见的。浏览器中可以看到他们3个是在一行平行排列的。
为什么节点都在一行显示?前面提到,树标签没有做任何格式的工作。
他们能够以正确的顺序读取树型结构,并且能匹配节点。所有格式代码是写在树型标签之间的,就像写HTML一样简单.垂直显示的最简单的方法是在</tree:tree>前添加换行<br>。然而,为了方便我们后面对节点进行缩进时,最好把节点放在表格的单独行。所以添加如下代码:
<table cellspacing="0" cellpadding="0" border="0">
 <tree:tree tree="tree.model" node="tree.node">
 <tr>
  <td>
   <tree:nodeMatch node="tree.node"><a
   href="myTree.jsp?expand=<tree:nodeId node="tree.node"/>"><img
   src="../images/collapsedMidNode.gif" border="0"></a>
   </tree:nodeMatch>
  </td>
  <td>
   <tree:nodeName node="tree.node"/>
  </td>
 </tr>
 </tree:tree>
</table>
点击根节点后,浏览器中将会以垂直显示:
-----------------------
|  +-Servers
-----|-----------------
|  +-ExchangServer
-----|-----------------
|  +-Notes Server
-----------------------
节点的缩进:
上面显示的节点的图象,并不象树,需要将两个子节点"Exchange Server" 和 "Notes Server"相对他们的父节点"Servers"错开。
刚开始看起来,缩进显得不是很重要。如果你只通过空格的方式造成缩进,很容易实现。你所需要做的只是知道一个子节点的跟节点的数量。从而子节点的缩进量只是相等数量的空格而已。这种空格缩进太简单了。我们也需要能够在被展开一个或几个节点的祖先节点之间显示垂直线.象在windows浏览器和其他树型控制中一样的实现。垂直线有利于在树型变大时分清节点层次。
当缩进一个节点时,我们需要读取并知道缩进是否要显示空格或垂直线。这意味着每个节点需要知道它祖先节点在垂直线上是否有兄弟节点。祖先的兄弟节点要先于祖先节点本身显示。问题就来了,因为节点是在祖先节点和祖先的兄弟节点之间显示的。
情况看起来很复杂,所以我们要先抽象它。
对于每个可见的读到的节点,产生一个缩进的轮廓。这个轮廓指出每个缩进的读取是否使用垂直线(nodeIndentVerticalLine)标识缩进或空格(nodeIndentBlankSpace)缩进。作为一个用户,你需要给垂直线缩进或空格缩进指出要使用的图象(HTML/JSP)。下面是个例子:

<table cellspacing="0" cellpadding="0" border="0">
 <tree:tree tree="tree.model" node="tree.node">
  <tr>
   <td>
    <tree:nodeIndent node="tree.node" indentationType="type">
     <tree:nodeIndentVerticalLine indentationType="type" >
      <img src="../images/verticalLine.gif">
     </tree:nodeIndentVerticalLine>
     <tree:nodeIndentBlankSpace indentationType="type" >
      <img src="../images/blankSpace.gif">
     </tree:nodeIndentBlankSpace>
    </tree:nodeIndent>
   </td>
   <td>
    <tree:nodeMatch node="tree.node">
     <a href="myTree.jsp?expand=<tree:nodeId node="tree.node"/>"><img
     src="../images/collapsedMidNode.gif" border="0"></a>
    </tree:nodeMatch>
   </td>
   <td>
    <tree:nodeName node="tree.node"/>
   </td>
  </tr>
 </tree:tree>
</table>
<tree:nodeIndent ...>标签读取目前节点的缩进轮廓.每个读到的缩进,都将被作为request属性使用,他们的的关键字是"type",关键字"type"是可以随机选择的.如果当前读到的是垂直线,<tree:nodeIndentVerticalLine>有效.如果当前读到的是空格, <tree:nodeIndentBlankSpace ...>有效.
点开根节点,显示如下:
-----------------------
|  +-Servers
-----|-----------------
|  +-ExchangServer
-----|-----------------
|  +-Notes Server
-----------------------
即使Servers前没有图象,它
他们并没有真的错开!原因是<td>间相互依赖.解决的办法是解除依赖,即把每个节点都放入单独的表格.代码如下:
<table cellspacing="0" cellpadding="0" border="1">
<tree:tree tree="tree.model" node="tree.node">
<tr>
<td>
 <table cellspacing="0" cellpadding="0" border="0">
  <tr>
   <td>
    <tree:nodeIndent node="tree.node" indentationType="type">
     <tree:nodeIndentVerticalLine indentationType="type">
      <img src="../images/verticalLine.gif">
     </tree:nodeIndentVerticalLine>
     <tree:nodeIndentBlankSpace indentationType="type">
      <img src="../images/blankSpace.gif">
     </tree:nodeIndentBlankSpace>
    </tree:nodeIndent>
   </td>
   <td>
    <tree:nodeMatch node="tree.node">
    <a href="myTree.jsp?expand=<tree:nodeId node='tree.node'/>"><img
       src="../images/collapsedMidNode.gif" border="0"></a>
    </tree:nodeMatch>
   </td>
   <td>
    <tree:nodeName node="tree.node" />
   </td>
  </tr>
 </table>
</td>
</tr>
</tree:tree>
</table>
点开根节点,显示如下:
---|------------------
|  + Servers
---|------------------
|  | + ExchangServer
|  |
|  + Notes Server
----------------------

 
原创粉丝点击