| 
         
     
     | 
     | 
    
  
    | 
    Tapestry入门及进阶二 | 
   
  
     | 
   
  
     | 
   
  
    | 
     作者:未知  来源:月光软件站  加入时间:2005-2-28 月光软件站  | 
   
  
    下面来谈谈Tapestry的开发流程。 Tapestry的开发主要有两种:一种是控件的开发,一种是页面的开发,其实页面也可以被看成控件。
  以我的工程为例,我的控件全放在com.ht.components下 以我的ToolBar为例, 我的ToolBar控件放在com.ht.components.toolbar下 下面有 IToolItemDescirption.java IToolItemListener.java SimpleToolItemDescription.java ToolBar_en_US.properties ToolBar_zh_CN.properties ToolBar.html ToolBar.jwc ToolItem.html ToolItem.java ToolItem.jwc
  因为我是这样设计的,一个ToolBar包括一些ToolItem项,每个ToolItem的数据由一个 IToolItemDescription来提供.
  一个控件XXX的通常组成为 一个XXX.java文件 一个XXX.jwc文件 一个XXX.html文件(当然html也可以不要,一个控件的render完全交给XXX.java去实现也是可行的) 可选的为 XXX._en_US_properties(对应的美国英语字符资源文件) XXX._zh_CN_properties(对应的中国大陆字符资源文件) XXX.xxx_properties(你还可以添加其他的local字符资源文件,只要xxx是合法的locale)
  我的例程实现:
  package com.ht.components.toolbar;
  /** * <p>Title: </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2003</p> * <p>Company: </p> * @author Hery Tang * @version 1.0 */ import org.apache.tapestry.IAsset;
  public interface IToolItemDescription {    public IToolItemListener getToolItemListener();    public IAsset getAsset();    public IAsset getDisabledAsset();    public String getLabel();    public String getActionType();    public boolean isSeparator();    public boolean isEnable(); }
  package com.ht.components.toolbar;
  /** * <p>Title: </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2003</p> * <p>Company: </p> * @author Hery Tang * @version 1.0 */ import org.apache.tapestry.IPage;
  public interface IToolItemListener {   public void actionPerformed(); }
  package com.ht.components.toolbar;
  /** * <p>Title: </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2003</p> * <p>Company: </p> * @author Hery Tang * @version 1.0 */ import org.apache.tapestry.IAsset;
  public class SimpleToolItemDescription implements IToolItemDescription{   private IToolItemListener toolItemListener;   private IAsset enabledAsset;   private IAsset disabledAsset;   private String label;   private String actionType;   private boolean isSeparator;   private boolean isEnable;   public SimpleToolItemDescription() {     isEnable = true;     isSeparator = false;   }
    public IToolItemListener getToolItemListener() {     return toolItemListener;   }   public void setToolItemListener(IToolItemListener listener) {     toolItemListener = listener;   }
    public IAsset getAsset() {     return enabledAsset;   }
    public void setAsset(IAsset asset) {     this.enabledAsset = asset;   }   public IAsset getDisabledAsset() {     return disabledAsset;   }   public void setDisabledAsset(IAsset asset) {     this.disabledAsset = asset;   }
    public String getLabel() {     return label;   }
    public void setLabel(String label) {     this.label = label;   }
    public void setActionType(String actionType) {     this.actionType = actionType;   }   public String getActionType() {     return actionType;   }      public boolean isSeparator() {     return isSeparator;   }      public void setIsSeparator(boolean value) {     isSeparator = value;   }      public boolean isEnable() {     return isEnable;   }      public void setIsEnable(boolean value) {     isEnable = value;   }
  }
  ToolBar_en_US.properties ToolBar_zh_CN.properties 暂时为空,我没有需要国际化的字符资源
  ToolBar.html
  <span jwcid="$content$"> <table width="100%" border="0" cellpadding="0" cellspacing="1">         <tr>                 <span jwcid="@Conditional" condition="ognl:!isAlignLeft">                         <td align="right">                 <table border="0" cellpadding="0" cellspacing="0">                                         <tr>                                                 <span jwcid="@Foreach" source="ognl:toolItemDescriptions" value="ognl:currentToolItemDesc">                                                                   <td>                                                                           <span jwcid="@ToolItem" description="ognl:currentToolItemDesc"/>                                                                   </td>                                                                   <td width="10">                                                                                                                                               </td>
                                                      </span>                                             </tr>                                     </table>                             </td>     </span>     <span jwcid="@Conditional" condition="ognl:isAlignLeft">         <td align="left">                                 <table border="0" cellpadding="0" cellspacing="0">                                         <tr>                                                 <span jwcid="@Foreach" source="ognl:toolItemDescriptions" value="ognl:currentToolItemDesc">                                                                 <td>                                                                         <span jwcid="@ToolItem" description="ognl:currentToolItemDesc"/>                                                                 </td>                                                                 <td width="10">                                                                                                                                           </td>                                                        </span>                                               </tr>                                     </table>             </td>     </span>             </tr> </table> </span>
  ToolBar.java package com.ht.components.toolbar;
  import org.apache.tapestry.BaseComponent; import org.apache.tapestry.IRequestCycle; import java.util.List;
  /** * Simple ArrayViewer object, for the Component chapter of the Tutorial * @author neil clayton */ public abstract class ToolBar extends BaseComponent {         private IToolItemDescription currentToolItemDesc;         private List toolItemDescriptions;
          public IToolItemDescription getCurrentToolItemDesc() {           return currentToolItemDesc;         }
          public void setCurrentToolItemDesc(IToolItemDescription itemDesc) {           this.currentToolItemDesc = itemDesc;         }
          public List getToolItemDescriptions() {           return toolItemDescriptions;         }
          public void setToolItemDescriptions(List descList) {           toolItemDescriptions = descList;         }
          /**          * @see net.sf.tapestry.AbstractComponent#cleanupAfterRender(IRequestCycle)          */         protected void cleanupAfterRender(IRequestCycle cycle) {                 currentToolItemDesc = null;                 toolItemDescriptions = null;                 super.cleanupAfterRender(cycle);         }
          public abstract boolean getIsAlignLeft(); }
  ToolBar.jwc
  <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE component-specification PUBLIC   "-//Apache Software Foundation//Tapestry Specification 3.0//EN"   "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd>
 
  <component-specification class="com.ht.components.toolbar.ToolBar" allow-body="no" allow-informal-parameters="yes">
      <parameter         name="toolItemDescriptions"         type="java.util.List"         direction="in"         required="yes">     </parameter>
      <parameter name="isAlignLeft" type="boolean" required="no" direction="in"/>
  </component-specification>
  ToolItem.html
  <span jwcid="$content$"> <span jwcid="@Conditional" condition="ognl:!isSeparator"> <span jwcid="@Conditional" condition="ognl:IsEnable">         <span jwcid="link"><img jwcid="enabledImage"/><font color="White"><span jwcid="@InsertText" value="ognl:label"/></font></span> </span> <span jwcid="@Conditional" condition="ognl:!IsEnable">         <img jwcid="disabledImage"/><font color="#A0A0A0"><span jwcid="@InsertText" value="ognl:label"/></font> </span> </span> <span jwcid="@Conditional" condition="ognl:isSeparator"> <img jwcid="@Image" image="ognl:enabledImage"/> </span> </span>
  ToolItem .java
  package com.ht.components.toolbar;
  import org.apache.tapestry.BaseComponent; import org.apache.tapestry.IBinding; import org.apache.tapestry.IRequestCycle; import org.apache.tapestry.components.Foreach; import org.apache.tapestry.IAsset;
  public class ToolItem extends BaseComponent{   private IToolItemDescription desc;
    /**    * @see net.sf.tapestry.AbstractComponent#cleanupAfterRender(IRequestCycle)    */   protected void cleanupAfterRender(IRequestCycle cycle) {     desc = null;     super.cleanupAfterRender(cycle);   }
    public IToolItemDescription getDescription() {     return desc;   }
    public void setDescription(IToolItemDescription desc) {     this.desc = desc;   }   public void excuteCurrent(IRequestCycle cycle) {     if(desc != null) {       IToolItemListener listener = desc.getToolItemListener();       listener.actionPerformed();     }   }   public IAsset getEnabledAsset() {     return desc.getAsset();   }   public IAsset getDisabledAsset() {     return desc.getDisabledAsset();   }   public String getLabel() {     return desc.getLabel();   }   public boolean getIsSeparator() {     return desc.isSeparator();   }   public boolean getIsEnable() {     return desc.isEnable();   } }
  ToolItem.jwc
  <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE component-specification PUBLIC   "-//Apache Software Foundation//Tapestry Specification 3.0//EN"   "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd>
 
  <component-specification class="com.ht.components.toolbar.ToolItem" allow-body="no" allow-informal-parameters="yes">
      <parameter         name="description"         type="com.ht.components.toolbar.IToolItemDescription"         direction="in"         required="yes">     </parameter>
      <component id="link" type="LinkSubmit">             <binding name="listener" expression="listeners.excuteCurrent"/>     </component>
      <component id="enabledImage" type="Image">             <binding name="image" expression="enabledAsset"/>     </component>
  <component id="disabledImage" type="Image">             <binding name="image" expression="disabledAsset"/>     </component> </component-specification>
  我就拿ToolBar这个控件讲: 先看ToolBar.jwc
  <component-specification class="com.ht.components.toolbar.ToolBar" allow-body="no" allow-informal-parameters="yes">
  这句是去说控件ToolBar对应的class为com.ht.components.toolbar.ToolBar allow-body="no'是说这个控件不允许有body, allow-informal-parameters="yes"是说这个控件允许带非正式参数。
  控件的参数有两种一种是在jwc文件里规定的,一种是没有规定,为什么会有非正式参数呢?大家知道Tapestry的控件,最后render到页面最终还是什么 <table width="100%" border="0" cellpadding="0" cellspacing="1">    <tr>       <td class="xxx"></td>    </tr> </table> HTML的元素如table, tr, td,span等等都是可以带很多参数,如果我们的控件输出一般会 对应于一个元素,这时非正式参数就会以元素的参数输出。
  <parameter         name="toolItemDescriptions"         type="java.util.List"         direction="in"         required="yes">     </parameter> 这个说明ToolBar控件需要配制一个叫toolItemDescriptions的参数,参数类型为java.util.List,direction为in表示这个参数仅仅需要输入,不要输出, required=yes表示这个参数是必须的,一定要提供。
 
      <parameter name="isAlignLeft" type="boolean" required="no" direction="in"/> 意义同上。
  我们再来分析一下ToolBa.html
  首先这个控件的模版被一个 <span jwcid="$content$"> </span> 包围,这个是说明,只有这个区域里的内容才是有意义的,区域外的全被忽略。
  然后这个控件可分为两部分,根据isAlignLeft参数决定这个ToolBar显示时是否向左靠齐 我们分析这一句 <span jwcid="@Conditional" condition="ognl:!isAlignLeft">
  </span> 首先讲讲怎么使用控件,Tapestry的控件有四种: Tapestry自己提供的有三种: 可参考: http://jakarta.apache.org/tapestry/doc/ComponentReference/index.html
  其中包括: 1 Framework Library (基础控件) 2 Contrib Library (Contributores 开发的控件) 3 WML Library   (应用在WML上的控件,主要用在移动设备,暂时不谈)
  4 自己开发的控件 
  在Tapestry中控件是可以由别的控件组成的,而且控件的嵌套级数不受限制,要在一个页面或一个控件中应用已开发的控件或Tapestry的提供的控件有两种方式:
  一种是在控件规范文件(*.jwc)或页面规范文件(*.page)声明后再在HTML模版里使用 一种直接在HTML模版里使用.
  不过这两种情况有个共同点,你都会在HTML模版发现<span jwcid="***">的字样。
  第一种情况: 你看那个ToolItem.jwc 里面含有   <component id="link" type="LinkSubmit">             <binding name="listener" expression="listeners.excuteCurrent"/>     </component>
      <component id="enabledImage" type="Image">             <binding name="image" expression="enabledAsset"/>     </component>
  <component id="disabledImage" type="Image">             <binding name="image" expression="disabledAsset"/>     </component>
  这里就是声明里三个空间,我们就看第一个,   <component id="link" type="LinkSubmit">             <binding name="listener" expression="listeners.excuteCurrent"/>     </component>  这里声明一个控件 id为link,id要是唯一的(是在同一控件名字空间里),  type为LinkSubmit,就是指定这个控件的类型,当然如果是使用自己开发的控件,还要注意名字空间的问题,这个问题下面再谈。
   <binding name="listener" expression="listeners.excuteCurrent"/>
  这句是为这个控件listener参数绑定一个值,expression=listeners.excuteCurrent 这个表达式是一个OGNL表达式,它等同于expression=this.getListeners().getListener("excuteCurrent");这里的this当然是com.ht.components.toolbar.ToolItem 所以我们察看ToolItem,会发现这个listener绑定的方法是
  public void excuteCurrent(IRequestCycle cycle) {     if(desc != null) {       IToolItemListener listener = desc.getToolItemListener();       listener.actionPerformed();     } }
  现在这个控件(id=link)声明配置好了,我们再看看ToolItem.html 会发现这一段 <span jwcid="link"><img jwcid="enabledImage"/><font color="White"><span jwcid="@InsertText" value="ognl:label"/></font></span>
  注意<span jwcid="link">***</span>,里面的东西暂时不管 这个<span jwcid="link">就是引用的我们刚才那个叫link的LinkSubmit控件。
  第二种是直接在HTML模版里使用:
  再回到前面看ToolBa.html里的那一句 <span jwcid="@Conditional" condition="ognl:!isAlignLeft">
  </span>
  这里就是在HTML模版里直接使用控件的例子,这里意思是使用一个类型为Conditional的控件,id忽略,Tapestry会给它自动指定一个id,如果你写成 <span jwcid="xxx@Conditional" condition="ognl:!isAlignLeft"> 那么你指定了这个控件的id为xxx. 这里的condition="ognl:!isAlignLeft"就跟我们规范文件(*.jwc,*.page)里写成的 <binding name="condition" expression="!isAlignLeft"/>是一个意义。
  开发好控件的管理:
    对于自己开发的控件,我们要把它管理起来,以便在以后的开发流程中使用, 我的在这里谈谈如何管理自己开发的控件的问题。具体的方法就是把它归档到一个library 里去。
  比如我开发了一些控件,我就把它归档到一个叫Common.library的xml文档里去。
  Common.library
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE library-specification PUBLIC   "-//Apache Software Foundation//Tapestry Specification 3.0//EN"   "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd>
  <library-specification> <!-- Library Section--> <library id="contrib" specification-path="/org/apache/tapestry/contrib/Contrib.library"/> <library id="basic" specification-path="/com/ht/components/basic/Basic.library"/> <!-- Add more libraries here.--> <!-- End of Library Section-->
  <component-type type="TabPanel" specification-path="tabpanel/TabPanel.jwc"/> <component-type type="Border" specification-path="border/Border.jwc"/> <component-type type="ToolItem" specification-path="toolbar/ToolItem.jwc"/>     <component-type type="ToolBar" specification-path="toolbar/ToolBar.jwc"/> <component-type type="AnchorDirect" specification-path="tree/components/AnchorDirect.jwc"/>     <component-type type="TreeDataView" specification-path="tree/components/TreeDataView.jwc"/>     <component-type type="TreeHeaders" specification-path="tree/components/TreeHeaders.jwc"/>     <component-type type="TreeNodeView" specification-path="tree/components/TreeNodeView.jwc"/>     <component-type type="TreeView" specification-path="tree/components/TreeView.jwc"/> <component-type type="FileList" specification-path="table/FileList.jwc"/> <component-type type="WrapInsertText" specification-path="wraptext/WrapInsertText.jwc"/> <component-type type="HighlightInsertText" specification-path="highlight/HighlightInsertText.jwc"/> <component-type type="DefaultTableColumnComponent" specification-path="table/DefaultTableColumnComponent.jwc"/> <component-type type="AlignRightTableColumnComponent" specification-path="table/AlignRightTableColumnComponent.jwc"/> <component-type type="DefaultTableColumns" specification-path="table/DefaultTableColumns.jwc"/> </library-specification>
  <libray-specification>包含两种元素 一种是library<library id="contrib" specification-path="/org/apache/tapestry/contrib/Contrib.library"/>
  因为如果被归档的控件还引用到其他的被归档的控件(控件库),就必须在这里包含进来。
  例外一种是 <component-type type="ToolBar" specification-path="toolbar/ToolBar.jwc"/> 就是被归档的控件项定义,这句我们应该有印象,这个控件就是我们前面讨论的ToolBar 注意这个specification-path是相对路径。 比如我的Common.library位于com.ht.components包内,而那个ToolBar.jwc位于com.ht.components.toolbar包内。
  页面的开发: 我的Web Application只支持英语和简体中文,以开发Home页为例,我所需要新建的文件 为: Home.java Home.page Home.properties Home_zh_CN.properties 它们都位于com.ht.home包内,对应的目录为F:\myproject\TapestryExmaple\src\ com\ht\home
  Home.html 它位于context下home目录内,对应的目录为F:\myproject\TapestryExmaple\context\home
  我的例程为: Home.java package com.ht.home;
  import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.tapestry.engine.AbstractEngine; import org.apache.tapestry.html.BasePage; import com.ht.web.PatientRecordBasePage; import com.ht.web.PatientRecordEngine; import com.ht.components.tabpanel.*;
 
  /** * @author Hery Tang * * Creation Date 2003-9-22 * Version 1.0 */ public class Home extends PatientRecordBasePage {     public void logout() {         PatientRecordEngine engine = (PatientRecordEngine) getEngine();
          engine.logout();     } }
  Home.page
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE page-specification PUBLIC  "-//Apache Software Foundation//Tapestry Specification 3.0//EN"  "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd>
  <page-specification class="com.ht.home.Home"> <component id="border" type="common:Border"> <message-binding name="title" key="title"/> <binding name="styleSheet" expression="assets.test"/> </component>
  <context-asset name="$template" path="home/Home.html"/> <context-asset name="menuIcon" path="home/images/homeIcon.gif"/> <context-asset name="test" path="home/css/test.css"/> </page-specification>
  Home_zh_CN.properties
  menuText=首页 title=首页 actionListener.logout.menuText=注销
  welcome=欢迎 welcomeDetail=欢迎使用web病历管理系统,这是一套基于网络的B/S结构的病历管理服务系统,功能新颖,界面友好,欢迎使用。
 
  Home.properties
  title=Home menuText=Home actionListener.logout.menuText=Logout
  welcome=Welcome welcomeDetail=Welcome to use Web Document Manage System.This system based on B/S network structure, it provides internal documents' management for your company. It's document directory organized as that: a department as a unit, departments can share documents each other. Meanwhile, it provides detailed document version control.    
 
  Home.html
  <span jwcid="border"> <table align="center" width="100%" height="100"> <tr> <!-- ========================== START MID COL ======================= --> <td VALIGN="TOP" width='100%'> <table width='100%' cellpadding='0' cellspacing='0' border='0'> <tr> <td width='10'><img src='home/images/pixel.gif' width='10' height='1' alt='-'></td> <td width='100%'><img src='home/images/welcome_head_icon.gif' ALIGN="BOTTOM" WIDTH="16" HEIGHT="16"  ALT="Welcome!"> <font class='h2' style='color: #080c77;'><span key="welcome">Welcome</span></font></td> <td width='10'><img src='home/images/pixel.gif' width='10' height='1' alt='-'></td> </tr> <tr> <td height='5' colspan='3' valign='top'><img src='home/images/head_home_line.gif' width='254' height='5' alt='-'></td> </tr> <tr> <td height='5' colspan='3' bgcolor='#ffffff'><img src='home/images/pixel.gif' width='1' height='5' alt='-'></td> </tr> <tr> <td width='10' bgcolor='#ffffff'><img src='home/images/pixel.gif' width='10' height='1' alt='-'></td> <td width='100%' bgcolor='#ffffff'> <span key="welcomeDetail">Welcome to use Web Document Manage System.This system based on B/S network structure, it provides internal documents' management for your company. It's document directory organized as that: a department as a unit, departments can share documents each other. Meanwhile, it provides detailed document version control.</span> </td> <td width='10' bgcolor='#ffffff'><img src='home/images/pixel.gif' width='10' height='1' alt='-'></td> </tr> <tr> <td height='5' colspan='3' bgcolor='#ffffff'><img src='home/images/pixel.gif' width='1' height='5' alt='-'></td> </tr> </table>             </td>         </tr>     </table>   </span>
 
  对于页面的开发,有几个值得讨论的问题, 一 框架化的页面怎么实现    这个很简单,你只要开发一个控件,预先定义好一个显示框架,我就是这么做的,我开发了一个叫Border的控件,然后把变动的显示作为Border可变的内容输出。 你看我的 Home.html,它被<span jwcid="border">**</span>所包围,我的Border控件负责 显示每页确定的内容,变动的则只在Border的一个预定的区域显示。
  二  国际化怎么办     Tapestry国际化非常简单,例如英文我要显示welcome,中文显示欢迎 只须这样就行:     <span key="welcome">Welcome</span>(中间的Welcome是预览hmtl用的没有 别的意义),然后你在home.properties设定key-value对为: welcome=Welcome 在Home_zh_CN.properties设定为: welcome=欢迎,不过最后打包时你要将你的 Home_zh_CN.properties用jdk的bin目录下的native2ascii命令转化一下,不然会 显示成乱码。
  我们来分析一下Home.page
  <page-specification class="com.ht.home.Home"> 声明本页对应的class为com.ht.home.Home <component id="border" type="common:Border"> <message-binding name="title" key="title"/> <binding name="styleSheet" expression="assets.test"/> </component> 声明并配置一个Border类型的控件 <message-binding name="title" key="title"/> 指定了本页的title binding name="styleSheet" expression="assets.test"/> 指定了本页应用的StyleSheet资源
  <context-asset name="$template" path="home/Home.html"/> 指定了Home页的模版为home/Home.html <context-asset name="menuIcon" path="home/images/homeIcon.gif"/> 声明一个context-asset(图标) <context-asset name="test" path="home/css/test.css"/> 声明一个context-asset(Stylesheet),被上面的Border控件引用
 
  最后讲讲划分子模块的问题:
  比如我的Web Application包含两个子模快home, patientrecord, home对应的包为com.ht.home,绝对路径为F:\myproject\TapestryExmaple\src\ com\ht\home,对应的context目录为home,绝对路径为F:\myproject\ TapestryExmaple\context\home
  patientrecord对应的包为com.ht.patientrecord,绝对路径为F:\myproject\TapestryExmaple\src\com\ht\patientrecord, 对应的context目录为patientrecord,绝对路径为F:\myproject\ TapestryExmaple\context\patientrecord
 
  home模块下的页面有 Home,Register,Login,About,PaitentRecordException,SecurityException
  patientrecord模块下的页面有
  Browser,Create,AddTreatment,AddExamination,AddOperation,AddOperationVisit,AddOperationVisit,AddComment
  我需要将这些页面归档,所以对应home子模块有Home.libray,对应于patientrecord 有PatientRecord.library
  Home.library的位于com.ht.home包下, PatientRecord.library位于com.ht.patientrecord包下
  他们分别为 Home.library
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE library-specification PUBLIC   "-//Apache Software Foundation//Tapestry Specification 3.0//EN"   "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd>
  <library-specification> <!-- Library Section--> <library id="contrib" specification-path="/org/apache/tapestry/contrib/Contrib.library"/> <library id="common" specification-path="/com/ht/components/Common.library"/>  <!-- Add more libraries here.-->
  <!-- End of Library Section-->
  <page name="Home" specification-path="Home.page"/> <page name="Register" specification-path="Register.page"/> <page name="Login" specification-path="Login.page"/> <page name="About" specification-path="About.page"/> <page name="PaitentRecordException" specification-path="PRException.page"/> <page name="SecurityException" specification-path="SecurityExceptionPage.page"/> </library-specification>
  PatientRecord.library <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE library-specification PUBLIC   "-//Apache Software Foundation//Tapestry Specification 3.0//EN"   "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd>
  <library-specification> <!-- Library Section--> <library id="contrib" specification-path="/org/apache/tapestry/contrib/Contrib.library"/> <library id="common" specification-path="/com/ht/components/Common.library"/> <!-- Add more libraries here.-->
  <!-- End of Library Section-->
  <page name="Browser" specification-path="Browser.page"/> <page name="Create"  specification-path="Create.page"/> <page name="AddTreatment" specification-path="AddTreatment.page"/> <page name="AddExamination" specification-path="AddExamination.page"/> <page name="AddOperation" specification-path="AddOperation.page"/> <page name="AddOperationVisit" specification-path="AddOperationVisit.page"/> <page name="AddComment" specification-path="AddComment.page"/> 
  </library-specification>
  最后我们再看一下patientrecord.application这个Tapestry Web 应用核心配置文件:
  patientrecord.application
  <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE application PUBLIC   "-//Apache Software Foundation//Tapestry Specification 3.0//EN"   "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd>
  <application name="Patient Record System" engine-class="com.ht.web.PatientRecordEngine">   <property name="org.apache.tapestry.visit-class" value="com.ht.web.VisitorState"/>
    <property name="com.ht.home-page" value="home:Home"/>
    <!--<property name="com.ht.exception-page" value="home:PaitentRecordException"/>-->     <property name="com.ht.security-exception-page" value="home:SecurityExceptionPage"/>
    <!--Overrided the Home Service to let us to decide which page will be the home page-->   <service name="home" class="com.ht.web.HomeService"/>       <library id="home" specification-path="/com/ht/home/Home.library"/>   <library id="patientrecord" specification-path="/com/ht/patientrecord/PatientRecord.library"/>  </application>
  看看最后两行 <library id="home" specification-path="/com/ht/home/Home.library"/>   <library id="patientrecord" specification-path="/com/ht/patientrecord/PatientRecord.library"/>
  我们把那两个libary文件包含进来了,分别对应id为home, patientrecord ,我们要在程序里激活Home页,则只需   得一个IRequestCycle对象cycle   cycle.activate("home:Home");
  注意“home:Home“,前一个home是library name,后一个是Page name.这是Tapestry 自定义的名字访问法则。
  以上,是我开发Tapestry Web Application的一点心得体会,欢迎讨论批评.
  msn:[email protected] QQ:15520929
 
 
  
 
  | 
   
  
     | 
   
  
     相关文章:相关软件:  | 
   
   
      |