Salut à tous,
j'aimerais connaitre la meilleur facon de créer nos propres composants ainsi de faire une template en jsf(j'ai entendu parler de facelets,pas trop compris le systéme,si vous connaissez un site si possible en fr,ca serait sympa)
Salut à tous,
j'aimerais connaitre la meilleur facon de créer nos propres composants ainsi de faire une template en jsf(j'ai entendu parler de facelets,pas trop compris le systéme,si vous connaissez un site si possible en fr,ca serait sympa)
Bonjour,
Il faudrait en savoir un peu plus sur le genre de composant que tu veux créer.
En gros, il y a deux voies :
1. Tu utilises les Facelets. Il s'agit là de faire un composant représentant une composition (un ensemble) de composants déjà existants. C'est rapide, simple, mais limité : par exemple, il n'est pas forcément possible d'affecter un ID à un composant de ce type.
Voici un composant fait à partir de composition qui permet de gérer facilement une colonne d'une DataTable (avec des liens permettant de trier la colonne en question) :
(j'ai un peu simplifié le code, voir la page ici pour plus de détails).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" ...> <ui:composition> <h:column> <f:facet name="header"> <h:panelGroup> ${label} [ <!-- Sort ascending --> <h:commandLink styleClass="smallLink" action="#{backingBean.sort}"> <h:outputText value="asc" /> <f:param name="by" value="${fieldName}"/> <f:param name="order" value="asc"/> </h:commandLink> , <!-- Sort descending --> <h:commandLink styleClass="smallLink" action="#{backingBean.sort}"> <h:outputText value="asc" /> <f:param name="by" value="${fieldName}"/> <f:param name="order" value="dec"/> </h:commandLink> ] </h:panelGroup> </f:facet> <!-- Display the field name --> <h:outputText value="${entity[fieldName]}"/> </h:column> </ui:composition> </html>
2. La seconde voie est de créer un composant en les codant en Java. Là, c'est plus complexe (il faut créer une classe pour le Renderer, une classe pour l'objet JSF, etc.) mais ça permet de créer absolument tout ce que l'on veut.
De mon côté, sur mon projet, nous utilisons les 2 méthodes. Quant la composition est possible, on l'utilise, sinon on crée nos propres composants. En fait, pour être plus précis, nous créons des composants en étendant des composants déjà existants.
Par exemple, nous avions besoin de créer un composant de type AjaxButton (a4j:commandButton), nous avons donc créer notre composant (qui étend la classe org.ajax4jsf.ajax.html.HtmlAjaxCommandButton), ainsi que le composant graphique (étandant la classe org.ajax4jsf.renderkit.html.CommandButtonRenderer).
J'espère t'avoir mis sur la bonne voie...
Nous sommes tous semblables, alors acceptons nos différences !
--------------------------------------------------------------
Liens : Blog | Page DVP | Twitter
Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
Critiques : Apache Maven
merci pour ta réponse
Ceux que j'ai compris par rapport à ton exemple,c'est qu'une variable contient le code permettant dans ton cas de trier une datable
Et si par exemple,j'ai envi de créer des composants dynamiques à partir d'un fichier xml.Je m'explique,j'ai un fichier qui contient des informations(faut voir sous qu'elle forme)et à partir de ses données,nous pouvons créer par exemple une datatable,un champ texte...,en fait des composant dynamique.
Aurais tu un petit exemple pour avoir un appercu d'un composant créer totalement
De rien
Tu parles de quoi au juste ? De ça : action="#{backingBean.sort}" ?
Ce bout de code signifie juste que lorsque l'utilisateur clique sur le lien, alors c'est la méthode sort du bean backingBean qui sera exécutée.
Il s'agit juste d'une expression EL.
Le principe général d'une composition, c'est d'externaliser un ensemble (une composition) de composants déjà existants, et ensuite de les appeler dans d'autres pages. Par exemple, l'exemple donné sera appelé juste par :
Hum, c'est bizarre comme idée. Pourquoi faire cela ? J'ai un peu de mal à comprendre pourquoi par moment tu devrais afficher un datatable, d'autre fois un champ texte... Pourquoi ne pas faire des sous-pages qui seront affichées ou non selon certaines conditions.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 ... <myns:myColumnComponent label="Item description" fieldName="description" entity="#{myBean}"/> ...
Tu peux jouer avec l'attribut rendered pour t'aider. Un exemple:
Ce code dit ceci : Si l'attribut readOnly (getter isReadOnly du bean myBean) vaut true, alors c'est le composant outputText qui sera affiché. S'il faut false, alors ce sera le composant inputText qui sera affiché. Mais jamais les deux en même temps.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 ... <h:inputText value="" ... rendered="#{!myBean.isReadOnly}"/> <h:outputText value="#{myBean.value}" ... rendered="#{myBean.isReadOnly}"/> ...
Voici un exemple de composant créé en Java. En fait, de mon côté, je ne fais qu'étendre un composant qui existe déjà. Ca me facilite la tâche. Et généralement, les composants dont j'ai besoin ne sont que des composants déjà existants, mais avec un certain nombre de nouvelles fonctionnalités, ou alors avec un rendu différent.
Mon exemple ici c'est la possibilité de créer un bouton avec des bords arrondis . Du coup, j'étends le <h:commandButton>, mais je change un peu son rendu, pour construire un petit tableau dans lequel je mettrais mes images pour créer le rendu du bouton.
Voici l'objet Java:
La classe qui se charge de son rendu:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 package mypackage.component; import javax.faces.component.html.HtmlCommandButton; import javax.faces.context.FacesContext; import javax.faces.el.ValueBinding; public class MyHtmlButton extends HtmlCommandButton { private String buttonType; public String getButtonType() { if (buttonType != null) { return buttonType; } ValueBinding vb = getValueBinding("buttonType"); if (vb != null) { return (String) vb.getValue(getFacesContext()); } return null; } public void setButtonType(String buttonType) { this.buttonType = buttonType; } @Override public void restoreState(FacesContext context, Object state) { Object values[] = (Object[]) (Object[]) state; super.restoreState(context, values[0]); buttonType = (String) values[1]; } @Override public Object saveState(FacesContext context) { Object[] values = new Object[2]; values[0] = super.saveState(context); values[1] = buttonType; return (Object) values; } }
Ensuite, je me créé un fichier taglib (romain.taglib.xml) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 package mypackage.renderkit; import java.io.IOException; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import mypackage.MyComponentUtils; import com.sun.faces.renderkit.html_basic.ButtonRenderer; public class MyButtonRenderer extends ButtonRenderer { public OpmButtonRenderer() { super(); } @Override public void encodeBegin(FacesContext context, UIComponent component) throws IOException { ResponseWriter writer = context.getResponseWriter(); String buttonType = getButtonType(component); writer.startElement("table", null); writer.writeAttribute("border", "0", "table"); writer.writeAttribute("cellpadding", "0", "table"); writer.writeAttribute("cellspacing", "0", "table"); writer.startElement("tr", null); writer.startElement("td", null); writer.startElement("img", null); writer.writeAttribute("src", MyComponentUtils.getResourceUrl("images/button_" + buttonType + "_left.gif"), "img"); writer.endElement("img"); writer.endElement("td"); writer.startElement("td", null); component.getAttributes().put("styleClass", buttonType + "Button"); super.encodeBegin(context, component); } @Override public void encodeEnd(FacesContext context, UIComponent component) throws IOException { super.encodeEnd(context, component); ResponseWriter writer = context.getResponseWriter(); writer.endElement("td"); writer.startElement("td", null); writer.startElement("img", null); writer.writeAttribute("src", MyComponentUtils.getResourceUrl("images/button_" + getButtonType(component) + "_right.gif"), "img"); writer.endElement("img"); writer.endElement("td"); writer.endElement("tr"); writer.endElement("table"); } private String getButtonType(UIComponent component) { String type = (String) component.getAttributes().get("buttonType"); if ((type != null) && (type.equalsIgnoreCase("std") || type.equalsIgnoreCase("default"))) { return type.toLowerCase(); } return MyComponentUtils.DEFAULT_BUTTON_CSS_CLASS; } }
Je "lie" ces types aux classes Java dans le fichier faces-config.xml:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12<facelet-taglib> <namespace>http://romain/jsf</namespace> ... <tag> <tag-name>button</tag-name> <component> <component-type>my.component.button</component-type> <renderer-type>my.renderkit.button</renderer-type> </component> </tag> </facelet-taglib>
Maintenant, quand je veux appeler ce composant dans une page, je fais :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 <faces-config> ... <component> <component-type>my.component.button</component-type> <component-class>mypackage.MyHtmlButton</component-class> </component> <render-kit> <render-kit-id>HTML_BASIC</render-kit-id> <renderer> <component-family>javax.faces.Command</component-family> <renderer-type>my.renderkit.button</renderer-type> <renderer-class>mypackage.MyButtonRenderer</renderer-class> </renderer> </render-kit> </faces-config>
J'espère être clair :o)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 <a4j:page xmlns="http://www.w3.org/1999/xhtml" ... xmlns:romain="http://romain/jsf"> ... <romain:button .../> ... </a4j:page>
Nous sommes tous semblables, alors acceptons nos différences !
--------------------------------------------------------------
Liens : Blog | Page DVP | Twitter
Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
Critiques : Apache Maven
niquel
Lors de l'appel de ce composant,je ne vois pas trop les tags à mettre et que rajouter à la pace des ...
Dans mon cas, j'ai étendu le composant <h:commandButton/>.
J'ai donc à ma disposition toute la liste des attributs de ce composant. Tu peux les voir ici.
J'ai également ajouté à mon composant un attribut "buttonType", qui me permet en fait de définir la classe CSS qui sera utilisée pour le bouton.
Nous sommes tous semblables, alors acceptons nos différences !
--------------------------------------------------------------
Liens : Blog | Page DVP | Twitter
Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
Critiques : Apache Maven
Partager