jsf jsf-2 facelets custom-component

Componente JSF personalizado que agrega un nuevo elemento secundario a la faceta "cabeza" de la página



jsf-2 facelets (1)

Quiero crear un componente personalizado que agregue nuevo elemento secundario a la faceta "cabeza" de la página.

Este componente personalizado se basa en h: selectOneMenu. Cuando se usa en la página jsf, el usuario puede simplemente cambiar el tema actual. Lo que necesito que haga este componente es agregar la hoja de estilo de la cabecera del hijo a la cabeza.

Mi componente tiene respaldo java. Traté de modificar "cabeza" en el método encodeBegins (), pero mi hijo no se representa en absoluto. Eche un vistazo a la implementación:

@FacesComponent(value = "com.ramps.util.ThemeSelector") public class ThemeSelector extends UIInput implements NamingContainer { public void encodeBegin(FacesContext context) throws IOException { UIComponent headFacet = context.getViewRoot().getFacet("javax_faces_location_HEAD"); Resource res = new Resource(); res.setName("..."); ... List <UIComponent> headChildren = headFacet.getChildren(); headChildren.add(res); super.encodeBegin(context); } }

¿Es posible modificar la faceta "cabeza" directamente desde el respaldo de Java de mi componente personalizado? Si es así, ¿qué me estoy perdiendo?
Saludos


UIViewRoot tiene un método para agregar un componente de recurso al objetivo principal de la vista:

public void addComponentResource (FacesContext context, UIComponent componentResource): agrega componentResource, que se supone que representa una instancia de recurso, a la vista actual. Una instancia de recurso es renderizada por un Renderer de recursos (como ScriptRenderer, StylesheetRenderer) como se describe en el estándar HTML RenderKit. Este método hará que el recurso se represente en el elemento "head" de la vista.

Para su caso, el componente es una UIOutput con un nombre de atributo y un tipo de representación de javax.faces.resource.Stylesheet .

Puede agregar el recurso de la hoja de estilo después de que su componente personalizado se haya agregado a la vista. Usted hace esto, registrándolo para escuchar PostAddToViewEvent''s. UIInput ya implementa ComponentSystemEventListener, por lo que debe sobrescribir processEvent.

Este es un ejemplo de trabajo de un componente que agrega una hoja de estilo.

@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); } }

Me pregunto si usar un componente compuesto no es más fácil para lo que estás tratando de hacer.