5月 11th, 2008at 0:51

Tags:

JSF1.1 カスタムコンポーネント

このエントリーをはてなブックマークに追加

JSFにはじめからあるInputタグbuttonタグなどはUIコンポーネントクラスから作られている。これらを改良してJSFのデフォルトに含まれないタグのコンポーネント化などができるようになる。

例えば、DBからのresultSetを整形してTableで表示するコンポーネントはあるんだけど、カラムの結合などまではできない。こういった処理を組み込んでオリジナルのコンポーネントを作ることで、JSPファイルへの記述を簡単にすることができそう。

じゃつくってみよう

今回はfieldsetタグをJSFのUIにしてしまう。

やること

  • UIコンポーネントクラス作成
  • タグクラス作成
  • レンダラー作成
  • TLDファイル作成
  • faces-config.xml作成
  • JSPに実装

UIコンポーネントクラス作成

UIコンポーネントはUIComponentBaseを継承して作成する。UIコンポーネント内にはタグに書かれた属性名と属性値などが保持される。ページに表示されるテキストボックスなどのコンポーネントをオブジェクトにしたもの・・・みたいな感じ。

package com.daipresents.kingdom.component;

import javax.faces.component.UIComponentBase;

public class UIFieldset extends UIComponentBase {

 /** UIコンポーネントFamilyName */ public static final String FAMILY_NAME = "com.daipresents.kingdom.component.UIFieldset"; /** コンポーネントタイプ */ public static final String COMPONENT_TYPE = "com.daipresents.kingdom.component.UIFieldset";

 /**  * FamilyNameを取得します。  */ public String getFamily() {  return FAMILY_NAME; }}
  • FamilyNameComponentTypeにはこのクラスのパッケージ名を利用することにした。デフォルトのUIFormでは「javax.faces.Form」になっていた。
  • ComponentTypeはUIが持ってもいいかなと思って実装した。これもパッケージ名を利用。
  • FamilyNameのGetterだけを実装。

タグクラス作成

UIコンポーネントとは別に、JSP用のタグクラスが必要になる。これはJSPに書かれたタグリブの内容をUIコンポーネントに設定する役割をしている。

package com.daipresents.kingdom.taglib;

import javax.faces.component.UIComponent;import javax.faces.webapp.UIComponentTag;

import com.daipresents.kingdom.component.UIFieldset;import com.daipresents.kingdom.renderkit.FieldsetRenderer;

public class FieldsetTag extends UIComponentTag {

 /** CSS指定用のstyle属性 */ private String style;

 /**  * CSSを取得します。  * @return CSSクラス名  */ public String getStyle() {  return style; }

 /**  * CSSを設定します。  * @param style  */ public void setStyle(String style) {  this.style = style; }

 /**  * コンポーネントタイプを取得します。  */ public String getComponentType() {  return UIFieldset.COMPONENT_TYPE; }

 /**  * RendererTypeを取得します。  */ public String getRendererType() {  return FieldsetRenderer.RENDERER_TYPE; }

 /**  * タグに設定された属性を設定します。  */    protected void setProperties(UIComponent component) {

        super.setProperties(component);        UIFieldset fieldset = (UIFieldset)component;        fieldset.getAttributes().put("style", this.style);    }

}
  • ComponentTypeRendererTypeはこのタグクラスに関連するUIコンポーネント、Rendererからとってきている。
  • 今回はstyle属性を使用できるfieldsetコンポーネントを作成した。
  • setProperties()メソッドによってJSPに書かれたタグの属性値を取得している。属性の数だけアクセッサが必要になる。

レンダラー作成 

Rendererはタグクラスが出力する内容を記述する。タグを書いた部分がResponseWriterによって置き換えられるわけ。

package com.daipresents.kingdom.renderkit;

import java.io.IOException;import java.util.List;

import javax.faces.component.UIComponent;import javax.faces.context.FacesContext;import javax.faces.context.ResponseWriter;import javax.faces.render.Renderer;

import com.daipresents.kingdom.component.UIFieldset;

public class FieldsetRenderer extends Renderer {

 /** RendererType */ public static final String RENDERER_TYPE = "com.daipresents.kingdom.renderkit.FieldsetRenderer";

 /**  * 開始タグを出力します。  */ public void encodeBegin(FacesContext context, UIComponent component)      throws IOException {

  ResponseWriter writer = context.getResponseWriter();  UIFieldset fieldset = (UIFieldset)component;          String style = (String)fieldset.getAttributes().get("style");

  writer.startElement("fieldset", component);        writer.writeAttribute("class", style, null);

 }

 /**  * 終了タグを出力します。  */ public void encodeEnd(FacesContext context, UIComponent component)   throws IOException {

  ResponseWriter writer = context.getResponseWriter();  writer.endElement("fieldset");

 }}
  • 開始タグ、終了タグを指定する。
  • 空要素OKの場合はencodeBegin()メソッドだけでもよいみたい。

TLDファイル作成

タグを利用できるようにTDLファイルに追記する。

<tag> <name>fieldset</name> <tag-class>com.daipresents.kingdom.taglib.FieldsetTag</tag-class> <body-content>JSP</body-content> <attribute>  <name>style</name>  <required>false</required> </attribute></tag>
  • body-content要素は「empty」だと空要素OK。「JSP」だとタグの内側にJSPが書けるようになる。
  • required要素によって属性が必須かどうかを指定できる。

faces-config.xml作成

UIコンポーネントの登録、UIコンポーネントに関連するRendererなどを指定する。

<component> <component-type>com.daipresents.kingdom.component.UIFieldset</component-type> <component-class>com.daipresents.kingdom.component.UIFieldset</component-class></component>

<render-kit> <renderer>  <component-family>com.daipresents.kingdom.component.UIFieldset</component-family>  <renderer-type>com.daipresents.kingdom.renderkit.FieldsetRenderer</renderer-type>  <renderer-class>com.daipresents.kingdom.renderkit.FieldsetRenderer</renderer-class> </renderer></render-kit>
  • component-type、component-family、renderer-typeには作成したクラスで指定している値を設定する。

JSPに実装

<f:view> <h:form>  <kd:fieldset style="loginfieid">    ・    ・    ・

画面は以下のようになる。

cc01.jpg

ソースは以下。

<fieldset class="loginfieid">
このエントリーをはてなブックマークに追加