Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to programmatically or dynamically create a composite component in JSF 2
    primarykey
    data
    text
    <p>I need to programatically create composite components in JSF 2. After few days of searching and experiments I figure out this method (higly inspired by Lexi at java.net): </p> <pre><code>/** * 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); //&lt;==[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); } } </code></pre> <p>Problem is that this code works for me only when javax.faces.PROJECT_STAGE is set to PRODUCTION (It took me all day to figure this out). If javax.faces.PROJECT_STAGE is set to DEVELOPMENT Exception is thrown on marked point (&lt;==[here]):</p> <pre><code>javax.faces.view.facelets.TagException: /resources/components/form/pokus.xhtml @8,19 &lt;cc:interface&gt; 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.&lt;init&gt;(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) </code></pre> <p>It's some problem with parent set in compositeRoot component (j_id2 is automaticaly generated ID of compositeRoot). Also this code is not tested thorougly enough, so I'm not sure if I can rely on it.</p> <p>I think its very important to be able to manipulate Composite Components programmaticaly. Otherwise Composite Components are half useless.</p> <p>Thank you very much.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload