I want to create custom component which adds new child to page \"head\" facet.
This custom component is based on h:selectOneMenu. When used on jsf page, user can sim
UIViewRoot has a method to add a resource component to the head target of the view:
public void addComponentResource(FacesContext context, UIComponent componentResource): Add componentResource, that is assumed to represent a resource instance, to the current view. A resource instance is rendered by a resource Renderer (such as ScriptRenderer, StylesheetRenderer) as described in the Standard HTML RenderKit. This method will cause the resource to be rendered in the “head” element of the view.
For your case, the component is an UIOutput with an attribute name and a render type of javax.faces.resource.Stylesheet.
You can add the stylesheet resource after your custom component is added to the view. You make this, registering it for listening to PostAddToViewEvent's. The UIInput already implements ComponentSystemEventListener so you have to override processEvent.
This is a working example of a component that adds a stylesheet.
@FacesComponent("CustomComponent")
@ListenerFor(systemEventClass=PostAddToViewEvent.class)
public class CustomComponent extends UIInput{
@Override
public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
if(event instanceof PostAddToViewEvent){
UIOutput resource=new UIOutput();
resource.getAttributes().put("name", "theme.css");
resource.setRendererType("javax.faces.resource.Stylesheet");
FacesContext.getCurrentInstance().getViewRoot().addComponentResource(FacesContext.getCurrentInstance(), resource);
}
super.processEvent(event);
}
}
I wonder if using a composite component is not easier for what you are trying to do.