?? 組件卷標(biāo).htm
字號(hào):
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>新建網(wǎng)頁(yè) 1</title>
</head>
<body>
<p>組件卷標(biāo)</p>
<div id="PageContent">
<table cellSpacing="0" cellPadding="0" width="100%" border="0" id="table3">
<tr>
<td class="pagebody" vAlign="top">
<table style="CLEAR: both" cellSpacing="0" cellPadding="0" width="100%" border="0" id="table4">
<tr>
<td class="pagecontent" vAlign="top" width="100%">
<div class="wiki-content">
完成Component的自訂,接下來(lái)要設(shè)定一個(gè)自訂Tag與之對(duì)應(yīng),自訂Tag的目的,在于設(shè)定
Component屬性,取得Componenty型態(tài),取得Renderer型態(tài)值等;屬性的設(shè)定包括了設(shè)定靜態(tài)值、設(shè)定綁定值、設(shè)定驗(yàn)證器等等。<p>
要自訂與Component對(duì)應(yīng)的Tag,您可以繼承UIComponentTag,例如:</p>
<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<div class="codeHeader" style="BORDER-BOTTOM-STYLE: solid">
<b>TextWithCmdTag.java</b></div>
<div class="codeContent">
<pre class="code-java"><span class="code-keyword">package</span> onlyfun.caterpillar;
<span class="code-keyword">import</span> javax.faces.application.Application;
<span class="code-keyword">import</span> javax.faces.component.UIComponent;
<span class="code-keyword">import</span> javax.faces.context.FacesContext;
<span class="code-keyword">import</span> javax.faces.el.ValueBinding;
<span class="code-keyword">import</span> javax.faces.webapp.UIComponentTag;
<span class="code-keyword">public</span> class TextWithCmdTag <span class="code-keyword">extends</span> UIComponentTag {
<span class="code-keyword">private</span> <span class="code-object">String</span> size;
<span class="code-keyword">private</span> <span class="code-object">String</span> value;
<span class="code-keyword">public</span> <span class="code-object">String</span> getComponentType() {
<span class="code-keyword">return</span> <span class="code-quote">"onlyfun.caterpillar.TextWithCmd"</span>;
}
<span class="code-keyword">public</span> <span class="code-object">String</span> getRendererType() {
<span class="code-keyword">return</span> <span class="code-keyword">null</span>;
}
<span class="code-keyword">public</span> void setProperties(UIComponent component) {
<span class="code-keyword">super</span>.setProperties(component);
setStringProperty(component, <span class="code-quote">"size"</span>, size);
setStringProperty(component, <span class="code-quote">"value"</span>, value);
}
<span class="code-keyword">private</span> void setStringProperty(UIComponent component,
<span class="code-object">String</span> attrName, <span class="code-object">String</span> attrValue) {
<span class="code-keyword">if</span>(attrValue == <span class="code-keyword">null</span>)
<span class="code-keyword">return</span>;
<span class="code-keyword">if</span>(isValueReference(attrValue)) {
FacesContext context =
FacesContext.getCurrentInstance();
Application application =
context.getApplication();
ValueBinding binding =
application.createValueBinding(attrValue);
component.setValueBinding(attrName, binding);
}
<span class="code-keyword">else</span> {
component.getAttributes().
put(attrName, attrValue);
}
}
<span class="code-keyword">public</span> void release() {
<span class="code-keyword">super</span>.release();
size = <span class="code-keyword">null</span>;
value = <span class="code-keyword">null</span>;
}
<span class="code-keyword">public</span> <span class="code-object">String</span> getSize() {
<span class="code-keyword">return</span> size;
}
<span class="code-keyword">public</span> void setSize(<span class="code-object">String</span> size) {
<span class="code-keyword">this</span>.size = size;
}
<span class="code-keyword">public</span> <span class="code-object">String</span> getValue() {
<span class="code-keyword">return</span> value;
}
<span class="code-keyword">public</span> void setValue(<span class="code-object">String</span> value) {
<span class="code-keyword">this</span>.value = value;
}
}</pre>
</div>
</div>
<p> 首先看到這兩個(gè)方法:</p>
<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<div class="codeContent">
<pre class="code-java"><span class="code-keyword">public</span> <span class="code-object">String</span> getComponentType() {
<span class="code-keyword">return</span> <span class="code-quote">"onlyfun.caterpillar.TextWithCmd"</span>;
}
<span class="code-keyword">public</span> <span class="code-object">String</span> getRendererType() {
<span class="code-keyword">return</span> <span class="code-keyword">null</span>;
}</pre>
</div>
</div>
<p>
由于我們的Component目前不使用Renderer,所以getRendererType()傳回null值,而
getComponentType()在于讓JSF取得這個(gè)Tag所對(duì)應(yīng)的Component,所傳回的值在faces-config.xml中要有定義,例如:</p>
<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<div class="codeContent">
<pre class="code-java">....
<component>
<component-type>
onlyfun.caterpillar.TextWithCmd
</component-type>
<component-class>
onlyfun.caterpillar.UITextWithCmd
</component-class>
</component>
....</pre>
</div>
</div>
<p> 藉由faces-config.xml中的定義,JSF可以得知
onlyfun.caterpillar.TextWithCmd的真正類別,而這樣的定義方式很顯然的,您可以隨時(shí)換掉<component-
class>所對(duì)應(yīng)的類別,也就是說(shuō),Tag所對(duì)應(yīng)的Component是可以隨時(shí)替換的。</p>
<p>
在設(shè)定Component屬性值時(shí),可以由component.getAttributes()取得Map對(duì)象,并將卷標(biāo)屬性值存入Map
中,這個(gè)Map對(duì)象可以在對(duì)應(yīng)的Component中使用getAttributes()取得,例如在上一個(gè)主題中的UITextWithCmd中可以如下取得存入Map的size屬性:</p>
<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<div class="codeHeader" style="BORDER-BOTTOM-STYLE: solid">
<b>UITextWithCmd.java</b></div>
<div class="codeContent">
<pre class="code-java"><span class="code-keyword">package</span> onlyfun.caterpillar;
<span class="code-keyword">import</span> java.io.IOException;
<span class="code-keyword">import</span> java.util.Map;
<span class="code-keyword">import</span> javax.faces.component.UIInput;
<span class="code-keyword">import</span> javax.faces.context.FacesContext;
<span class="code-keyword">import</span> javax.faces.context.ResponseWriter;
<span class="code-keyword">public</span> class UITextWithCmd <span class="code-keyword">extends</span> UIInput {
....
<span class="code-keyword">private</span> void encodeTextField(ResponseWriter writer,
<span class="code-object">String</span> clientId) <span class="code-keyword">throws</span> IOException {
....
<span class="code-object">String</span> size = (<span class="code-object">String</span>) getAttributes().get(<span class="code-quote">"size"</span>);
<span class="code-keyword">if</span>(size != <span class="code-keyword">null</span>) {
writer.writeAttribute(<span class="code-quote">"size"</span>, size, <span class="code-keyword">null</span>);
}
.....
}
....
}</pre>
</div>
</div>
<p> 可以使用isValueReference()來(lái)測(cè)試是否為JSF Expression
Language的綁定語(yǔ)法,如果是的話,則我們必須建立ValueBinding對(duì)象,并設(shè)定值綁定:</p>
<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<div class="codeContent">
<pre class="code-java">....
<span class="code-keyword">private</span> void setStringProperty(UIComponent component,
<span class="code-object">String</span> attrName, <span class="code-object">String</span> attrValue) {
<span class="code-keyword">if</span>(attrValue == <span class="code-keyword">null</span>)
<span class="code-keyword">return</span>;
<span class="code-keyword">if</span>(isValueReference(attrValue)) {
FacesContext context =
FacesContext.getCurrentInstance();
Application application =
context.getApplication();
ValueBinding binding =
application.createValueBinding(attrValue);
component.setValueBinding(attrName, binding);
}
<span class="code-keyword">else</span> {
component.getAttributes().
put(attrName, attrValue);
}
}
....</pre>
</div>
</div>
<p> 如果是value屬性,記得在上一個(gè)主題中我們提過(guò),從UIOutput繼承下來(lái)的getValue()方法可以取得
Component的value設(shè)定值,這個(gè)值可能是靜態(tài)的屬性設(shè)定值,也可能是JSF
Expression的綁定值,預(yù)設(shè)會(huì)先從組件的屬性設(shè)定值開始找尋,如果找不到,再?gòu)慕壎ㄖ担╒alueBinding對(duì)象)中找尋。</p>
<p> 最后,我們必須提供自訂Tag的tld檔:</p>
<div class="code" style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<div class="codeHeader" style="BORDER-BOTTOM-STYLE: solid">
<b>textcmd.tld</b></div>
<div class="codeContent">
<pre class="code-java"><?xml version=<span class="code-quote">"1.0"</span> encoding=<span class="code-quote">"UTF-8"</span>?>
<taglib version=<span class="code-quote">"2.0"</span>
xmlns=<span class="code-quote">"http:<span class="code-comment">//java.sun.com/xml/ns/j2ee"</span>
</span> xmlns:xsi=<span class="code-quote">"http:<span class="code-comment">//www.w3.org/2001/XMLSchema-instance"</span>
</span> xsi:schemaLocation=
<span class="code-quote">"http:<span class="code-comment">//java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"</span>>
</span> <tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<<span class="code-object">short</span>-name>textcmd</<span class="code-object">short</span>-name>
<uri>http:<span class="code-comment">//caterpillar.onlyfun.net/textcmd</uri>
</span>
<tag>
<name>textcmd</name>
<tag-class>onlyfun.caterpillar.TextWithCmdTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>size</name>
</attribute>
<attribute>
<name>value</name>
<required><span class="code-keyword">true</span></required>
</attribute>
</tag>
</taglib></pre>
</div>
</div>
</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</body>
</html>
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -