JSF ResponseWriter自定义组件
我知道ResponseWriter上的startElement、endElement和writeAttribute方法。我的问题是,例如,我想通过像JSF ResponseWriter自定义组件,jsf,uicomponents,Jsf,Uicomponents,我知道ResponseWriter上的startElement、endElement和writeAttribute方法。我的问题是,例如,我想通过像HtmlCommandLink=newhtmlcommandlink()这样声明来输出h:commandLink 如何在自己的组件中输出其他类似的UIComponent?我可能也想在我的组件中使用一些RichFaces ajax的东西,这样我就可以避免从头开始 编辑:我正在尝试用以下标记创建我自己的标记库。每个评论都有一个回复按钮,当点击回复按钮时,
HtmlCommandLink=newhtmlcommandlink()这样声明来输出h:commandLink代码>
如何在自己的组件中输出其他类似的UIComponent?我可能也想在我的组件中使用一些RichFaces ajax的东西,这样我就可以避免从头开始
编辑:我正在尝试用以下标记创建我自己的标记库
。每个评论都有一个回复按钮,当点击回复按钮时,我会在评论下面呈现回复表单。渲染完成后,我想输出richfaces
组件。这必须在我自己的java标记文件中完成,我调用了CommentsTreeUI.java
通常,我使用writer.startElement(“输入”,myComponent)输出所有显示表单和按钮的元素;writer.writeAttribute(“类型”,“按钮”,null)代码>但是如果我可以改为做例如startElement(“a4j:commandbutton,myComponent)
,这会对我的很多帮助,因为它有所有内置的ajax功能等等
有什么线索吗?你可以这样做:
HtmlCommandLink link = new HtmlCommandLink();
getChildren().add(link);
它确实取决于您想对子组件执行什么操作,也就是说,如果您想让它们包含自定义HTML(例如,在HTML列表中),则需要更复杂的内容。制作复合控件的一种方法是使用binding属性将标记与您自己的代码相关联:
<f:view>
<h:form>
<h:panelGroup binding="#{compositeControlBean.panelGrid}" />
</h:form>
</f:view>
faces-config.xml中的bean配置:
复合控件
composite.CompositeControlBean
要求
bean代码:
/**
* Configure this bean in request scope as "compositeControlBean".
*/
public class CompositeControlBean {
private transient UIComponent panelGrid;
public UIComponent getPanelGrid() {
if (panelGrid == null) {
panelGrid = createCompositePanel();
}
return panelGrid;
}
public void setPanelGrid(UIComponent panelGrid) {
this.panelGrid = panelGrid;
}
private UIComponent createCompositePanel() {
initContextMemebers();
UIComponent commandLink = createCommandLink();
String id = view.createUniqueId();
UIComponent panelGrid = application
.createComponent("javax.faces.HtmlPanelGroup");
panelGrid.setId(id);
panelGrid.setRendererType("javax.faces.Group");
panelGrid.getChildren().add(commandLink);
return panelGrid;
}
private UIComponent createCommandLink() {
// create control
String id = view.createUniqueId();
UIComponent commandLink = application
.createComponent("javax.faces.HtmlCommandLink");
commandLink.setId(id);
commandLink.setRendererType("javax.faces.Link");
// set attributes (bind to printHello method)
Map<String, Object> attributes = commandLink
.getAttributes();
MethodExpression action = expressionFactory
.createMethodExpression(elContext,
"#{compositeControlBean.printHello}",
String.class, new Class<?>[0]);
attributes.put("value", "print hello");
attributes.put("actionExpression", action);
return commandLink;
}
private transient FacesContext context;
private transient Application application;
private transient ELContext elContext;
private transient ExpressionFactory expressionFactory;
private transient UIViewRoot view;
private void initContextMemebers() {
context = FacesContext.getCurrentInstance();
application = context.getApplication();
elContext = context.getELContext();
expressionFactory = application.getExpressionFactory();
view = context.getViewRoot();
}
public String printHello() {
System.out.println("Hello");
return null;
}
}
/**
*在请求范围中将此bean配置为“compositeControlBean”。
*/
公共类CompositeControlBean{
私有暂态分量网格;
公共UIComponent getPanelGrid(){
if(panelGrid==null){
panelGrid=createCompositePanel();
}
返回板栅;
}
公共void setPanelGrid(UIComponent panelGrid){
this.panelGrid=panelGrid;
}
私有UIComponent createCompositePanel(){
initContextMemebers();
UIComponent commandLink=createCommandLink();
String id=view.createUniqueId();
UIComponent panelGrid=应用程序
.createComponent(“javax.faces.HtmlPanelGroup”);
panelGrid.setId(id);
setRenderType(“javax.faces.Group”);
panelGrid.getChildren().add(commandLink);
返回板栅;
}
私有UIComponent createCommandLink(){
//创建控件
String id=view.createUniqueId();
UIComponent commandLink=应用程序
.createComponent(“javax.faces.htmlCommand链接”);
commandLink.setId(id);
setRenderType(“javax.faces.Link”);
//设置属性(绑定到printHello方法)
映射属性=commandLink
.getAttributes();
MethodExpression动作=expressionFactory
.createMethodExpression(elContext,
“#{compositeControlBean.printHello}”,
String.class,新类[0]);
attributes.put(“value”,“print hello”);
attributes.put(“actionExpression”,action);
返回命令链接;
}
私有瞬态FacesContext上下文;
私有瞬态应用程序;
私人临时语境;
私人瞬时表达式工厂表达式工厂;
私有视图根视图;
私有void initContextMemebers(){
context=FacesContext.getCurrentInstance();
application=context.getApplication();
elContext=context.getELContext();
expressionFactory=application.getExpressionFactory();
view=context.getViewRoot();
}
公共字符串printHello(){
System.out.println(“你好”);
返回null;
}
}
通过使用添加新组件解决了此问题
HtmlCommandButton button = new HtmlCommandButton();
button.encodeAll(context);
非常非常有趣。通过getChildre()添加(链接)它将我的按钮/链接一直添加到页面的末尾。我如何在我的htmloutputs序列中输出它?例如,我正在写一个div,我希望链接在该div中。非常感谢!总而言之,我基本上希望在需要的地方添加这些子组件。它们只是附加在GUI的末尾。你有没有试着在你想要呈现的组件上调用encodeBegin(…)等?嗯,没有。我的程序中有encodeBegin和encodeEnd,但我渲染的所有内容都是在encodeBegin方法中完成的。它真的很大,有几百行代码。我是不是做错了?你想做什么?创建复合控件?或者只是在运行时创建一个新控件?我知道这个问题很老了,但我也在这样做。这种方法的问题是HtmlCommandButton没有得到父级分配,即使它呈现为ok。您需要专门调用按钮。setParent(this)
。检查:仅供阅读此问题的任何人参考。最好不要通过“新建”创建组件,但如下所示:
HtmlCommandButton button = new HtmlCommandButton();
button.encodeAll(context);