5月 11th, 2008at 0:51
Tags: Java
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; }}
- FamilyName、ComponentTypeにはこのクラスのパッケージ名を利用することにした。デフォルトの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); }
}
- ComponentTypeとRendererTypeはこのタグクラスに関連する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"> ・ ・ ・
画面は以下のようになる。
ソースは以下。
<fieldset class="loginfieid">





