2003年度 データベース論

カスタム・コンポーネント
JSFによるWebアプリケーション開発
第11回
1
ここでの内容

カスタム・コンポーネントの作成方法につい
て学ぶ。
2
カスタム・コンポーネントの
作成技法
3
カスタム・コンポーネントとは?


JSF では、UIコンポーネントを自分で作る
ことができる。
こうした、自作したコンポーネントのことを
「カスタム・コンポーネント」と言う。
4
カスタム・コンポーネントの例 (1)
<%@ taglib uri="/WEB-INF/blink.tld"
prefix="my" %>
.........
<f:view>
<my:blink>Hello !</my:blink>
</f:view>
5
カスタム・コンポーネントの例 (2)

内容で指定した文字列が点滅する。

HTML の blink タグが使われる
6
カスタム・コンポーネントの
作成に必要なファイル

Javaのプログラム




UIコンポーネントクラス
タグハンドラクラス
レンダラ
設定ファイル


タグライブラリディスクリプタ (TLD)
faces-config.xml
7
注意点

Javaプログラムは、必ずパッケージ宣言を
すること。パッケージを付けないとうまく動
かない。
8
UIコンポーネントクラス (1)


UIコンポーネントの表すクラス
すべてのUIコンポーネントは、
UIComponentBase クラスを継承する。
9
UIコンポーネントクラス (2)
package blink;
import javax.faces.component.UIComponentBase;
public class UIBlink extends UIComponentBase {
public String getFamily() {
return "MyFamily";
}
}
10
UIコンポーネントクラス (3)
public String getFamily() {
return "MyFamily";
}


「コンポーネント・ファミリ」を設定
UIコンポーネントとレンダラを関連づけるた
めに使われる。
11
タグハンドラクラス (1)


JSPからUIコンポーネントを利用するため
のクラス
次のいずれかのクラスを継承する



UIComponentTag (タグのボディ(=内容)を操
作しない場合)
UIComponentBodyTag (タグのボディを操作
する場合)
UIComponentTag で十分な場合が多い
12
タグハンドラクラス (2)
package blink;
import javax.faces.webapp.UIComponentTag;
public class BlinkTag extends UIComponentTag {
public String getComponentType() {
return "Blink";
}
public String getRendererType() {
return "BlinkRenderer";
}
}
13
タグハンドラクラス (3)
public String getComponentType() {
return "Blink";
}


コンポーネントの名前を返す。
faces-config.xml で指定する。
14
タグハンドラクラス (4)
public String getRendererType() {
return "BlinkRenderer";
}


レンダラの名前を返す。
faces-config.xml で指定する。
15
レンダラの2つの機能

エンコード


HTMLのフォームから入力されたデータを、UI
コンポーネントに設定する。
デコード

UIコンポーネントから、HTMLを出力する。
16
レンダラクラス (1)


Renderer クラスを継承する。
エンコードには、encodeBegin メソッドと
encodeEnd メソッドを使う。
17
レンダラクラス (2)
public class BlinkRenderer extends Renderer {
}
public void encodeBegin(……) {
………
}
public void encodeEnd(……) {
………
}
18
レンダラクラス (3)
// HTML の開始タグを出力する
public void encodeBegin(FacesContext context,
UIComponent component) throws IOException {
.........
ResponseWriter writer =
context.getResponseWriter();
writer.write("<blink>");
}
19
レンダラクラス (4)
// HTML の終了タグを出力する
public void encodeEnd(FacesContext context,
UIComponent component) throws IOException {
.........
ResponseWriter writer =
context.getResponseWriter();
writer.write("</blink>");
}
20
TLDの設定 (1)


タグライブラリディスクリプタ = TLD
JSPでどんなタグを利用できるか定義する
ための設定ファイル
21
TLDの設定 (2)
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>Blink !</short-name>
<tag>
<name>blink</name>
<tag-class>blink.BlinkTag</tag-class>
<body-content>scriptless</body-content>
</tag>
</taglib>
22
TLDの設定 (3)
<tag>
<name>blink</name>
<tag-class>blink.BlinkTag</tag-class>
<body-content>scriptless</body-content>
</tag>



name 要素はタグの名前
tag-class 要素はタグハンドラクラスの名前
body-content 要素の “scriptless” は、要素の内容に
テキストや Value Binding 式などが入ることを示す。 23
faces-config.xml の設定 (1)

UIコンポーネントとレンダラを設定する。
24
faces-config.xml の設定 (2)
<component>
<component-type>Blink</component-type>
<component-class>blink.UIBlink</component-class>
</component>


component-type 要素は、タグハンドラクラスの
componentTypeプロパティ
component-class 要素は、UIコンポーネントクラスのク
ラス名
25
faces-config.xml の設定 (3)
<render-kit>
<renderer>
<component-family>MyFamily</component-family>
<renderer-type>BlinkRenderer</renderer-type>
<renderer-class>
blink.BlinkRenderer</renderer-class>
</renderer>
</render-kit>
26
faces-config.xml の設定 (4)
<component-family>MyFamily</component-family>
<renderer-type>BlinkRenderer</renderer-type>
<renderer-class>blink.BlinkRenderer</renderer-class>
 component-family 要素は、UIコンポーネントクラスの
family プロパティ
 renderer-type 要素は、タグハンドラクラスの
rendererType プロパティ
 renderer-class 要素は、レンダラクラス名
27
JSPの記述
<%@ taglib uri="/WEB-INF/blink.tld" prefix="my" %>
………
<f:view>
<my:blink>Hello !</my:blink>
</f:view>
28
ディレクティブの記述
<%@ taglib uri="/WEB-INF/blink.tld" prefix="my" %>

TLD を WEB-INF フォルダに置いておく。
29
空要素タグ
30
サンプルプログラム (1)
<%@ taglib uri="/WEB-INF/now.tld"
prefix="my" %>
<my:now />
31
サンプルプログラム (2)

現在の日時を表示する
32
UIコンポーネントクラス
package now;
import javax.faces.component.UIComponentBase;
public class UINow extends UIComponentBase {
public String getFamily() {
return "MyFamily";
}
}
33
タグハンドラクラス
package now;
import javax.faces.webapp.UIComponentTag;
public class NowTag extends UIComponentTag {
public String getComponentType() {
return “Now";
}
public String getRendererType() {
return “NowRenderer";
}
}
34
レンダラクラス (1)
public class NowRenderer extends Renderer {
public void encodeBegin(……) {
………
}
}

タグがないので、encodeBegin メソッドだけでよい
35
レンダラクラス (2)
// 現在の日時を表示
public void encodeBegin(FacesContext context,
UIComponent component) throws IOException {
.........
Date d = new Date();
DateFormat df =
DateFormat.getDateTimeInstance();
ResponseWriter writer =
context.getResponseWriter();
writer.write(df.format(d));
}
36
TLDの設定
<tag>
<name>now</name>
<tag-class>now.NowTag</tag-class>
<body-content>empty</body-content>
</tag>

body-content 要素の “empty” は、このUIコンポーネ
ントが空要素タグで表現されることを示す。
37
faces-config.xml の設定 (1)
<component>
<component-type>Now</component-type>
<component-class>now.UINow</component-class>
</component>


component-type 要素は、タグハンドラクラスの
componentTypeプロパティ
component-class 要素は、UIコンポーネントクラスのク
ラス名
38
faces-config.xml の設定 (2)
<render-kit>
<renderer>
<component-family>MyFamily</component-family>
<renderer-type>NowRenderer</renderer-type>
<renderer-class>
now.NowRenderer</renderer-class>
</renderer>
</render-kit>
39
JSPの記述
<%@ taglib uri="/WEB-INF/now.tld"
prefix="my" %>
<my:now />
40
属性の記述
41
サンプルプログラム (1)
<%@ taglib uri="/WEB-INF/now.tld"
prefix="my" %>
......
<my:now format="FULL" /><br />
<my:now format="LONG" /><br />
<my:now format="MEDIUM" /><br />
<my:now format="SHORT" /><br />
42
サンプルプログラム (2)

属性で指定したスタイルに従って、現在の
日時を表示する。
43
UIコンポーネントクラス
package now;
import javax.faces.component.UIComponentBase;
public class UINow extends UIComponentBase {
public String getFamily() {
return "MyFamily";
}
}
44
タグハンドラクラス (1)
package now;
import javax.faces.webapp.UIComponentTag;
public class NowTag extends UIComponentTag {
public String getComponentType() {
return “Now";
}
public String getRendererType() {
return “NowRenderer";
}
}
45
タグハンドラクラス (2)
protected void setProperties(
UIComponent component) {
super.setProperties(component);
UINow now = (UINow)component;
now.getAttributes().put("format", format);
}
 コンポーネントに属性を設定する。
46
タグハンドラクラス (3)
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
 属性値をプロパティとして扱う
47
レンダラクラス (1)

属性値を取り出し、その値によって必要な
処理を行う。
48
レンダラクラス (2)
UINow now = (UINow)component;
String format =
(String)now.getAttributes().get("format");
if (format.equals("FULL")) {
df = DateFormat.getDateTimeInstance(
DateFormat.FULL, DateFormat.FULL);
} else if (format.equals("LONG")) {
df = DateFormat.getDateTimeInstance(
DateFormat.LONG, DateFormat.LONG);
49
TLDの設定 (1)
<tag>
<name>now</name>
<tag-class>now.NowTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>format</name>
<required>true</required>
</attribute>
</tag>
50
TLDの設定 (2)
<attribute>
<name>format</name>
<required>true</required>
</attribute>


name 要素で属性名を指定する
required 要素でこの属性が必須かどうかを示す。
51
faces-config.xml の設定 (1)
<component>
<component-type>Now</component-type>
<component-class>now.UINow</component-class>
</component>


component-type 要素は、タグハンドラクラスの
componentTypeプロパティ
component-class 要素は、UIコンポーネントクラスのク
ラス名
52
faces-config.xml の設定 (2)
<render-kit>
<renderer>
<component-family>MyFamily</component-family>
<renderer-type>NowRenderer</renderer-type>
<renderer-class>
now.NowRenderer</renderer-class>
</renderer>
</render-kit>
53
JSPの記述
<%@ taglib uri="/WEB-INF/now.tld"
prefix="my" %>
......
<my:now format="FULL" /><br />
<my:now format="LONG" /><br />
<my:now format="MEDIUM" /><br />
<my:now format="SHORT" /><br />
54