Neste artigo veremos como definir o componente e sua renderização.
Definindo o componente:
Basta criarmos uma classe que chamaremos HtmlSeuComponente. Nela redefiniremos os atributos definidos na classe SeuComponenteTag do artigo anterior, criaremos seu gets e sets e mais algumas funções necessárias.
public class HtmlSeuComponente extends UIComponentBase{
private String _id;
private String _value;
private String _styleClass;
/**
* Definimos quem renderizará nosso componente, isto deve
* estar de acordo com o META-INF/faces-config.xml
*/
public HtmlSeuComponente() {
super();
setRendererType(“pacote.ClasseDoRenderizador”);
}/**
* Definimos a familia do nosso componente, isto deve
* estar de acordo com o META-INF/faces-config.xml
*/
public String getFamily(){
return “familiaDoComponente”;
}/**
* Este método é responsável por salvar o
* valor das propriedades do componente
*/
public Object saveState(FacesContext context){
Object values[] = new Object[4];
values[0] = super.saveState(context);
values[1] = _id;
values[2] = _value;
values[3] = _styleClass;return values;
}
/**
* Este método é responsável por restaurar o
* valor das propriedades do componente
*/
public void restoreState(FacesContext context, Object state){
Object values[] = (Object[])state;
super.restoreState(context, values[0]);
setId((String)values[1]);
setValue((String)values[2]);
setStyleClass((String)values[3]);
}/**
* Estes são os métodos de get e set de um atributo qualquer,
* aqui no caso, definimos para o id (devem ser definidos os
* outros gets e sets da mesma forma ).
* O value binding é utilizado para pegar o valor informado
* para o nosso componente.
*/
public void setId(String id) {
this._id = id;
}public String getId(){
if (_id != null)
return _id;ValueBinding vb = getValueBinding(”id”);
if (vb == null)
return null;
else
return (String)vb.getValue(getFacesContext());
}}
Da mesma forma, precisamos definir um renderizador, responsável por exibir nosso componente. Esta classe é definida da seguinte maneira:
public class HtmlSeuComponenteRenderer extends Renderer{
/**
* Consultar documentac�o da superclasse
*/
public void encodeBegin(javax.faces.context.FacesContext context, UIComponent component) throws IOException{
super.encodeBegin(context, component);
}/**
* Consultar documentac�o da superclasse
*/
public void encodeEnd(javax.faces.context.FacesContext context, UIComponent component) throws IOException{
super.encodeEnd(context, component);
decode(context, component);
}/**
* Etapa mediana no processo de renderizacao da tela
*
* @param context
* @param component
*/
public void decode(FacesContext context, UIComponent component){
ResponseWriter writer = context.getResponseWriter();
/** Aqui podemos imprimir qualquer HTML via
* writer.startElement(HTML.INPUT_ELEM, component);
* writer.writeAttribute(”id”,”idDoInput”, null);
* writer.writeAttribute(”type”,”button”, null);
* writer.writeAttribute(”onClick”,”funcaoQualquer()”, null);
* writer.endElement(HTML.INPUT_ELEM);
* ou até mesmo utilizar componentes de outras bibliotecas, tais como
* o próprio MyFaces.
* Podemos ainda fazer tratamento de requisições AJAX e coisas do tipo
*/
}protected Class getComponentClass() {
return HtmlSeuComponenteRenderer.class;
}
}
Como você pode notar, esta classe é extremamente simples, mas começa atingir níveis maiores de complexidade quando começamos a adicionar recursos na página onde o componente será renderizado, como por exemplo javascript e css. Ainda podemos ter requisições AJAX envolvidas.
Ainda há muito a ser explorado neste campo, talvez num próximo artigo venhamos a falar a respeito de mais algumas possibilidades.
Portanto, um componente JSF funciona da seguinte maneira:
Existe um xml que define o componente e suas propriedades (META-INF/nomeDaTLD.tld) e um xml que define as classes envolvidas no processo (META-INF/faces-config.xml). Quando instanciamos o componente numa página JSP/JSF, utilizamos a definição da TLD. O JSF se encarrega de definir os valores na classe SeuComponenteTag, que por sua vez repassa ao HtmlSeuComponente que faz o binding dos valores reais. Em seguida é chamado o HtmlSeuComponenteRenderer que renderiza o seu componente conforme a sua vontade.
Para finalizar vamos utilizar nosso componente. Para uma página JSF/JSP qualquer:
<%@ taglib uri=”http://auri.algumacoisa” prefix=”tb”%>
<tb:nomeDoComponente id=”idDele”
value=”#{AlgumaClasse.propriedade}”
binding=”#{AlgumaClasse.objetoQueRepresentaOComponente}”
styleClass=”nomeDaClasseCss”/>
Então, agora que já compreende o processo, é só definir corretamente as propriedades e começar a definir seu próprio componente.
Boa sorte
Parabéns ficou show de bola este artigo mto bom mesmo,Que tal se agora fizessemos este mesmo componente gerar wml em vez de html vejo inumeras pessoas com duvidas qto a criacao de componentes para wap.t+
Obrigado Leandro!
O processo de criação de um componente WML é o mesmo de um componente HTML, a única diferença é o modo de renderização. Ou seja, ao invés de utilizar writer.startElement(HTML.*) podemos utilizar writer.startElement(WML.*) (que deve ser implementado) ou ainda gestores apropriados para escrita WML.
O MyFaces por exemplo, possui componentes WML que podem ser utilizados como embasamento.
link: http://mirrors.ibiblio.org/pub/mirrors/maven2/myfaces/myfaces-wap/1.0.9/
Mesmo assim o assunto é uma boa pedida, então talvez eu escreva sobre o assunto.
Obrigado pela sugestão =)