`

Tapestry 4 实现自定义组件-CheckboxList

阅读更多

[本文中的程序在JDK 6, Tapestry 4.1中测试通过]

用Tapestry自定义组件和创建一个page一样简单,同样要创建三个文件,html模板,配置文件,java类文件,只不过配置文件后缀不是page了,而是jwc。


定义组件的html模板

组件html模板和page的模板基本差不多,只不过组件模板可以是html的片段,也可以是完整的html文件。我们要实现的CheckboxList只需要一个html片段作为模板:

  1. <table border="0" cellpadding="0" cellspacing="0">
  2. <tr jwcid="allItems">
  3. <td>
  4. <input type="checkbox" jwcid="curItem"/>
  5. <span jwcid="curItemLabel">Checkbox 1<!---->span>
  6. <!---->td>
  7. <!---->tr>
  8. <!---->table>


将一个表格作为模板,每一个checkbox和一个标签作为一行。

CheckboxList.java处理类中,添加两个组件的参数:

  1. @Parameter(name = "allItems", required = true)
  2. public abstract List <basepojo> getAllItems(); </basepojo>
  3. @Parameter(name = "selectedItems", required = false)
  4. public abstract List <basepojo> getSelectedItems(); </basepojo>


这两个参数接受用户指定的所有checkbox项的集合组件显示的时候选中项的集合,前者是required,后者是可选的(不指定的话就是不选中任何的checkbox)


CheckList.jwc文件中,循环指定给组件参数的allItems:

  1. <property name="curItem"/>
  2. <property name="itemIndex"/>

 

  1. <component id="allItems" type="For">
  2. <binding name="source" value="allItems"/>
  3. <binding name="value" value="curItem"/>
  4. <binding name="index" value="itemIndex"/>
  5. <binding name="element" value="literal:tr"/>
  6. <!---->component>


将curItem和itemIndex输出给CheckboxList模板上的Checkbox组件和Insert组件,分别显示一个Checkbox和一个标签:

  1. <component id="curItem" type="Checkbox">
  2. <binding name="id" value="ognl:name"/>
  3. <binding name="value" value="mapping[itemIndex]"/>
  4. <!---->component>
  5. <component id="curItemLabel" type="Insert">
  6. <binding name="value" value="curItem"/>
  7. <!---->component>



注意Checkbox中的value="mapping[temIndex]",这个mapping是一个boolean的数组,和allItems中的项一一对应,里面标识了所有的checkbox项的选中情况,某项选中则对应的mapping[i]为true,否则为false。这个mapping 需要我们根据组件使用者给定的两个参数来生成。renderComponent方法是BaseComponent的用于渲染整个组件的方法,我们需要override该方法并在这里生成或者说初始化mapping:

CheckboxList.java
  1. private boolean[] mapping = null;
  2. @Override
  3. protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
  4. mapping = new boolean[this.getAllItems().size()];
  5. for(int i=0;i<this.getAllItems().size();i++){
  6. if(getSelectedItems()==null)continue;
  7. mapping[i] = getSelectedItems().contains(this.getAllItems().get(i));
  8. }
  9. super.renderComponent(writer, cycle);
  10. }


然后,你就可以在你的页面中使用CheckboxList组件来显示内容了。

在你的页面中使用CheckboxList组件
  1. <component id="userSelectionList" type="CheckboxList">
  2. <binding name="name" value="literal:userSelectionList"/>
  3. <binding name="allItems" value="ognl:allUsers"/>
  4. <binding name="selectedItems" value="ognl:selectdUsers"/>
  5. <!---->component>


至此,我们的CheckboxList组件已经可以页面上显示所有的Checkbox项,并正确选中用户指定的Checkbox项了。
但是还没有完,在我们修改这些Checkbox的选中状态后,如何将改动反映给处理类,使之可以将改动保存到DB中呢?
可以看到,虽然我们将选定项集合从参数selectedItems传递到了我们自定义的CheckboxList组件中,但是真正和Checkbox组件绑定的是mapping,所以当你改变某个Checkbox的选中状态后相应的mapping的值会改变,而不会改变参数selectedItems的内容。因此,我们需要自己编码来把他实现了。在前面的CheckboxList.java中的renderComponent后面方法中加入以下语句:

java 代码
  1. if(cycle.isRewinding()){
  2. List <basepojo> reselectedList = new ArrayList <basepojo>(); </basepojo> </basepojo>
  3. for(int i=0;i<this.getAllItems().size();i++){
  4. if(mapping[i] == false)continue;
  5. reselectedList.add(this.getAllItems().get(i));
  6. }
  7. this.setSelectedItems(reselectedList);
  8. }

调用cycle.isRewinding()方法告诉我们是否是用户提交表单。
完整的renderComponent方法就是:



@Override
protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
    mapping = new boolean[this.getAllItems().size()];
    for(int i=0;i<this.getAllItems().size();i++){
    if(getSelectedItems()==null)continue;
        mapping[i] = getSelectedItems().contains(this.getAllItems().get(i));
    }
    super.renderComponent(writer, cycle);
    if(cycle.isRewinding()){
        List reselectedList = new ArrayList(); 
        for(int i=0;i<this.getAllItems().size();i++){
        if(mapping[i] == false)continue;
            reselectedList.add(this.getAllItems().get(i));
        }
        this.setSelectedItems(reselectedList);
    }
}
 


这样,我们CheckboxList就可以和用户指定的选定项的集合完全的绑定起来,就是说既可以取值也可以设值了,一个具有完整功能的自定义组件也就实现啦!

分享到:
评论

相关推荐

    tapestry5 自定义组件

    在 Tapestry 5 框架中,自定义组件是扩展其功能的关键方式,它允许开发者根据特定需求创建个性化和可重用的 UI 元素。Tapestry 5 是一个强大的 Java Web 应用程序开发框架,它强调组件化、模块化以及声明式编程模型...

    tapestry-bin-5.1.0.5

    4. **tapestry-ioc-LICENSE.txt**:这部分涉及Tapestry的依赖注入(IOC)框架,它是Tapestry实现组件之间解耦的关键部分。 5. **tapestry-upload-LICENSE.txt**:关于Tapestry中文件上传功能的许可信息,帮助开发者...

    tapestry-ioc-5.0.3-src

    通过深入研究"tapestry-ioc-5.0.3-src"中的源代码,开发者可以了解Tapestry IOC如何实现这些功能,以及如何将其应用于实际项目,以提升Web应用的开发效率和质量。同时,源代码还提供了丰富的示例,帮助开发者更好地...

    tapestry5 build web application-alexander

    通过阅读此书,读者能够深入理解Tapestry 5如何将MVC(模型-视图-控制器)模式与组件编程思想结合,实现高度模块化和可重用的Web应用设计。 1. **组件模型**:Tapestry 5的核心是组件模型,它允许开发者创建可复用...

    tapestry-project-4.1.5

    在"tapestry-project-4.1.5"这个压缩包中,我们有机会深入探索 Tapestry 4.1.5 版本的特性和应用。 首先,让我们关注"Tapestry-libraries"这个文件夹。它包含了Tapestry 框架运行所需的各种库文件,这些库文件是...

    tapestry教程资料文档合集

    Tapestry5最新中文教程.doc 作者 Renat Zubairov & Igor Drobiazko译者 沙晓兰 发布于 2008年7月2日 下午9时30分 社区 Java 主题 Web框架 ----------------------------------------- Tapestry5.1实例教程.pdf ...

    tapestry4开发指南

    在深入探讨Tapestry 4的编程模型时,读者将学习如何使用Ivy或Maven来管理依赖,理解配置文件的结构,以及如何编写自定义组件。此外,书中还会涉及组件库的使用,包括内置的表单组件、导航组件等,这些组件可以帮助...

    apache-tapestry-5.3.8-bin.zip

    4. **Tapestry IoC (Inversion of Control)**:`tapestry-ioc-5.3.8.jar`实现了依赖注入容器,使得对象的创建和管理变得更加简单,同时也促进了代码的解耦。开发者可以声明服务并定义它们之间的依赖关系,IoC容器会...

    Tapestry简单入门.rar_java Tapestry_tapestry

    4. **编写第一个页面**:在Tapestry中,一个页面是由一个或多个组件组成的。你需要定义一个类来表示页面,并在HTML模板中声明组件。 接下来,我们转向"tapestry组件.docx",组件是Tapestry的核心组成部分,它们是可...

    tapestry-clojure-5.4-beta-3.zip

    android-priority-jobqueue.zip,一种专为android编写的作业队列,用于方便地调度在后台运行的作业(任务),提高用户体验和应用程序稳定性。一种专为android编写的作业队列,用于方便地调度在后台运行的作业(任务)...

    apache-tapestry-5.3.7-bin.zip

    例如,`tapestry-core-5.3.7.jar`包含了Tapestry框架的基础库,提供了核心组件、服务、事件处理和生命周期管理等功能。 Tapestry IOC(Inversion of Control)容器,如`tapestry-ioc-5.3.7.jar`,是Tapestry框架的...

    Tapestry4开发指南

    4) **定义页面**:页面是Tapestry4中的主要交互单元,它由一个或多个组件组成。在Java类中定义页面,然后在HTML模板中引用这些组件。 5) **配置URL映射**:Tapestry4通过元数据来处理URL到页面和组件的映射。在模块...

    Tapestry-3-Getting Started.doc

    - **项目名称**:Tapestry-3-Getting Started - **项目目标**:开发一个基于Web的货币转换器应用。 - **技术栈**:Tapestry 3、Eclipse IDE、Apache Tomcat。 #### 二、开发环境搭建 ##### 1. Eclipse IDE安装 - **...

    tapestry4.02中封装ext的GridPanel组件

    4. **设置JavaScript逻辑**:`GridPanel.jwc`文件可能包含了组件的JavaScript配置,用于初始化和配置ExtJS的GridPanel实例。这里通常会涉及数据源的配置、列定义、事件监听器等。 5. **资源文件**:`GridPanel....

    tapestry页面编辑组件

    在Tapestry中,这些组件不仅可以方便地呈现和管理用户输入,还可以配合各种事件处理程序,如onChange、onSubmit等,实现复杂的业务逻辑。同时,Tapestry的类型安全机制确保了服务器接收到的数据是经过验证的,减少了...

    优化大使tapestry-bin-5.0.18.zip

    这个压缩包包含了多个以"Tapestry"开头的子文件,如 "tapestry-core", "tapestry-hibernate", "tapestry-ioc", "tapestry-upload", 和 "tapestry-spring",这些都是Tapestry框架的不同模块或插件。这些文件的后缀是...

    深入浅出Tapestry4一书源代码(2)

    在Tapestry4中,每个页面都是由一组相互关联的组件构成的,这些组件可以是简单的HTML元素,也可以是复杂的自定义Java类。在"quickStart"中,我们通常会看到如`index.tml`这样的页面模板文件,它使用TML(Tapestry ...

    (Tapestry)An infrastructure for Fault-Tolerant Wide-area Location and Routing.ppt

    Tapestry是一个分布式系统基础设施,专门设计用于实现容错性的广域定位和路由。这个系统由Ben Y. Zhao、John Kubiatowicz和Anthony D. Joseph等人在加州大学伯克利分校的计算机科学部开发,旨在应对无处不在计算的...

    Tapestry开发

    &lt;tapestry:foreach each="${list}" var="item"&gt; ${item.name} &lt;/tapestry:foreach&gt; ``` **2. Insert组件:** - **用途:**用于插入HTML代码片段到页面中。 - **示例代码:** ```xml &lt;tapestry:insert ...

Global site tag (gtag.js) - Google Analytics