⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 自订 renderer.htm

📁 良葛格學習筆記,《jsf入门》简体中文版,对学习JSF有帮助
💻 HTM
字号:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>新建网页 1</title>
</head>

<body>

<p>自订 Renderer</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可以将译码、编码的动作交给Renderer,这让您的表现层技术可以轻易的抽换,我们可以将之前的自订组件的译码、编码动作移出至
						Renderer,不过由于我们之前设计的Component是个很简单的组件,事实上,如果只是要新增一个Command在输入字段旁边,我们并不需要大费周章的自订一个新的组件,我们可以直接为输入字段更换一个自订的Renderer。<p>
						要自订一个Renderer,您要继承javax.faces.render.Renderer,我们的自订Renderer如下:</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>TextCmdRenderer.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.EditableValueHolder;
 <span class="code-keyword">import</span> javax.faces.component.UIComponent;
 <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">import</span> javax.faces.render.Renderer;

 <span class="code-keyword">public</span> class TextCmdRenderer <span class="code-keyword">extends</span> Renderer {
    <span class="code-keyword">private</span> <span class="code-keyword">static</span> <span class="code-keyword">final</span> <span class="code-object">String</span> TEXT = <span class="code-quote">&quot;.text&quot;</span>;
    <span class="code-keyword">private</span> <span class="code-keyword">static</span> <span class="code-keyword">final</span> <span class="code-object">String</span> CMD = <span class="code-quote">&quot;.cmd&quot;</span>;

    <span class="code-keyword">public</span> void encodeBegin(FacesContext context,
                 UIComponent component) <span class="code-keyword">throws</span> IOException {
        ResponseWriter writer = context.getResponseWriter();
        <span class="code-object">String</span> clientId = component.getClientId(context);

        encodeTextField(component, writer, clientId);
        encodeCommand(component, writer, clientId);
    }

    <span class="code-keyword">public</span> void decode(FacesContext context,
                               UIComponent component) {
        Map reqParaMap = context.getExternalContext().
                                   getRequestParameterMap();
        <span class="code-object">String</span> clientId = component.getClientId(context);

        <span class="code-object">String</span> submittedValue =
                  (<span class="code-object">String</span>) reqParaMap.get(clientId + TEXT);
        ((EditableValueHolder) component).setSubmittedValue(
                                             submittedValue);
        ((EditableValueHolder) component).setValid(<span class="code-keyword">true</span>);
    }

    <span class="code-keyword">private</span> void encodeTextField(UIComponent component,
                     ResponseWriter writer, <span class="code-object">String</span> clientId)
                                      <span class="code-keyword">throws</span> IOException {
        writer.startElement(<span class="code-quote">&quot;input&quot;</span>, component);
        writer.writeAttribute(<span class="code-quote">&quot;name&quot;</span>, clientId + TEXT, <span class="code-keyword">null</span>);

        <span class="code-object">Object</span> value = ((UIInput) component).getValue();
        <span class="code-keyword">if</span>(value != <span class="code-keyword">null</span>) {
            writer.writeAttribute(<span class="code-quote">&quot;value&quot;</span>,
                         alue.toString(), <span class="code-keyword">null</span>);
        }

        <span class="code-object">String</span> size =
             (<span class="code-object">String</span>) component.getAttributes().get(<span class="code-quote">&quot;size&quot;</span>);
        <span class="code-keyword">if</span>(size != <span class="code-keyword">null</span>) {
            writer.writeAttribute(<span class="code-quote">&quot;size&quot;</span>, size, <span class="code-keyword">null</span>);
        }

        writer.endElement(<span class="code-quote">&quot;input&quot;</span>);
    }

    <span class="code-keyword">private</span> void encodeCommand(UIComponent component,
                        ResponseWriter writer,
                        <span class="code-object">String</span> clientId) <span class="code-keyword">throws</span> IOException {
        writer.startElement(<span class="code-quote">&quot;input&quot;</span>, component);
        writer.writeAttribute(<span class="code-quote">&quot;type&quot;</span>, <span class="code-quote">&quot;submit&quot;</span>, <span class="code-keyword">null</span>);
        writer.writeAttribute(<span class="code-quote">&quot;name&quot;</span>, clientId + CMD, <span class="code-keyword">null</span>);
        writer.writeAttribute(<span class="code-quote">&quot;value&quot;</span>, <span class="code-quote">&quot;submit&quot;</span>, <span class="code-keyword">null</span>);
        writer.endElement(<span class="code-quote">&quot;input&quot;</span>);
    }
 }</pre>
							</div>
						</div>
						<p>
						这个自订的Renderer其译码、编码过程,与之前直接在Component中进行译码或编码过程是类似的,所不同的是在译码与编码的方法上,多了
						UIComponent参数,代表所代理绘制的Component。</p>
						<p>
						接下来在自订Tag上,我们的TextWithCmdTag与之前主题所介绍的没什么差别,只不过在getComponentType()与
						getRendererType()方法上要修改一下:</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">&quot;javax.faces.Input&quot;</span>;
    }

    <span class="code-keyword">public</span> <span class="code-object">String</span> getRendererType() {
        <span class="code-keyword">return</span> <span class="code-quote">&quot;onlyfun.caterpillar.TextCmd&quot;</span>;
    }
    .....
 }</pre>
							</div>
						</div>
						<p>
						getComponentType()取得的是&quot;javax.faces.Input&quot;,它实际上对应至UIInput类别,而getRendererType()取回的是&quot;onlyfun.caterpillar.TextCmd&quot;,这会在faces-config.xml中定义,以对应至实际的Renderer类别:</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>faces-config.xml</b></div>
							<div class="codeContent">
								<pre class="code-java">....
 &lt;faces-config&gt;
     &lt;render-kit&gt;
         &lt;renderer&gt;
             &lt;component-family&gt;
                 javax.faces.Input
             &lt;/component-family&gt;
             &lt;renderer-type&gt;
                 onlyfun.caterpillar.TextCmd
             &lt;/renderer-type&gt;
             &lt;renderer-class&gt;
                 onlyfun.caterpillar.TextCmdRenderer
             &lt;/renderer-class&gt;
         &lt;/renderer&gt;
     &lt;/render-kit&gt;
 ....
 &lt;/faces-config&gt;</pre>
							</div>
						</div>
						<p>为Component定义一个Renderer,必须由component family与renderer
						type共同定义,这并不难理解,因为一个Component可以搭配不同的Renderer,但它是属于同一个component
						family,例如UIInput就是属于javax.faces.Input这个组件家族,而我们为它定义一个新的Renderer。</p>
						<p>
						接下未完成的范例可以取之前主题介绍过的,我们虽然没有自订组件,但我们为UIInput置换了一个新的Renderer,这个Renderer会在输入字段上加入一个按钮。</p>
						<p>如果您坚持使用之前自订的UITextWithCmd,则可以如下修改:</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> javax.faces.component.UIInput;

 <span class="code-keyword">public</span> class UITextWithCmd <span class="code-keyword">extends</span> UIInput {
    <span class="code-keyword">public</span> UITextWithCmd() {
        setRendererType(<span class="code-quote">&quot;onlyfun.caterpillar.TextCmd&quot;</span>);
    }
 }</pre>
							</div>
						</div>
						<p>
						我们只是单纯的继承UIInput,然后使用setRendererType()设定&quot;onlyfun.caterpillar.TextCmd&quot;,但并没有为组件加入什么行为,看来什么事都没有作,但事实上这是因为继承了UIInput,它为我们处理了大多数的细节。</p>
						<p>接下来同样的,设定自订Tag:</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">&quot;onlyfun.caterpillar.TextWithCmd&quot;</span>;
    }

    <span class="code-keyword">public</span> <span class="code-object">String</span> getRendererType() {
        <span class="code-keyword">return</span> <span class="code-quote">&quot;onlyfun.caterpillar.TextCmd&quot;</span>;
    }
    .....
 }</pre>
							</div>
						</div>
						<p>要使用自订的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">....
    &lt;component&gt;
        &lt;component-type&gt;
            onlyfun.caterpillar.TextWithCmd
        &lt;/component-type&gt;
        &lt;component-class&gt;
            onlyfun.caterpillar.UITextWithCmd
        &lt;/component-class&gt;
    &lt;/component&gt;
 ...</pre>
							</div>
						</div>
					</div>
					</td>
				</tr>
			</table>
			</td>
		</tr>
	</table>
</div>

</body>

</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -