RichFacesCDK:构建自定义组件
立即解锁
发布时间: 2025-08-21 02:21:54 阅读量: 1 订阅数: 5 


RichFaces实战指南:深入解析JSF框架的高级应用
### RichFaces CDK:构建自定义组件
在开发过程中,我们常常需要构建自定义组件来满足特定的业务需求。RichFaces CDK 提供了强大的功能,帮助我们更高效地创建自定义组件。下面将详细介绍如何使用 RichFaces CDK 构建自定义组件。
#### 创建组件库
在创建组件类和渲染器模板之前,我们需要先定义标签库。以下是具体步骤:
1. 创建一个 `package-info.java` 类,并将其放在 `org.richfaces.book` 包中,内容如下:
```java
@org.richfaces.cdk.annotations.TagLibrary(uri="http://org.richfaces.book/spinner", shortName="in")
package org.richfaces.book;
```
**注意**:如果在 Eclipse 中操作,使用“Create File”而不是“Create Class”向导来创建 `package-info.java`,因为 Eclipse 的类向导不允许使用这样的文件名。
使用这个注解,CDK 会在生成 VDL(View Description Language)标签库时添加基本信息,如下所示:
```xml
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd" version="2.0" id="in">
<namespace>http://org.richfaces.book/spinner</namespace>
...
</facelet-taglib>
```
之后,生成器会填充标签及其属性。
#### 创建抽象组件类
接下来,我们要为旋转器组件创建抽象组件类,将其放在 `org.richfaces.book.component` 包中。该类的目的是比手动创建 `UIComponent` 类更轻松地描述生成的组件契约。示例代码如下:
```java
@JsfComponent(type = "org.richfaces.book.Spinner", family = "javax.faces.Input", renderer =
@JsfRenderer(template = "spinner.template.xml"))
public abstract class AbstractSpinnerComponent extends UIInput {
@Attribute
public abstract boolean isDisabled();
@Attribute(defaultValue = "1")
public abstract String getStep();
@Attribute(defaultValue = "0")
public abstract String getMinValue();
@Attribute(defaultValue = "100")
public abstract String getMaxValue();
}
```
通过这个类,我们可以看到一组 CDK 注解,主要有 `@JsfComponent` 和 `@Attribute`。`@JsfComponent` 标记该类为基础组件类,用于生成 UI 类;`@Attribute` 用于指定要在 UI 类中生成的属性。以下是这两个注解的重要属性说明:
| `@JsfComponent` 属性 | 描述 |
| ---- | ---- |
| `type` | 指定生成组件的组件类型 |
| `family` | 指定生成组件的组件家族 |
| `generate` | 要生成的 UI 类的名称,默认是 UI<抽象类名>(去掉“abstract”前缀) |
| `facets` | 定义组件的方面,是 `@Facet` 注解的数组,`Facet#generate()` 属性告诉 CDK 为方面生成 getter 和 setter 方法 |
| `fires` | `@Event` 注解的数组,定义组件触发的 JSF 事件(以及继承自 `FacesEvent` 的自定义事件),CDK 会为每个事件生成 `add/remove/get<Event>Listener` 方法、创建 `<event>Listener` 标签处理程序和监听器类 |
| `tag` | 允许为组件指定标签名和处理程序类 |
| `attributes` | 包含字符串数组,每个字符串是 `faces-config.xml` 片段的名称,用于 CDK 在不同组件中重用属性定义,CDK 在项目类路径的 `META-INF/cdk/attributes` 文件夹中查找这些文件 |
| `renderer` | 将组件与渲染器实现关联,有两种方式:通过渲染器类型或模板名称。对于类型,CDK 不检查目标渲染器的存在性;对于模板名称,CDK 强制渲染器和组件共享相同的渲染器类型和家族 |
| `interfaces` | 生成的组件应实现的 Java 接口类数组 |
| `@Attribute` 属性 | 描述 |
| ---- | ---- |
| `aliases` | 为单个属性定义不同的名称 |
| `defaultValue` | 有效的 Java 表达式,计算为属性的默认值 |
| `events` | 客户端行为事件定义的数组,`@EventName` 注解的值是事件名称,`defaultEvent` 定义将事件标记为默认行为事件 |
| `literal` | 禁用属性的 EL 表达式 |
| `passThrough` | 定义属性以 HTML 属性形式渲染,不进行转换 |
| `readOnly` | 禁用 setter 方法的生成 |
| `required` | 强制标签处理程序检查开发人员是否为该属性提供了显式值 |
执行 `mvn install` 构建项目后,在 `target/generated sources` 文件夹的“main/resources”中可以找到 `faces-config.xml`,它包含标准组件描述符条目和一些 CDK 扩展标签。更重要的是在 `main/java/org/richfaces/book/component` 中可以看到生成的 `UISpinner` 类,示例代码如下:
```java
public class UISpinner extends AbstractSpinnerComponent{
public static final String COMPONENT_FAMILY="javax.faces.Input";
public static final String COMPONENT_TYPE="org.richfaces.book.Spinner";
@Override
public String getFamily() {
return COMPONENT_FAMILY;
}
protected enum Properties {
disabled,
maxValue,
minValue,
step
}
public boolean isDisabled() {
Boolean value = (Boolean) getStateHelper().eval(Properties.disabled, false);
return value;
}
// More component attributes accessor methods
}
```
我们只需在抽象组件类上使用 `@JsfComponent` 注解,并在几个抽象 getter 方法上使用 `@Attribute` 注解,就能得到这些代码。
#### 创建组件渲染器模板
现在,我们回到之前创建的 HTML 模板,创建一个渲染器类来编码标记和脚本,同时学习 RichFaces CDK 渲染器模板的基础知识。模板的用途如下:
- 以标准 HTML 格式定义组件的标记,这将在生成的渲染器类中转换为 `set` 或 `ResponseWriter` 方法。
- 允许添加常见的、特定于渲染器的属性(例如,导入常见的 HTML 属性)。
模板文件是一个格式良好的 XML 文件,其结构与 JSF 2 复合组件相同。我们按照 CDK 约定将文件命名为 `spinner.template.xml`,并放在 `src/main/resources/templates` 文件夹中,示例代码如下:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<cdk:root xmlns="http://jboss.org/schema/richfaces/cdk/xhtml-el"
xmlns:cdk="http://jboss.org/schema/richfaces/cdk/core"
xmlns:cc="http://jboss.org/schema/richfaces/cdk/jsf/composite"
xmlns:c="http://jboss.org/schema/richfaces/cdk/jstl/core"
xmlns:xi="http://www.w3.org/2001/XInclude">
<cc:interface>
<cdk:class>org.richfaces.book.renderkit.SpinnerRenderer</cdk:class>
<cdk:superclass>org.richfaces.book.renderkit.SpinnerBaseRenderer</cdk:superclas
```
0
0
复制全文
相关推荐







