Chapter 29. Seam的JSF控件

Seam包括许多有利于使用Seam的JSF控件。它们用来补充内建的JSF控件,以及来自其他第三方库的控件。 我们推荐以JBoss Ajax4jsf、JBoss Richfaces和Apache MyFaces Trinidad标签库来使用Seam。我们不建议使用Tomahawk标签库来使用Seam。

29.1. 标签

为了使用这些tagsd,要在你的页面中定义“s”命名空间如下(只用于Facelets):

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:s="http://jboss.com/products/seam/taglib">

ui的例子,示范了这其中许多标签的用法。

Table 29.1. Seam的JSF控件参考

<s:button>

描述

通过控制对话传播支持动作调用的按钮。不提交表单。

属性

  • value — 标签

  • action — 指定动作监听者的一种方法绑定。

  • view — 链接的JSF view id。

  • fragment — 链接的fragment标识符。

  • disabled — 该链接处于取消状态吗?

  • propagation — 确定对话传播风格:beginjoinnestnone 或者 end

  • pageflow — 起始的页面流定义。 (这只在 propagation="begin" 或者 propagation="join" 的时候才有用。)

用法

<s:button id="cancel" value="Cancel"
          action="#{hotelBooking.cancel}"/>

<s:cache>

描述

利用JBoss的Cache缓存渲染过的页面片断。 注意 <s:cache> 实际上使用由内建的 pojoCache 组件管理的JBoss Cache的实例。

属性

  • key — 是缓存渲染过的内容的键,经常是一个值表达式。 例如,如果我们在缓存一个显示文档的页面片断,我们可以使用 key="Document-#{document.id}"

  • enabled — 是一个值表达式,决定是否应该使用缓存。

  • region — 是一个要使用的JBoss Cache节点(不同的节点可以有不同的过期策略)。

Usage 用法

<s:cache key="entry-#{blogEntry.id}" region="pageFragments">
  <div class="blogEntry">
    <h3>#{blogEntry.title}</h3>
    <div>
      <s:formattedText value="#{blogEntry.body}"/>
    </div>
    <p>
      [Posted on&#160;
      <h:outputText value="#{blogEntry.date}">
        <f:convertDateTime timezone="#{blog.timeZone}" locale="#{blog.locale}"
                           type="both"/>
      </h:outputText>]
    </p>
  </div>
</s:cache>

<s:conversationId>

描述

将对话id添加到一个输出链接(或者类似的JSF控件)。只用于Facelets。

属性

无。

<s:conversationPropagation>

描述

给一个命令链接或者按钮定制对话传播(或者类似的JSF控件)。只用于Facelets。

属性

  • propagation — 确定对话传播风格;beginjoinnestnone 或者 end

  • pageflow — 是一个起始页面流定义。 (这只在 propagation="begin" 或者 propagation="join" 的时候才有用。)

用法

<h:commandButton value="Apply" action="#{personHome.update}">
  <s:conversationPropagation type="join" />
</h:commandButton>

<s:convertDateTime>

描述

在Seam的timezone中执行日期或者时间对话。

属性

无。

用法

<h:outputText value="#{item.orderDate}">
  <s:convertDateTime type="both" dateStyle="full"/>
</h:outputText>

<s:convertEntity>

描述

给当前的组件分配一个实体转换器。这主要对单选按钮和下拉控件有用。

转换器使用任何具有 @Id 注解(简单的或者复合的)的受控实体。

属性

无。

配置

你必须通过 <s:convertEntity /> 使用 Seam管理的事务 (请见Section 8.2, “Seam管理的事务”

如果你的 受控持久化上下文 不是称作 entityManager,那你就需要在 components.xml 中设置它:

<component name="org.jboss.seam.ui.EntityConverter">
  <property name="entityManager">#{em}</property>
</component>

如果你想在实体转换器上使用不止一个实体管理器,你可以在componets.xml中为每一个实体管理器创建一份实体转换器。

<component name="myEntityConverter" class="org.jboss.seam.ui.converter.EntityConverter">
  <property name="entityManager">#{em}</property>
</component>
<h:selectOneMenu value="#{person.continent}">
  <s:selectItems value="#{continents.resultList}" var="continent"
                 label="#{continent.name}" />
    <f:converter converterId="myEntityConverter" />
</h:selectOneMenu>

用法

<h:selectOneMenu value="#{person.continent}" required="true">
  <s:selectItems value="#{continents.resultList}" var="continent"
                 label="#{continent.name}"
                 noSelectionLabel="Please Select..."/>
    <s:convertEntity />
</h:selectOneMenu>

<s:convertEnum>

描述

给当前的组件分配一个enum转换器。这主要对单选按钮和下拉控件有用。

属性

无。

用法

<h:selectOneMenu value="#{person.honorific}">
  <s:selectItems value="#{honorifics}" var="honorific"
                 label="#{honorific.label}"
                 noSelectionLabel="Please select" />
  <s:convertEnum />
</h:selectOneMenu>

<s:decorate>

描述

在验证失败或者设置了 required="true" 时,“装饰”一个JSF输入域。

属性

  • template — 用来装饰组件的Facelets模板。

#{invalid}#{required} 可以在 s:decorate 内使用; 如果你按要求设置了正被装饰的输入组件,#{required} 就取值为 true, 并且如果发生校验错误, #{invalid} 取值为 true

用法

<s:decorate template="edit.xhtml">
  <ui:define name="label">Country:</ui:define>
    <h:inputText value="#{location.country}" required="true"/>
  </s:decorate>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:s="http://jboss.com/products/seam/taglib">

  <div>

    <s:label styleClass="#{invalid?'error':''}">
      <ui:insert name="label"/>
      <s:span styleClass="required" rendered="#{required}">*</s:span>
    </s:label>

    <span class="#{invalid?'error':''}">
      <s:validateAll>
        <ui:insert/>
      </s:validateAll>
    </span>

    <s:message styleClass="error"/>

  </div>

</ui:composition>

<s:div>

描述

渲染一个HTML<div>

属性

无。

用法

<s:div rendered="#{selectedMember == null}">
  Sorry, but this member does not exist.
</s:div>

<s:enumItem>

描述

从一个enum值中创建一个 SelectItem

属性

  • enumValue — 是enum值的字符串表示法。

  • label — 在渲染 SelectItem 时要使用的标签。

用法

<h:selectOneRadio id="radioList"
                  layout="lineDirection"
                  value="#{newPayment.paymentFrequency}">
  <s:convertEnum />
  <s:enumItem enumValue="ONCE" label="Only Once" />
  <s:enumItem enumValue="EVERY_MINUTE" label="Every Minute" />
  <s:enumItem enumValue="HOURLY"       label="Every Hour" />
  <s:enumItem enumValue="DAILY"        label="Every Day" />
  <s:enumItem enumValue="WEEKLY"       label="Every Week" />
</h:selectOneRadio>

<s:fileUpload>

描述

渲染一个文件上载控件。这个控件必须通过在form中使用 multipart/form-data 的编码类型,例如:

<h:form enctype="multipart/form-data">

对于多部分请求,也必须在 web.xml 中配置Seam Multipart Servlet过滤器:

<filter>
  <filter-name>Seam Filter</filter-name>
  <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>Seam Filter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

配置

下列多部分请求的配置选项可以在 components.xml 中进行配置:

  • createTempFiles — 如果这个选择设置为true,上载好的文件就流向一个临时文件,而不是流向内存。

  • maxRequestSize — 允许上载文件的最大字节数。

下面是一个例子:

<component class="org.jboss.seam.web.MultipartFilter">
  <property name="createTempFiles">true</property>
  <property name="maxRequestSize">1000000</property>
</component>

属性

  • data — 这个值绑定接收二进制文件数据。 接收域应该声明为一个 byte[] 或者 InputStream (必要)。

  • contentType — 这个值绑定接收文件的内容类型(可选)。

  • fileName — 这个值绑定接收的文件名(可选)。

  • fileSize — 这个值绑定接收的文件大小(可选)。

  • accept — 可以接受的一个以逗号分隔的内容类型列表,可能浏览器不支持。 例如 "images/png,images/jpg""images/"

  • style — 控件的样式,即CSS之类的

  • styleClass — 控件的样式类

用法

<s:fileUpload id="picture" data="#{register.picture}"
              accept="image/png"
              contentType="#{register.pictureContentType}" />

<s:formattedText>

描述

输出 Seam Text,一种富文本标记,对于博客、Wiki和其他可能使用富文本的应用程序很有用。完整的用法请见Seam Text章节。

属性

  • value — 一个指定要渲染的富文本标记的EL表达式。

用法

<s:formattedText value="#{blog.text}"/>

实例

<s:validateFormattedText>

描述

检查提交的值是否合乎Seam Text

属性

无。

<s:fragment>

描述

一个非渲染的组件,用于启用/取消它子组件的渲染。

属性

无。

用法

<s:fragment rendered="#{auction.highBidder ne null}">
  Current bid:
</s:fragment>

<s:graphicImage>

描述

一个允许在Seam Component中创建图片的扩展了的 <h:graphicImage>;可以对图片进行进一步转换。

支持 <h:graphicImage> 的所有属性,以及:

属性

  • value — 要显示的图片。可以是一个路径 String(从classpath加载)、 byte[]java.io.Filejava.io.InputStream 或者 java.net.URL。 目前支持的图片格式有 image/pngimage/jpegimage/gif

  • fileName — 如果没有指定,图片将有一个通用的文件名。 如果你想要自己给文件命名,就应该在这里指定。这个名称应该是唯一的。

转换

为了给图片应用一种转换,你要嵌套一个指定要应用的转换的标签。Seam目前支持下面这些转换:

<s:transformImageSize> s:transformImageSize
  • width — 图片的新宽度

  • height — 图片的新高度

  • maintainRatio — 如果为 true,并且指定了其中 一个 width/height,图片将利用不确定的、正被计算用来维持纵横比的尺寸调整大小。

  • factor — 通过指定的比例缩放图片

<s:transformImageBlur>
  • radius — 利用指定的半径执行一个渐变模糊

<s:transformImageType>
  • contentType — 将图片的类型变成 image/jpeg 或者 image/png

创建你自己的转换很容易——创建一个 实现org.jboss.seam.ui.graphicImage.ImageTransformUIComponent。 在 applyTransform() 方法内部使用 image.getBufferedImage() 来获得原始图片,用 image.setBufferedImage() 来设置你转换后的图片。转换以视图中指定的顺序进行。

用法

<s:graphicImage rendered="#{auction.image ne null}"
                value="#{auction.image.data}">
  <s:transformImageSize width="200" maintainRatio="true"/>
</s:graphicImage>

<s:link>

描述

通过控制对话传播支持动作调用的链接。不提交表单。

属性

  • value — 标签。

  • action — 指定动作监听者的一种方法绑定。

  • view — 链接的JSF view id。

  • fragment — 链接的fragment标识符。

  • disabled — 该链接处于取消状态吗?

  • propagation — 确定对话传播风格:beginjoinnestnone 或者 end

  • pageflow — 起始的页面流定义。 (这只在 propagation="begin" 或者 propagation="join"的时候才有用。)

用法

<s:link id="register" view="/register.xhtml"
        value="Register New User"/>

<s:message>

描述

”装饰“一个包含验证出错消息的JSF输入域。

属性

无。

用法

<f:facet name="afterInvalidField">
  <s:span>
    &#160;Error:&#160;
    <s:message/>
  </s:span>
</f:facet>

<s:label>

描述

装饰一个包含标签的JSF输入域。这个标签放在HTML <label> 标签内部,且与最近的JSF输入组件相关联。 它经常与 <s:decorate> 共用。

Attributes 属性

  • style — 控件的样式

  • styleClass — 控件的样式类

用法

<s:label styleClass="label">
  Country:
</s:label>
<h:inputText value="#{location.country}" required="true"/>

<s:remote>

描述

用Seam Remoting生成所需要的JavaScript存根(stub)。

属性       

  • include — 一个要为其生成Seam Remoting JavaScript 存根的以逗号分隔的组件名列表(或者合法的全类名)。 更多详情请见 Chapter 21, Remoting

用法

<s:remote include="customerAction,accountAction,com.acme.MyBean"/>

<s:selectDate>

描述

已被废弃。 用 <rich:calendar /> 代替。

显示一个动态的日期选择器组件,它给指定的输入域选择日期。 selectDate 元素的主体应该包含HTML元素,例如文本或者图片,提示用户点击以显示日期选择器。 日期选择器 必须 利用CSS定义样式。 可以在Seam booking demo中找到CSS范例文件 date.css ,或者可以利用seam-gen生成。 用来控制日期选择器外观的CSS样式也在下面做了说明。

属性

  • for — 日期选择器要把选择的日期插入到其中的输入域的id。

  • dateFormat — 日期格式的字符串。这应该与输入域的日期格式匹配。

  • startYear — 弹出年选择器范围将从这一年开始。

  • endYear — 弹出年选择器范围将从这一年终止。

  • firstDayOfWeek — 控制哪一天是一周的第一天(0 = Sunday, 6 = Saturday)。 如果没有设置这个属性,那么一周的第一天默认将基于用户所在的区域。

用法

<div class="row">
  <h:outputLabel for="dob">Date of birth<em>*</em></h:outputLabel>
  <h:inputText id="dob" value="#{user.dob}" required="true">
    <s:convertDateTime pattern="MM/dd/yyyy"/>
  </h:inputText>
  <s:selectDate for="dob" startYear="1910" endYear="2007">
    <img src="img/datepicker.png"/>
  </s:selectDate>
  <div class="validationError"><h:message for="dob"/></div>
</div>

范例

CSS样式

以下列表描述了用来控制selectDate控件样式的CSS类名。

  • seam-date — 这个类用于包含弹出日历的外层 div。 (1) 它还用于控制日历内部布局的 table。 (2)

  • seam-date-header — 这个类用于日历头表行(tr)和头表单元(td)。 (3)

  • seam-date-header-prevMonth — 用于”前一个月“表单元(td),点击它时,导致日历显示当前显示的前一个月。 (4)

  • seam-date-header-nextMonth — 这个类用于”下一个月“表单元(td),点击它时,导致日历显示当前显示的下一个月。 (5)

  • seam-date-headerDays — 这个类用于历日header行(tr),它包含了周日期的名称。 (6)

  • seam-date-footer — 这个类用于日历的footer行(tr),它显示当前日期。 (7)

  • seam-date-inMonth — 这个类用于包含了当前显示月份中的一个日期的表单元(td)元素。 (8)

  • seam-date-outMonth — 这个类用于包含了当前显示月份之外的一个日期的表单元(td)元素。 (9)

  • seam-date-selected — 这个类用于包含当前选择日期的表单元td元素。 (10)

  • seam-date-dayOff-inMonth — 这个类用于包含当前选择月份之内的”休假“日(例如周末,周六和周日)的表单元元素。 (11)

  • seam-date-dayOff-outMonth — 这个类用于包含当前选择的月份之外的休假日(例如周末,周六和周日)的表单元元素。 (12)

  • seam-date-hover — 这个类用于鼠标经过的表单元(td)元素。 (13)

  • seam-date-monthNames — 这个类用于包含弹出月份选择器的 div 控件。 (14)

  • seam-date-monthNameLink — 这个类用于包含弹出月份名称的anchor(a控件。 (15)

  • seam-date-years — 这个类用于包含弹出年选择器的div控件。 (16)

  • seam-date-yearLink — 这个类用于包含弹出年份的anchor(a)控件。 (17)

<s:selectItems>

描述

从一个List、Set、DataModel或者Array中创建一个 List<SelectItem>

属性

  • value — 一个EL表达式,指定支持 List<SelectItem> 的数据;

  • var — 定义迭代期间保存当前对象的本地变量的名称。

  • label — 渲染 SelectItem 时要使用的标签。可以参考 var 变量。

  • disabled — 如果为true,SelectItem 将被取消渲染。可以参考 var 变量。

  • noSelectionLabel — 指定(可选)标签放在列表的顶部(如果也指定 required="true",那么选择这个值将导致验证出错)。

  • hideNoSelectionLabel — 如果为true,选择一个值时,noSelectionLabel 将被隐藏。

用法

<h:selectOneMenu value="#{person.age}"
                 converter="#{converters.ageConverter}">
  <s:selectItems value="#{ages}" var="age" label="#{age}" />
</h:selectOneMenu>

<s:span>

描述

渲染一个HTML的<span>

属性

无。

用法

<s:span styleClass="required" rendered="#{required}">*</s:span>

<s:taskId>

描述

当任何可以通过 #{task} 使用的时候,将任何id添加到一个输出链接(或者类似的JSF控件)。只用于Facelets。

属性

无。

<s:validate>

描述

一个非可视化的控件,利用 Hibernate Validator 对绑定属性验证一个JSF输入域。

属性

无。

用法

<h:inputText id="userName" required="true"
             value="#{customer.userName}">
  <s:validate />
</h:inputText>
<h:message for="userName" styleClass="error" />

<s:validateAll> s:validateAll

描述

一个非可视化的控件,利用 Hibernate Validator 对它们绑定的属性验证所有的子JSF输入域。

属性

无。

用法

<s:validateAll>
  <div class="entry">
    <h:outputLabel for="username">Username:</h:outputLabel>
    <h:inputText id="username" value="#{user.username}"
                 required="true"/>
    <h:message for="username" styleClass="error" />
  </div>
  <div class="entry">
    <h:outputLabel for="password">Password:</h:outputLabel>
    <h:inputSecret id="password" value="#{user.password}"
                   required="true"/>
    <h:message for="password" styleClass="error" />
  </div>
  <div class="entry">
    <h:outputLabel for="verify">Verify Password:</h:outputLabel>
    <h:inputSecret id="verify" value="#{register.verify}"
                   required="true"/>
    <h:message for="verify" styleClass="error" />
  </div>
</s:validateAll>

29.2. 注解

为了允许你用Seam组件作为JSF转换器和验证器,Seam也提供注解:

@Converter
@Name("fooConverter")
@BypassInterceptors
@Converter
public class FooConverter implements Converter {

  @In EntityManager entityManager;

  @Transactional
  public Object getAsObject(FacesContext context, UIComponent cmp, String value) {
    EntityManager entityManager = (EntityManager) Component.getInstance("entityManager");
    entityManager.joinTransaction();
    // Do the conversion
  }

  public String getAsString(FacesContext context, UIComponent cmp, Object value) {
    // Do the conversion
  }

}

将Seam组件注册为一个JSF转换器。这里展示的是,在将值转换回它的对象表示法的时候,能够访问JTA事务中的JPA EntityManager的转换器。

@Validator
@Name("barValidator")
@BypassInterceptors
@Validator
public class BarValidator implements Validator {

  @In FooController fooController;

  public void validate(FacesContext context, UIComponent cmp, Object value)
    throws ValidatorException {
    FooController fooController = (FooController) Component.getInstance("fooController");
    return fooController.validate(value);
  }

}

将Seam组件注册为一个JSF验证器。这里展示的是,一个注入另一个Seam组件的验证器;注入的组件用来验证值。