我需要以編程方式在JSF 2中創建複合組件。經過幾天的搜索和實驗,我找出了此方法(受到java.net上的Lexi的啓發):如何以編程方式或動態創建JSF 2中的複合組件
/**
* Method will attach composite component to provided component
* @param viewPanel parent component of newly created composite component
*/
public void setComponentJ(UIComponent viewPanel) {
FacesContext context = FacesContext.getCurrentInstance();
viewPanel.getChildren().clear();
// load composite component from file
Resource componentResource = context.getApplication().getResourceHandler().createResource("whatever.xhtml", "components/form");
UIComponent composite = context.getApplication().createComponent(context, componentResource);
// push component to el
composite.pushComponentToEL(context, composite);
boolean compcompPushed = false;
CompositeComponentStackManager ccStackManager = CompositeComponentStackManager.getManager(context);
compcompPushed = ccStackManager.push(composite, CompositeComponentStackManager.StackType.TreeCreation);
// Populate the component with value expressions
Application application = context.getApplication();
composite.setValueExpression("value", application.getExpressionFactory().createValueExpression(
context.getELContext(), "#{stringValue.value}",
String.class));
// Populate the component with facets and child components (Optional)
UIOutput foo = (UIOutput) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
foo.setValue("Foo");
composite.getFacets().put("foo", foo);
UIOutput bar = (UIOutput) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
bar.setValue("Bar");
composite.getChildren().add(bar);
// create composite components Root
UIComponent compositeRoot = context.getApplication().createComponent(UIPanel.COMPONENT_TYPE);
composite.getAttributes().put(Resource.COMPONENT_RESOURCE_KEY, componentResource);
compositeRoot.setRendererType("javax.faces.Group");
composite.setId("compositeID");
try {
FaceletFactory factory = (FaceletFactory) RequestStateManager.get(context, RequestStateManager.FACELET_FACTORY);
Facelet f = factory.getFacelet(componentResource.getURL());
f.apply(context, compositeRoot); //<==[here]
} catch (Exception e) {
log.debug("Error creating composite component!!", e);
}
composite.getFacets().put(
UIComponent.COMPOSITE_FACET_NAME, compositeRoot);
// attach composite component to parent componet
viewPanel.getChildren().add(composite);
// pop component from el
composite.popComponentFromEL(context);
if (compcompPushed) {
ccStackManager.pop(CompositeComponentStackManager.StackType.TreeCreation);
}
}
問題是,只有當javax.faces.PROJECT_STAGE設置爲PRODUCTION(我花了我一整天的時間才弄清楚),這段代碼才適用於我。如果javax.faces.PROJECT_STAGE被設定爲發拋出異常上標記點(< == [此處]):
javax.faces.view.facelets.TagException: /resources/components/form/pokus.xhtml @8,19 <cc:interface> Component Not Found for identifier: j_id2.getParent().
at com.sun.faces.facelets.tag.composite.InterfaceHandler.validateComponent(InterfaceHandler.java:135)
at com.sun.faces.facelets.tag.composite.InterfaceHandler.apply(InterfaceHandler.java:125)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:82)
at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:152)
at cz.boza.formcreator.formcore.Try.setComponentJ(Try.java:83)
at cz.boza.formcreator.formcore.FormCreator.<init>(FormCreator.java:40)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
這一些問題,在父組件compositeRoot設定(j_id2被automaticaly產生compositeRoot的ID) 。此外,這些代碼還沒有經過足夠的測試,所以我不確定我是否可以依靠它。
我認爲它非常重要,能夠操縱複合材料部件programmaticaly。否則,複合組件是無用的。
非常感謝。
經過一番測試我也發現,我不能編程嵌套任何組件(添加爲兒童)在其他複合組件:(。 – 2011-03-23 22:44:49
好吧所以我最終找到的解決方案。在這裏你可以下載演示豪以編程方式創建複合組件。 /confluence.highsource。org/display/Hifaces20/Dynamic + Faces + - + sample +演示+動態+或+編程+ UI +創建+使用+ JSF + 2.0 +和+ Facelets – 2011-03-24 22:52:20
我試過現在的鏈接和它的工作原理。這個過程非常複雜,因爲它是關於編程組件創建和整個JSF頁面動態構建的整個項目。 – 2012-01-06 16:20:02