项目里面使用了sandbox 的 s:selectManyPicklist 标签, 但是因为它只有两个button,客户需要加两个全选的button。开始的解决方法是这样,但是在不同的浏览器下位置有变动。于是就想自己定制这个tag,加上全选的两个按钮。
<div style="height:3px;top:-207px;position:relative;left:125px;">
<input type="button" onclick="addAllService('addEditForm:Corporate_Billing_Reference_Type')" value=">>" style="top:80px;position:relative;left: 44px;"/>
<input type="button" onclick="removeAllService('addEditForm:Corporate_Billing_Reference_Type')" value="<<" style="top:139px;position:relative;left:19px;"/>
</div>
定制jsf组件的结构图(转自<<Core javaServer Face>>)
因为只是加两个按钮,其他功能不变,所以直接拷贝了sandbox包里的源码。这里有个需要注意的地方,因为只是替换了selectManyPicklist的实现,其他的代码还是用到了jar的代码,所以新的代码必须放在org.apache.myfaces.custom下面,不然就出错。
大体上有三个类和两个配置文件:tag类、component类和render类。render功能可以写在component类里面。配置文件为web-inf下的faces-config.xml和一个tld文件。
(一)tld文件主要是定义标签的一些属性,jsf会在web-inf目录、其子目录、META-INF 目录或WEB-INF/lib下的jar文件里面查找tld文件。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>cp</short-name>
<uri>http://myfaces.apache.org/customizePicklist</uri>
<display-name>Tomahawk tag library.</display-name>
<description>MyFaces subproject that contains components and other goodies to be used with any JSF implementation.</description>
<tag>
<name>selectManyPicklist</name>
<tag-class>org.apache.myfaces.custom.HtmlSelectManyPicklistTag2</tag-class>
<body-content>JSP</body-content>
<description>A tag for a select many pick list component</description>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>java.lang.String</type>
</attribute>
<attribute>
<name>value</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>java.lang.String</type>
<description><![CDATA[The initial value of this component.]]></description>
</attribute>
...
(二)这里分析下render类。一般我们会覆盖其中的encode和decode这两个方法。
encode会在jsf生命周期的末尾调用,生成相应的html代码,共有三个方法encodeBegin(),encodeChildren(),encodeEnd()。对于大多数组件用encodeBegin()或者encodeEnd()就可以了。
public void encodeBegin(FacesContext context,UIComponent uiComponent) throws IOException {
...
encodeJavascript(facesContext,uiComponent); // 定制的Javascript
...
ResponseWriter writer = facesContext.getResponseWriter();
writer.startElement(HTML.TABLE_ELEM, uiComponent);
writer.startElement(HTML.TR_ELEM, uiComponent);
writer.startElement(HTML.TD_ELEM, uiComponent);
writer.writeAttribute("name", "myTd", null); // 添加属性
...
writer.endElement(HTML.TD_ELEM);
writer.endElement(HTML.TR_ELEM);
writer.endElement(HTML.TABLE_ELEM);
}
在encodeBegin里面还可以导入Javascript文件,当然也可以直接用writer写在encodeBegin方法里面。
private void encodeJavascript(FacesContext facesContext,
UIComponent uiComponent)
{
// AddResource takes care to add only one reference to the same script
AddResource addResource = AddResourceFactory.getInstance(facesContext);
try {
addResource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN,
HtmlPicklistRenderer2.class, "picklist2.js");
} catch (Exception e) {
e.printStackTrace();
}
}
HtmlPicklistRenderer2.class 就是這個Render類了,picklist2.js必須放在Render類同目錄下的Resource目錄下。javascript的使用方法如下:
...
writer.writeAttribute(HTML.ONCLICK_ATTR, javaScriptFunction, null); // javaScriptFunction 为string型
...
decode则在生命周期的开始调用,取得客户端的请求,得到submitted value。这时可以做一些验证工作,结束时必须调用 setValid(true)以表示submittedValue是可以转成你在后台想要的类型。
public void decode(FacesContext context, UIComponent component) {
Map requestMap = context.getExternalContext().getRequestParameterMap();
String submittedValue = requestMap.get(idName));
... // 做些验证工作
setSubmittedValue(submittedValue);
setValid(true);
}
因为html-base应用接受的数据都是string型的需要设置你想要的转换器。这个可以在构造器了做,比如这里我想由String转成Integer型。当然也可以自己定制Converter。
// 构造函数
setConverter(new IntegerConverter()); // to convert the submitted value
...
(三)tag类主要是根据定义在tld文件里的属性和标签来写。主要的有两个方法:setProperties() 和release()。
setProperties()主要是拷贝tag属性到component里。
public String getComponentType()
{
return HtmlSelectManyPicklist2.COMPONENT_TYPE;
}
public String getRendererType()
{
return HtmlSelectManyPicklist2.DEFAULT_RENDERER_TYPE;
}
public void setEnabledOnUserRole(String enabledOnUserrole) {
//TODO: please do something here, because it is referenced by the tld
}
public void setVisibleOnUserRole(String enabledOnUserrole) {
//TODO: please do something here, because it is referenced by the tld
}
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "accesskey", _accesskey);
setStringProperty(component, "datafld", _datafld);
setStringProperty(component, "onblur", _onblur);
setStringProperty(component, "onchange", _onchange);
setStringProperty(component, "onfocus", _onfocus);
setStringProperty(component, "onselect", _onselect);
setIntegerProperty(component, "size", _size);
setStringProperty(component, "enabledClass", _enabledClass);
...
}
以后就可以用 Integer size = (Integer) component.getAttributes().get("size");来访问属性。
release()方法就是初始化了,不过它必须调用super.release()。
getComponentType 和getRendererType 会根据web-inf目录下的faces-config.xml寻找相应的类去实现。
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<faces-config>
<component>
<component-type>org.apache.myfaces.HtmlSelectManyPicklist2</component-type>
<component-class>org.apache.myfaces.custom.HtmlSelectManyPicklist2</component-class>
</component>
<render-kit>
<renderer>
<component-family>javax.faces.SelectMany</component-family>
<renderer-type>org.apache.myfaces.PicklistRenderer2</renderer-type>
<renderer-class>org.apache.myfaces.custom.HtmlPicklistRenderer2</renderer-class>
</renderer>
</render-kit>
</faces-config>
(四)component類
一般情况下,只需继承已有的类就可以了。
(五) 对于有子标签的标签来说还需要额外的一些工作。
分享到:
相关推荐
- **实现方法**:根据需要定制组件的外观和行为,实现Renderer接口中定义的方法。 - **注册Renderer**:在JSF配置文件中注册自定义的Renderer,使其能够与相应的组件关联。 总之,通过深入理解JSF的生命周期、...
在"jsf组件开发源码"中,我们很可能是要探讨如何创建自定义的JSF组件,以及源码背后的实现逻辑。 首先,JSF组件是由UIComponent类及其子类构成的。每个组件都是一个独立的UI元素,具有渲染、属性和事件处理能力。...
创建JSF自定义组件是一项复杂但强大的任务,它允许开发者根据项目需求定制Web应用的界面和交互。通过理解组件和渲染器的工作原理,以及如何注册和使用它们,开发者可以极大地提升JSF应用的灵活性和可扩展性。
在JavaServer Faces (JSF) ...自定义组件是JSF 2.0的强大特性,它允许开发人员创建高度定制化的用户界面元素,适应各种复杂的应用场景。理解并掌握自定义组件的开发,对于提升JSF应用程序的灵活性和可维护性至关重要。
【JSF创建自定义组件】 JSF(JavaServer Faces)是一种用于构建Web应用程序的MVC框架,它允许开发者创建可重用的UI组件。在JSF中,自定义组件允许开发人员扩展框架的功能,以满足特定项目的需求。下面将详细解释...
通过这种方式,开发者可以创建出符合特定业务需求的自定义JSF组件,增强Web应用的灵活性和可定制性。 总结起来,自定义JSF组件是JSF框架的一大优势,它允许开发者根据项目需求创建独特的UI组件。通过理解组件模型、...
为特定Web应用编写定制组件集可能比试图使用客户甚至不接受的现有组件更为有效。 撰写自己的JSF UI组件是否容易?Sun的J2EE教程专门有一部分讲解了如何创建JSF组件。本文将从以下几个步骤深入探讨: 步骤1:构建...
自定义组件允许开发人员根据特定需求创建自己的UI组件,这些组件可以扩展和定制,以满足应用程序的独特功能。 自定义组件的核心概念包括以下几个部分: 1. **组件类(Component Class)**:这是组件的核心,通常...
这些组件可以通过XML(Faces配置文件)或Java代码声明,并可以通过属性和事件进行定制。动态操作组件意味着可以在运行时根据需要创建、更新或删除这些组件。 3. **MyEclipse 6.5**:这是一个集成开发环境(IDE),...
理解和分析源码可以帮助开发者深入理解JSF的工作原理,定制自己的组件,或者优化性能。例如,可以通过查看`FacesServlet`的源码了解JSF如何处理HTTP请求,或者研究`UIComponent`类以了解组件的生命周期和渲染过程。 ...
每个组件都有对应的属性和事件,可以方便地进行定制和交互。 **4. Managed Beans** Managed Beans是JSF中的核心概念,它们作为业务逻辑的载体,可以被JSF框架自动管理。开发者可以定义属性和方法,实现后端逻辑,并...
- **faces-config.xml**:JSF的配置文件,用于定义页面导航规则、管理Bean的生命周期以及设置其他定制配置。例如,`<managed-bean>`标签用于声明和配置Bean,`<navigation-rule>`用于定义页面间的跳转逻辑。 JSF还...
组件可以通过属性进行定制,如设置值、验证规则等。此外,还可以通过JSF的事件模型来响应用户操作。 **6. 数据绑定与EL** JSF的Expression Language(EL)用于在视图和Managed Bean之间进行数据绑定。例如,`#{bean...
`webui-jsf.jar`包含了基本的JSF UI组件,如按钮、输入字段等,而`webui-jsf-suntheme.jar`则提供了Sun Microsystems的主题样式,用于定制UI的外观和感觉。 2. **jsf-impl.jar** 和 **jsf-api.jar**: 这是JSF的...
京东可能在其内部开发了一个定制版的JSF框架,以适应其电商平台的需求。这可能包括对性能的优化、额外的安全特性、更符合京东业务流程的组件库等。由于没有具体的京东JSF框架的详细信息,这部分只能是推测。 **学习...
- **组件模型**:JSF 1.2基于组件模型,允许开发者组合和定制UI组件。`UIComponent`是所有组件的基类,而`UIInput`、`UIMessage`等则是具体组件类型。 - **生命周期**:JSF有六阶段的生命周期,包括恢复视图、应用...
1. **组件(Components)**:JSF的核心是UI组件,它们负责呈现用户界面。例如,按钮、文本输入框、表格等。这些组件可以通过XML配置或者在Java代码中动态创建。 2. **事件(Events)**:JSF中的事件处理机制允许...
- **JSF**:相比于Struts,JSF在组件模型上更加先进,支持更丰富的用户界面组件,并且内置了更多的功能,如验证、转换等,使得开发过程更加简单高效。 #### 四、JSF的优势与劣势 - **优势**: - **易于学习和使用*...
**JSF(JavaServer Faces)API** 是Java平台上的一个组件框架,用于构建Web应用程序。JSF提供了一种声明式的方式来创建用户界面,并且它与MVC(模型-视图-控制器)设计模式紧密集成。这个API帮助文档是开发者理解和...
这些组件可以通过属性和事件进行定制,以满足不同需求。 3. **Facelets**:Facelets是JSF推荐的视图表示技术,它是一种XML基的模板语言,用于构建用户界面。Facelets允许开发者使用EL(Expression Language)表达式...