<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>@Repository(&#34;djo&#34;) &#187; RichFaces</title>
	<atom:link href="https://blog.developpez.com/djo-mos/pcategory/java/jsf/richfaces/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/djo-mos</link>
	<description></description>
	<lastBuildDate>Sun, 27 Sep 2009 00:05:37 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Sortie de Richfaces 3.2</title>
		<link>https://blog.developpez.com/djo-mos/p5412/annonces/sortie_de_richfaces_3_2</link>
		<comments>https://blog.developpez.com/djo-mos/p5412/annonces/sortie_de_richfaces_3_2#comments</comments>
		<pubDate>Tue, 01 Apr 2008 12:41:51 +0000</pubDate>
		<dc:creator><![CDATA[djo.mos]]></dc:creator>
				<category><![CDATA[Annonces]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[RichFaces]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[La nouvelle version de JBoss Richfaces 3.2 est sortie apportant plus de 900 bugs corrigés ainsi que de nouvelles fonctionnalités (le tri/filtrage sur dataTable, l&#8217;EL côté client, colonnes dynamiques) et de nouveaux composants (composant d&#8217;upload de fichiers, des composants d&#8217;edition in-place, etc.) => Annonce => What is New => Live Demo]]></description>
				<content:encoded><![CDATA[<p>La nouvelle version de JBoss Richfaces 3.2 est sortie apportant plus de 900 bugs corrigés ainsi que de nouvelles fonctionnalités (le tri/filtrage sur dataTable, l&rsquo;EL côté client, colonnes dynamiques) et de nouveaux composants (composant d&rsquo;upload de fichiers, des composants d&rsquo;edition in-place, etc.)</p>
<p>=> <a href="http://labs.jboss.com/auth/jbossrichfaces/">Annonce</a><br />
=> <a href="http://labs.jboss.com/auth/wiki/RichFacesWhatIsNewIn3_2_0">What is New</a><br />
=> <a href="http://livedemo.exadel.com/richfaces-demo/richfaces/">Live Demo</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSF : the good, the bad and the ugly &#8230;</title>
		<link>https://blog.developpez.com/djo-mos/p5341/java/jsf_the_good_the_bad_and_the_ugly</link>
		<comments>https://blog.developpez.com/djo-mos/p5341/java/jsf_the_good_the_bad_and_the_ugly#comments</comments>
		<pubDate>Thu, 20 Mar 2008 22:12:18 +0000</pubDate>
		<dc:creator><![CDATA[djo.mos]]></dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[RichFaces]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Bonjour, Après avoir travaillé sur 3 applications JSF (faisant partie du même projet) ces 5 derniers mois, et maintenant que c&#8217;est fini (enfin, presque &#8230;), j&#8217;aimerais parler du the good, the bad and the ugly, bref, une sorte de retour d&#8217;expérience sur l&#8217;utilisation de JSF. Je vais commencer par the good. Les managed beans: là, c&#8217;est le bonheur. Du java pur et dur, on est libre de s&#8217;exprimer comme on veut (héritage/composition/délégation, etc.). Ajoutez Spring [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Bonjour,<br />
  Après avoir travaillé sur 3 applications JSF (faisant partie du même projet) ces 5 derniers mois, et maintenant que c&rsquo;est fini (enfin, presque &#8230;), j&rsquo;aimerais parler du <em>the good, the bad and the ugly</em>, bref, une sorte de retour d&rsquo;expérience sur l&rsquo;utilisation de JSF.<br />
<span id="more-18"></span><br />
  Je vais commencer par <em>the good</em>.</p>
<ul>
<li>Les managed beans: là, c&rsquo;est le bonheur. Du java pur et dur, on est libre de s&rsquo;exprimer comme on veut (héritage/composition/délégation, etc.). Ajoutez Spring dans l&rsquo;equation et on est proches de l&rsquo;orgasme cérébral !<br />
 Enfin, avec quelques limitations bien sûr (signature des actions, etc.).</li>
<li>Richfaces/Ajax4jsf: J&rsquo;en ai parlé à maintes reprises dans le forum, mais je tiens à en reparler ici: Impossible AMHA de battre Ajax4jsf comme moyen de faire de l&rsquo;ajax <strong>via une taglib</strong>. J&rsquo;ai bien dit pour une taglib car j&rsquo;ai vu comment on procède avec Wicket, et c&rsquo;est beaucoup plus puissant, mais c&rsquo;est normal car on passe par Java.</li>
<li>L&rsquo;approche composants: je ne suis pas spécialement doué en HTML/CSS, et n&rsquo;o n&rsquo;avait pas une personne pareille dans l&rsquo;équipe. C&rsquo;est pour cela que j&rsquo;ai énormément apprécié le fait qu&rsquo;avec quelques lignes XML pour décrire le composant dans la page JSF, j&rsquo;obtiens à l&rsquo;exécution des trucs à couper le souffle côté visuel (Merci Richfaces)
</li>
</ul>
<p>  Trois points seulement &#8230; mais c&rsquo;est déjà ça <img src="https://blog.developpez.com/djo-mos/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>Mais je pense que vous êtes nombreux à attendre l&rsquo;autre partie plutôt, <em>the bad and the ugly</em> <img src="https://blog.developpez.com/djo-mos/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<ul>
<li>Tooling: là, c&rsquo;est un véritable cauchemar. On est sous eclipse europa, qui offre quelques fonctionnalités d&rsquo;un IDE JSF, mais il en est encore loin &#8230; très loin. En fait, ça a tourné au vinaigre dès qu&rsquo;on ne fait plus du JSF de base (sans jeux de composants additionnels ni facelets ni Spring).<br />
Mais dès qu&rsquo;on essaies de faire quelque chose de puissant, eclipse nous a complètement laché.<br />
Il perd complètement les boules avec facelets, ce qui est tout simplement choquant, vu qu&rsquo;aucun développeur JSF sérieux n&rsquo;oserait faire sans facelets.<br />
D&rsquo;ailleurs, eclipse s&rsquo;est amélioré au fils des versions de maintenance (3.3.1.1 et 3.3.2), dans le sens où il accepte par exemple les pages xhtml dans l&rsquo;editeur des règles de navigation, chose qu&rsquo;il refusait avant, où qu&rsquo;il offre l&rsquo;auto-completion sur les jeux de composants standards (core et html) dans une page xhtml, mais il refuse de fonctionner pour facelets et tout autre jeu de composants.<br />
Exit l&rsquo;aspect IDE et nous revoilà à l&rsquo;époque de notepad, où on est censé taper des pages de quelques dizaines de lignes d&rsquo;XML sans se tromper dans le nom d&rsquo;un composant où d&rsquo;un attribut.</p>
<p>De plus, mais là c&rsquo;est vivable, si on fait gérer ses managed beans par Spring, eclipse ne peut plus faire de l&rsquo;auto-completion sur les ELs. D&rsquo;ailleurs, il ne le fait plus du moment qu&rsquo;on est dans une page xhtml et non pas JSP.</li>
<li>Ca figure dans la liste des bonnes chose, mais également ici: le fait qu&rsquo;on bosse sur les composants et que ça génère du HTML. J&rsquo;en ai vu des vertes et des pas mûres à cause de cela, et le pire que tu ne peux rien y faire: des liens qui ne marchent pas, générant des erreurs JavaScript, des inputs qui ne sont pas envoyés lors d&rsquo;un submit, des composant qui violent leur contrat, notamment les valueChangeListeners sur les inputText, etc.<br />
On se retrouvait alors obligés à faire de l&rsquo;acrobatie en essayant de contourner ces problèmes avec des solutions plus sordides l&rsquo;une que l&rsquo;autre.
</li>
<li>Je sais que ça devrait être résolu dans JSF 2.0, ou encore déjà avec Seam et RestFaces, mais l&rsquo;aspect fortement stateful de JSF peut vraiment devenir ennuyant, surtout si l&rsquo;application est destinés à un utilisateur non forcément informaticien. Vas lui expliquer qu&rsquo;il vaut mieux éviter le bouton retour du navigateur ou les F5 <img src="https://blog.developpez.com/djo-mos/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /> ou encore qu&rsquo;il doit suivre une séquence particulière dans les pages pour arriver au résultat, et qu&rsquo;il ne peut pas bookmarker des pages, etc.</li>
<li>Les maudits erreurs de &laquo;&nbsp;View has Expired&nbsp;&raquo;, et la gestion des erreurs en général qui est, et c&rsquo;est un doux euphémisme, exécrable.</li>
<li>Facelets: je l&rsquo;ai déjà dit à maintes occasions: JSF sans Facelets c&rsquo;est comme les oeufs avant la maîtrise du feu, mais la gestion/rapport d&rsquo;erreurs de facelets est parfois cryptique et n&rsquo;aide aucunement à leur localisation/correction.<br />
Par exemle, si dans un include on se trompe du nom du fichier à inclure, on obtient un beau 404 quand on essaie d&rsquo;accèder à la page mère au lieu d&rsquo;un message indiquant clairement l&rsquo;origine de l&rsquo;erreur&#8230; ainsi que dans d&rsquo;autre cas où on obtenait des messages d&rsquo;erreur cryptés sur 128 bits sans même le numéro de la ligne en cause.
</li>
<li>Difficile de faire quoi que soit d&rsquo;utile avec le scope request. On se retrouve obligé de passer au scope session.</li>
<li>Bouffeur de CPU: J&rsquo;en parle dans <a href="http://blog.developpez.com/index.php?blog=174&amp;title=qui_consomme_les_cycles_du_processeur_da&amp;more=1&amp;c=1&amp;tb=1&amp;pb=1">ce billet</a>.</li>
<li>Mais le point noir à mon avis est la difficulté sordide de la tache de développement de composants personnels &#8230; C&rsquo;est vrai que facelets essaies de simplifier ça, mais ça permet pas de développer de véritables composants personnels.</li>
</ul>
<p>Impressionnant cette liste, non ? En relisant ce billet, je sens que c&rsquo;est injuste pour JSF, car on a tout de même fait pas mal de trucs puissants avec, et ce en un temps record, ce qui est ne serait pas forcément la conclusion tirée par quelqu&rsquo;un lisant ce billet <img src="https://blog.developpez.com/djo-mos/wp-includes/images/smilies/icon_sad.gif" alt=":(" class="wp-smiley" /></p>
<p>Pour résumer et rectifier un peu le tir, je dirais qu&rsquo;avec JSF, on est pas loin de la règle de 80/20, mais que je transformerais en 80/60 au risque de casser sa beauté <img src="https://blog.developpez.com/djo-mos/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<ul>
<li>On fait 80% du boulot en 60% du temps attribué</li>
<li>Et on se retrouve à combattre les 20% restantes du boulant dans le 40% du temps restant</li>
</ul>
<p>Enfin, pour conclure, je ne suis aucunement en train de lancer une croisade contre JSF, loin de là même: JSF est toujours une option valable à envisager pour un nouveau projet. Seulement, comme tuotes les autres technos, JSF a ses défauts et un prix à payer.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Qui consomme les cycles du processeur dans une application web ?</title>
		<link>https://blog.developpez.com/djo-mos/p5083/java/qui_consomme_les_cycles_du_processeur_da</link>
		<comments>https://blog.developpez.com/djo-mos/p5083/java/qui_consomme_les_cycles_du_processeur_da#comments</comments>
		<pubDate>Tue, 12 Feb 2008 14:56:03 +0000</pubDate>
		<dc:creator><![CDATA[djo.mos]]></dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[RichFaces]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Sur l&#8217;application surlaquelle je travaille actuellement au boulot, j&#8217;ai été amené à réaliser quelques tests de profiling, histoire de débusquer les goulots d&#8217;étranglement et les optimiser (si possible). L&#8217;application en question est une application Web tournant sur Tomcat et qui utilise les technos suivantes: JSF: La Sun RI 1.2_07 (Mojarra) Richfaces 3.1.3 Facelets Spring framework 2.5.1: pour la DI et pour l&#8217;abstraction JDBC De nombreuses commons de jakarta (dbcp, pooling, collections, logging, etc.) Log4j MySQL [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Sur l&rsquo;application surlaquelle je travaille actuellement au boulot, j&rsquo;ai été amené à réaliser quelques tests de profiling, histoire de débusquer les goulots d&rsquo;étranglement et les optimiser (si possible).<br />
<span id="more-6"></span><br />
L&rsquo;application en question est une application Web tournant sur Tomcat et qui utilise les technos suivantes:</p>
<ul>
<li>JSF: La Sun RI 1.2_07 (Mojarra)</li>
<li>Richfaces 3.1.3</li>
<li>Facelets</li>
<li>Spring framework 2.5.1: pour la DI et pour l&rsquo;abstraction JDBC</li>
<li>De nombreuses commons de jakarta (dbcp, pooling, collections, logging, etc.)</li>
<li>Log4j</li>
<li>MySQL 5</li>
</ul>
<p>L&rsquo;IHM est assez complexe avec de l&rsquo;Ajax à gog, des images complexes générées dynamiquement, et bien sûr, pour combler le tout, le volume des données traitées est imposant.</p>
<p>Donc, avant de lancer les tests, j&rsquo;etais presque sûr que les goulots d&rsquo;étranglement etaient dans la couche DAO, la couche services (à cause de calculs complexes) et peut être aussi dans la génération dynamique des images.</p>
<p>Vous vous en doutez déjà, j&rsquo;avais complètement tort &#8230;<br />
Voici un extrait des résultats du profiling (temps d&rsquo;exécution) (réalisé avec TPTP):</p>
<p><img src="http://img339.imageshack.us/img339/8379/perfcd0.png" alt="Résultats du profiling" title="Résultats du profiling" /></p>
<p>Pour résumer, ou encore textuellement, ça donne:</p>
<ol>
<li>32% du temp processeur passé dans ajax4jsf, plus précisément dans le package component</li>
<li>28% du temp processeur passé dans Mojarra, plus précisément dans le package component</li>
<li>22% du temp processeur passé dans Richfaces, plus précisément dans le package component</li>
<li>Ensuite la couche JDBC ave 8%</li>
<li>3% dans la génération dynamique des images (notre propre code, enfin)</li>
</ol>
<p>Effrayant &#8230; 82% du temps processeur est consumé dans la couche présentation et est partagé par Mojarra, Richfaces et Ajax4jsf.<br />
La logique métier, aussi complexe soit elle, n&rsquo;apparait pas dans le top 10, donc consomme moins de 0.5% du temps processeur.<br />
Même la couche JDBC, le usual suspect dans les problèmes de performances ne s&rsquo;accapare que de 8% du gateau.</p>
<p>Il se peut que je refasses des tests vec MyFaces au lieu de Mojarra, car il est facile d&rsquo;interchanger les implémentations JSF.<br />
Par contre, il est trop tard pour ce qui est de Richfaces/Ajax4jsf.</p>
<p>Là, je me poses des questions &#8230; Est ce que ça vient de notre IHM complexe et/ou style de codage ou est ce que c&rsquo;est plutôt de la faute des librairies utilisées ?<br />
Et est ce spécifique à JSF ou est ce que ça touche d&rsquo;autres frameworks ?</p>
<p>N&rsquo;hésitez pas à faire part de vos propres expériences <img src="https://blog.developpez.com/djo-mos/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Drag&#8217;n&#8217;Drop avec RichFaces</title>
		<link>https://blog.developpez.com/djo-mos/p4589/java/drag_n_drop_avec_richfaces</link>
		<comments>https://blog.developpez.com/djo-mos/p4589/java/drag_n_drop_avec_richfaces#comments</comments>
		<pubDate>Tue, 27 Nov 2007 15:49:40 +0000</pubDate>
		<dc:creator><![CDATA[djo.mos]]></dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[RichFaces]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Bonjour. Voici encore un petit exemple avec RichFaces. Cette fois-ci, il s&#8217;agit de réaliser une petite application mettant en œuvre le drag and drop offert par RichFaces. C&#8217;est une simple application composée d&#8217;une seule page et qui simule l&#8217;activité d&#8217;achat en ligne: quelques articles et un panneau. Pour acheter un article, il suffit de le dragger et le dropper dans le panneau. Attaquons sans tarder la couche métier de notre application. On commence par les [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Bonjour.<br />
Voici encore un petit exemple avec <em>RichFaces</em>.<br />
Cette fois-ci, il s&rsquo;agit de réaliser une petite application mettant en œuvre le <em>drag and drop</em> offert par <em>RichFaces</em>.<br />
C&rsquo;est une simple application composée d&rsquo;une seule page et qui simule l&rsquo;activité d&rsquo;achat en ligne: quelques articles et un panneau. Pour acheter un article, il suffit de le <em>dragger</em> et le dropper dans le panneau.<br />
<span id="more-16"></span><br />
Attaquons sans tarder la couche métier de notre application.<br />
On commence par les entités (1 seul dans ce cas-ci):</p>
<ul>
<li>L&rsquo;objet Item représente un article. Il contient juste un identifiant, un nom et un prix.</li>
</ul>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">package model; <br />
&nbsp;<br />
public class Item { <br />
&nbsp; private String name; <br />
&nbsp; private Long price; <br />
&nbsp; private Long id; <br />
&nbsp;<br />
&nbsp; public Item() { <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public Item(String name, Long price) { <br />
&nbsp; &nbsp; this.name = name; <br />
&nbsp; &nbsp; this.price = price; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public String getName() { <br />
&nbsp; &nbsp; return name; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public void setName(String name) { <br />
&nbsp; &nbsp; this.name = name; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public Long getPrice() { <br />
&nbsp; &nbsp; return price; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public void setPrice(Long price) { <br />
&nbsp; &nbsp; this.price = price; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public Long getId() { <br />
&nbsp; &nbsp; return id; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public void setId(Long id) { <br />
&nbsp; &nbsp; this.id = id; <br />
&nbsp; } <br />
}</div></div>

</pre>
<p>Passons maintenant au contrôleurs JSF. On en a deux:</p>
<ul>
<li>ItemCtrl: Un simple <em>pojo</em> qui expose une liste d&rsquo;Items.</li>
<li>CartCtrl: Contient lui une liste d&rsquo;Items qui représente les articles achetés jusque là ainsi qu&rsquo;un champ price qui contient le prix total des articles achetés.<br />
      De plus, c&rsquo;est ce contrôleur qui gère l&rsquo;évènement drop généré lorsque l&rsquo;on dépose un article sur le panneau.</li>
</ul>
<p>Voici le code d&rsquo;<em>ItemCtrl</em></p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">package control; <br />
&nbsp;<br />
import java.util.ArrayList; <br />
import java.util.List; <br />
&nbsp;<br />
import model.Item; <br />
&nbsp;<br />
public class ItemsCtrl { <br />
&nbsp; private List&lt;item&gt; items = new ArrayList&lt;item&gt;(); <br />
&nbsp;<br />
&nbsp; public ItemsCtrl() { <br />
&nbsp; &nbsp; items.add(new Item(&quot;Montre&quot;, 50L)); <br />
&nbsp; &nbsp; items.add(new Item(&quot;Table&quot;, 450L)); <br />
&nbsp; &nbsp; items.add(new Item(&quot;Chaise&quot;, 150L)); <br />
&nbsp; &nbsp; items.add(new Item(&quot;Moquette&quot;, 250L)); <br />
&nbsp; &nbsp; items.add(new Item(&quot;Lit&quot;, 750L)); <br />
&nbsp; &nbsp; items.add(new Item(&quot;Armoire&quot;, 1050L)); <br />
&nbsp; &nbsp; items.add(new Item(&quot;Ordinateur&quot;, 750L)); <br />
&nbsp; &nbsp; items.add(new Item(&quot;Imprimante&quot;, 90L)); <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public List&lt;item&gt; getItems() { <br />
&nbsp; &nbsp; return items; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public void setItems(List&lt;item&gt; items) { <br />
&nbsp; &nbsp; this.items = items; <br />
&nbsp; } <br />
}</div></div>

</pre>
<p>Rien de spécial à dire à propos de cette classe <img src="https://blog.developpez.com/djo-mos/wp-includes/images/smilies/icon_wink.gif" alt=";-)" class="wp-smiley" /> (juste un détail, dans le constructeur, j&rsquo;ai ajouté quelques articles fictifs pour égayer un peu l&rsquo;application !)<br />
Maintenant, le code de <em>CartCtrl</em>:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">package control; <br />
&nbsp;<br />
import java.util.ArrayList; <br />
import java.util.List; <br />
import org.richfaces.event.DropEvent; <br />
&nbsp;<br />
import model.Item; <br />
&nbsp;<br />
public class CartCtrl { <br />
&nbsp; private List&lt;item&gt; items = new ArrayList&lt;item&gt;(); <br />
&nbsp; private Long price = 0L; <br />
&nbsp;<br />
&nbsp; public void onDropItem(DropEvent e) { <br />
&nbsp;<br />
&nbsp; &nbsp; Item i = (Item) e.getDragValue(); <br />
&nbsp; &nbsp; items.add(i); <br />
&nbsp; &nbsp; price += i.getPrice(); <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public List&lt;item&gt; getItems() { <br />
&nbsp; &nbsp; return items; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public void setItems(List&lt;item&gt; items) { <br />
&nbsp; &nbsp; this.items = items; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public Long getPrice() { <br />
&nbsp; &nbsp; return price; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public void setPrice(Long price) { <br />
&nbsp; &nbsp; this.price = price; <br />
&nbsp; } <br />
}</div></div>

</pre>
<p>Le seul point à expliquer ici est la méthode <em>onItemDrop</em>.<br />
Cette méthode ne retourne rien (<em>void</em>) et accepte un paramètre de type <em>org.richfaces.event.DropEvent</em><br />
qui contient toutes les informations relatives à un évènement <em>Drag and Drop</em>.<br />
En particulier, on a le champ <em>dragValue</em> (<em>Object</em>) qui contient l&rsquo;objet qu&rsquo;on a déplacé et lâché au dessus du panneau. Ici, c&rsquo;est un Item. Dès lors, on l&rsquo;ajoute à la liste des articles achetés et on incrémente le prix total des achats.</p>
<p>Passons maintenant à la couche présentation.<br />
Pour afficher la liste des articles, j&rsquo;ai décidé d&rsquo;utiliser le composant <em>DataGrid</em> de <em>RichFaces</em> qui ressemble au <em>DataTable</em> mais qui affiche les données exactement comme le composant <em>PanelGrid</em> de JSF:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;rich:dataGrid value=&quot;#{itemsCtrl.items}&quot; var=&quot;item&quot; columns=&quot;3&quot;&gt; <br />
&nbsp; &lt;h:panelGrid border=&quot;0&quot; columns=&quot;2&quot;&gt; <br />
&nbsp; &nbsp; &lt;h:outputText value=&quot;Nom: &quot; /&gt; <br />
&nbsp; &nbsp; &lt;h:outputText value=&quot;#{item.name}&quot; /&gt; <br />
&nbsp; &nbsp; &lt;h:outputText value=&quot;Prix: &quot; /&gt; <br />
&nbsp; &nbsp; &lt;h:outputText value=&quot;#{item.price}&quot; /&gt; <br />
&nbsp; &lt;/h:panelGrid&gt; <br />
&lt;/rich:dataGrid&gt;</div></div>

</pre>
<p>Voici ce que ça donne:</p>
<p><img src="http://blog.developpez.com/media/dataGrid.jpg" width="278" height="151" alt="Aperçu du résultat du composant DataGrid de RichFaces" /></p>
<p>On va maintenant rendre les éléments <em>draggables</em>. Pour ce faire, il suffit d&rsquo;ajouter le composant <em>dragSupport</em> de <em>RichFaces</em> dans chaque article. Comme le composant support d&rsquo;ajax4Jsf (présenté dans les posts précédents), ce composant ajouté le comportement <em>draggable</em> au composant qui le contient.</p>
<p>Dans notre cas, on va placer le <em>panelGrid</em> sur lequel on itère dans le composant <em>a4j:outputPanel</em> (dragSupport impose quelques limitations sur le conteneur, et il se trouve que <em>outputPanel</em> les satisfait). On ajoutera ensuite <em>dragSupport</em> dans le <em>outputPanel</em>, ce qui donne:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;rich:dataGrid value=&quot;#{itemsCtrl.items}&quot; var=&quot;item&quot; columns=&quot;3&quot;&gt; <br />
&nbsp; &lt;a4j:outputPanel layout=&quot;block&quot; style=&quot;cursor: move&quot;&gt; <br />
&nbsp; &nbsp; &lt;rich:dragSupport dragType=&quot;item&quot; dragValue=&quot;#{item}&quot; /&gt; <br />
&nbsp; &nbsp; &lt;h:panelGrid border=&quot;0&quot; columns=&quot;2&quot;&gt; <br />
&nbsp; &nbsp; &nbsp; &lt;h:outputText value=&quot;Nom: &quot; /&gt; <br />
&nbsp; &nbsp; &nbsp; &lt;h:outputText value=&quot;#{item.name}&quot; /&gt; <br />
&nbsp; &nbsp; &nbsp; &lt;h:outputText value=&quot;Prix: &quot; /&gt; <br />
&nbsp; &nbsp; &nbsp; &lt;h:outputText value=&quot;#{item.price}&quot; /&gt; <br />
&nbsp; &nbsp; &lt;/h:panelGrid&gt; <br />
&nbsp; &lt;/a4j:outputPanel&gt; <br />
&lt;/rich:dataGrid&gt;</div></div>

</pre>
<p>Comme principaux paramètres, dragSupport prend:</p>
<ul>
<li>dragType: une chaine qui identifie le type de l&rsquo;élément. C&rsquo;est surtout utile pour pouvoir discerner entre plusieurs types d&rsquo;éléments draggables. Ici, on en a qu&rsquo;un seul, et on le nomm item.</li>
<li>dragValue: la valeur de l&rsquo;élément draggé. C&rsquo;est cette valeur là qui sera récupéré dans <em>DropEvent.getDragValue</em> (cf plus haut). Ici, on met l&rsquo;Item courant.</li>
</ul>
<p>Reste maintenant à définir la zone de drop.<br />
Comme pour le drag, on définit une telle zone en incluant le composant <em>dropSupport</em>:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;a4j:outputPanel layout=&quot;block&quot;&gt; <br />
&nbsp; &lt;rich:dropSupport acceptedTypes=&quot;item&quot; dropListener=&quot;#{cartCtrl.onDropItem}&quot; <br />
&nbsp; &nbsp; &nbsp; reRender=&quot;boughtItems, totalPrice&quot; dropValue=&quot;x&quot; /&gt; <br />
&nbsp; &lt;h:graphicImage url=&quot;/pics/shopping_cart.png&quot; /&gt; <br />
&lt;/a4j:outputPanel&gt;</div></div>

</pre>
<p>En gros, il s&rsquo;agit d&rsquo;une image à l&rsquo;intérieur dans <em>outputPanel</em> pour les même raisons que pour le <em>dragSupport</em>).<br />
Les attributs de <em>dropSupport</em> sont:</p>
<ul>
<li>acceptedType: un liste de types d&rsquo;éléments acceptés par cette zone. Ici, on ne a qu&rsquo;un seul qui est item (cf attribut dragType du composant dragSupport).</li>
<li>dropListener: la méthode d&rsquo;un managed bean qui sera appelée lorsque le drag and drop est terminé (cf CartCtrl.onDropItem).</li>
<li>reRender: les identifiants des composants à re-dessiner à la réception de la réponse de la requête générée par le drop.</li>
</ul>
<p><strong>N.B: Il faut mettre les composants <em>dragSupport</em> (ainsi que ses parents) et <em>dropSupport</em> (ainsi que ses parents) dans un formulaire et dans le même formulaire !<br />
</strong><br />
Reste enfin à afficher les articles achetés ainsi que le prix total:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;rich:dataList id=&quot;boughtItems&quot; value=&quot;#{cartCtrl.items}&quot; var=&quot;item&quot;&gt; <br />
&nbsp; &lt;h:outputText value=&quot;#{item.name}&quot; /&gt; <br />
&nbsp; &lt;/rich:dataList&gt; <br />
&lt;h:outputText id=&quot;totalPrice&quot; value=&quot;Prix total: #{cartCtrl.price}&quot; /&gt;</div></div>

</pre>
<p>Voilou ! C&rsquo;est un peu long parce qu&rsquo;on est passé par un exemple plus ou moins réaliste et pratique, mais c&rsquo;est hyper-simple dans le fond !</p>
<p>Voici pour conclure un petit shot de l&rsquo;application:</p>
<p><img src="http://blog.developpez.com/media/dnd.jpg" width="275" height="320" alt="Screenshot de l'application drag and drop avec RichFaces"/></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Say Hello Version RichFaces</title>
		<link>https://blog.developpez.com/djo-mos/p4570/java/say_hello_version_richfaces</link>
		<comments>https://blog.developpez.com/djo-mos/p4570/java/say_hello_version_richfaces#comments</comments>
		<pubDate>Fri, 23 Nov 2007 10:15:47 +0000</pubDate>
		<dc:creator><![CDATA[djo.mos]]></dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[RichFaces]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Bonjour. Ce billet est une sorte d&#8217;introduction rapide au développement Ajax avec JSF via la bibliothèque JBoss RichFaces. Pour ce faire, je vous propose de réaliser étape par étape la célèbre application exemple SayHello. Cette application se contente de récupérer le nom entré par l&#8217;utilisateur pour ensuite le saluer (Hello $nom). Pour commencer, dans eclipse Europa + WTP 2.0.1, il faut créer un projet &#171;&#160;Dynamic Web Project&#160;&#187; en prensant soin d&#8217;inclure dans les librairies du [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Bonjour.<br />
Ce billet est une sorte d&rsquo;introduction rapide au développement Ajax avec JSF via la bibliothèque JBoss RichFaces.<br />
Pour ce faire, je vous propose de réaliser étape par étape la célèbre application exemple SayHello.<br />
Cette application se contente de récupérer le nom entré par l&rsquo;utilisateur pour ensuite le saluer (Hello $nom).<br />
<span id="more-14"></span><br />
Pour commencer, dans eclipse Europa + WTP 2.0.1, il faut créer un projet &laquo;&nbsp;Dynamic Web Project&nbsp;&raquo; en prensant soin d&rsquo;inclure dans les librairies du projet les 3 fichiers jars de Rich Faces 3.1.2 GA <a href="http://labs.jboss.com/jbossrichfaces/downloads/">téléchargeables ici</a>.<br />
Ajaxifier son application JSF avec RichFaces revient juste à ajouter ces 3 fichiers jars dans le classpath de l&rsquo;applciation (WEB-INF/lib) ainsi qu&rsquo;à modifier web.xml en ajoutant ces quelques lignes:<br />
(juste après l&rsquo;élément display-name).</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;filter&gt; <br />
&nbsp; &nbsp;&lt;display-name&gt;RichFaces Filter&lt;/display-name&gt; <br />
&nbsp; &nbsp;&lt;filter-name&gt;richfaces&lt;/filter-name&gt; <br />
&nbsp; &nbsp;&lt;filter-class&gt;org.ajax4jsf.Filter&lt;/filter-class&gt; <br />
&lt;/filter&gt; <br />
&lt;filter-mapping&gt; <br />
&nbsp; &nbsp;&lt;filter-name&gt;richfaces&lt;/filter-name&gt; <br />
&nbsp; &nbsp;&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt; <br />
&nbsp; &nbsp;&lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt; <br />
&nbsp; &nbsp;&lt;dispatcher&gt;FORWARD&lt;/dispatcher&gt; <br />
&nbsp; &nbsp;&lt;dispatcher&gt;INCLUDE&lt;/dispatcher&gt; <br />
&lt;/filter-mapping&gt;</div></div>

</pre>
<p>Attaquons maintenant le jeu. On commence par créer un simle POJO (le managed bean) qui servira à stocker le nom saisi par l&rsquo;utilisateur:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">public class HelloBean { <br />
&nbsp; &nbsp; &nbsp;private String name; <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp;public String getName() { <br />
&nbsp; &nbsp; &nbsp; &nbsp; return name; <br />
&nbsp; &nbsp; &nbsp;} <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp;public void setName(String name) { <br />
&nbsp; &nbsp; &nbsp; &nbsp; this.name = name; <br />
&nbsp; &nbsp; &nbsp;} <br />
}</div></div>

</pre>
<p>On déclare ensuite ce bean dans faces-config.xml pour qu&rsquo;il soit accessible depuis les pages JSF:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;managed-bean&gt; <br />
&nbsp; &nbsp; &nbsp;&lt;managed-bean-name&gt;helloBean&lt;/managed-bean-name&gt; <br />
&nbsp; &nbsp; &nbsp;&lt;managed-bean-class&gt;HelloBean&lt;/managed-bean-class&gt; <br />
&nbsp; &nbsp; &nbsp;&lt;managed-bean-scope&gt;request&lt;/managed-bean-scope&gt; <br />
&lt;/managed-bean&gt;</div></div>

</pre>
<p>On crée ensuite une première pages (index.jsp) qui se contente de &laquo;&nbsp;forwarder&nbsp;&raquo; vers la page JSF:</p>
<p>    <code class="codecolorer text default"><span class="text">&lt;jsp:forward page=&quot;hello.jsf&quot; /&gt;</span></code></p>
<p>Enfin, on arrive aux choses sérieuses: du JSF et de l&rsquo;AJAX. Dans la page hello.jsp, et à l&rsquo;intérieur de l&rsquo;élément view:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;h:outputText value=&quot;Name :&quot; /&gt; <br />
&lt;h:form&gt; <br />
&nbsp; &nbsp;&lt;h:inputText value=&quot;#{helloBean.name}&quot;&gt; <br />
&nbsp; &nbsp; &nbsp; &lt;a4j:support event=&quot;onchange&quot; reRender=&quot;greeting&quot; /&gt; <br />
&nbsp; &nbsp;&lt;/h:inputText&gt; <br />
&lt;/h:form&gt; <br />
&lt;h:outputText id=&quot;greeting&quot; value=&quot;Hello #{helloBean.name} !&quot; /&gt;</div></div>

</pre>
<p>Toute la magie de la chose est réalisée par le &lt;a4j:support&gt;. Il permet d&rsquo;ajaxifier n&rsquo;importe quel composant JSF standard. Ce composant est très flexible et a de nombreux usages, mais dans ce cas particulier, on l&rsquo;a utilisé pour capturer l&rsquo;évènement onchange (javascript), formuler une requête AJAX et redessiner le composant outputText (reRender=&nbsp;&raquo;greeting&nbsp;&raquo;) à la reception d&rsquo;une réponse à cette requête. C&rsquo;etait le comportement côté client. Côté serveur, RichFaces s&rsquo;occupe de décoder la requête AJAX, mettre à jour le champ &laquo;&nbsp;name&nbsp;&raquo; de notre managed bean et formuler la réponse.</p>
<p>C&rsquo;etait un aperçu rapide de la simplicité et la puissance de RichFaces.<br />
Comptez sur moi pour d&rsquo;autres exemples dans les prochains billets.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>GuessGame version RichFaces</title>
		<link>https://blog.developpez.com/djo-mos/p4576/java/guessgame_version_richfaces</link>
		<comments>https://blog.developpez.com/djo-mos/p4576/java/guessgame_version_richfaces#comments</comments>
		<pubDate>Fri, 23 Nov 2007 21:29:51 +0000</pubDate>
		<dc:creator><![CDATA[djo.mos]]></dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[RichFaces]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Bonjour. Dans ce billet, je vais présenter et expliquer les étapes de création du jeu GuessGame avec JSF et RichFaces. Je vous rappèle donc le principe du jeu: Au départ, l&#8217;application génère un nombre aléatoire entre 1 et 100. L&#8217;utilisateur essaie de deviner ce nombre à travers un textbox. à chaque essais, l&#8217;application vous informe si c&#8217;est trop grand, trop petit ou si c&#8217;est la bonne réponse. Sans plus tarder, attaquons la chose. N.B: Je [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Bonjour.<br />
 Dans ce billet, je vais présenter et expliquer les étapes de création du jeu GuessGame avec JSF et RichFaces.<br />
 Je vous rappèle donc le principe du jeu: Au départ, l&rsquo;application génère un nombre aléatoire entre 1 et 100. L&rsquo;utilisateur essaie de deviner ce nombre à travers un textbox. à chaque essais, l&rsquo;application vous informe si c&rsquo;est trop grand, trop petit ou si c&rsquo;est la bonne réponse.<br />
<span id="more-15"></span><br />
Sans plus tarder, attaquons la chose.<br />
<strong>N.B: Je vais passer l&rsquo;étape de configuration de RichFaces (<a href="http://blog.developpez.com/index.php?blog=174&amp;p=4570&amp;more=1&amp;c=1&amp;tb=1&amp;pb=1#more4570">voir post précédent</a>).</strong><br />
On commence par le backing bean de notre jeu qui va génerer le nombre aléatoire et ensuite vérifier les essais du joueur.:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">public class GameBean { <br />
&nbsp; private int magic; <br />
&nbsp; private Random random; <br />
&nbsp; private String guess; <br />
&nbsp; private String message; <br />
&nbsp;<br />
&nbsp; public GameBean() { <br />
&nbsp; &nbsp; random = new Random(); <br />
&nbsp; &nbsp; reset(); <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; private void reset() { <br />
&nbsp; &nbsp; magic = random.nextInt(100) + 1; <br />
&nbsp; &nbsp; guess = &quot;&quot;; <br />
&nbsp; &nbsp; message = &quot;...&quot;; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public String check() { <br />
&nbsp; &nbsp; int x = 0; <br />
&nbsp; &nbsp; try { <br />
&nbsp; &nbsp; &nbsp; &nbsp;x = Integer.parseInt(guess); <br />
&nbsp; &nbsp; &nbsp; &nbsp;if (x &lt; 1 || x &gt; 100) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;throw new Exception(); <br />
&nbsp; &nbsp; } catch (Exception e) { <br />
&nbsp; &nbsp; &nbsp; &nbsp;message = &quot;Entrée non valide&quot;; <br />
&nbsp; &nbsp; &nbsp; &nbsp;return null; <br />
&nbsp; &nbsp; } <br />
&nbsp;<br />
&nbsp; &nbsp; if (x &lt; magic) { <br />
&nbsp; &nbsp; &nbsp; &nbsp;message = &quot;Trop petit !&quot;; <br />
&nbsp; &nbsp; } else if (x &gt; magic) { <br />
&nbsp; &nbsp; &nbsp; &nbsp;message = &quot;Trop grand !&quot;; <br />
&nbsp; &nbsp; } else { <br />
&nbsp; &nbsp; &nbsp; &nbsp;message = &quot;Excellent ! Le nombre magique était &quot; + magic; <br />
&nbsp; &nbsp; } <br />
&nbsp; &nbsp; return null; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public int getMagic() { <br />
&nbsp; &nbsp; return magic; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public String getGuess() { <br />
&nbsp; &nbsp; return guess; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public void setGuess(String guess) { <br />
&nbsp; &nbsp; this.guess = guess; <br />
&nbsp; } <br />
&nbsp;<br />
&nbsp; public String getMessage() { <br />
&nbsp; &nbsp; return message; <br />
&nbsp; } <br />
}</div></div>

</pre>
<p>Voici rapidement de quoi il s&rsquo;agit:</p>
<ul>
<li>Le champ magic (int) va contenir le nombre à deviner.</li>
<li>Le champ random (<em>java.util.Random</em>) servira à générer les nombres aléatoires.</li>
<li>Le champ guess (String) servira à receuillir les essais de l&rsquo;utilisateur. Normalement, il devrait être de type int combiné avec un converter dans la page JSF, mais bon, j&rsquo;ai omis ça pour simplifier la chose.</li>
<li>Le champ message servira à contenir la réponse de l&rsquo;application suite à un essai du joueur (trop grand, trop petit, etc.)</li>
<li>La méthode privée reset() sera appelée à l&rsquo;initialisation du jeu pour générer le nombre aléatoire.</li>
<li>La méthode check() est une action JSF (type de retour String, sans paramètres) quis era appelé à chaque entrée utilisateur pour la vérifier.<br />
      <strong>N.B: check retourne toujours null, et ce pour rester dans la même page.</strong></li>
<li>Les méthodes restantes ne sont que des getters et des setters pour exposer nos champs à l&rsquo;EL (aux pages JSF).</li>
</ul>
<p>Passons maintenant à la partie présentation. Notre jeu tiendra dans une seule page.<br />
Normalement (sans Ajax), nous aurions déclaré dans <em><f:view ></em> un élément de type <em><h:form ></em> avec un inputText la dedans bindé avec notre <em>#{guessBean.guess}</em> ainsi qu&rsquo;un outputText bindé avec <em>#{guessBean.message}</em> qui affichera le résultat, un truc de ce genre:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;h:form&gt; <br />
&nbsp; &lt;h:inputText value=&quot;#{gameBean.guess}&quot; /&gt; <br />
&nbsp; &lt;h:outputText value=&quot;#{gameBean.message}&quot; /&gt; <br />
&nbsp; &lt;h:commandButton value=&quot;Check&quot; action=&quot;#{gameBean.check}&quot; /&gt; <br />
&lt;/h:form&gt;</div></div>

</pre>
<p>En cliquant sur le commandButton &laquo;&nbsp;check&nbsp;&raquo;, le formulaire sera envoyé et traité par JSF, ce qui implique entre autre que gameBean.guess se verra affecter la valeur entrée dans le champ texte. Ensuite, la méthode gameBean.check() à sera appelé qui va mettre dans le champ message le résultat de la vérification et retournera null. JSF retournera la main alors à la même page qui sera rendu à nouveau mais avec le message adéquat.</p>
<p>Nous allons maintenant ajaxifier la chose avec RichFaces (ou plus exactement avec Ajax4Jsf).<br />
Dans une première passe (et là, c&rsquo;est vraiment magique ;-)), on se contente de remplacer le composant form de JSF par celui d&rsquo;Ajax4Jsf, comme ça:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;a4j:form&gt; <br />
&nbsp; &lt;h:inputText value=&quot;#{gameBean.guess}&quot; /&gt; <br />
&nbsp; &lt;h:outputText value=&quot;#{gameBean.message}&quot; /&gt; <br />
&nbsp; &lt;h:commandButton value=&quot;Check&quot; action=&quot;#{gameBean.check}&quot; /&gt; <br />
&lt;/a4j:form&gt;</div></div>

</pre>
<p>N.B: l&rsquo;uri qu&rsquo;il faut importer pour utiliser les comosants a4j est: <em>http://richfaces.org/a4j</em></p>
<p>Relançons l&rsquo;application.<br />
A première vue rien ne se passe: suite à un clic sur le commandButton, absolument rien ne se passe &#8230; mais en fait si ! Pour s&rsquo;en convaincre, il suffit d&rsquo;ajouter un simple :<br />
<em>System.out.println(&laquo;&nbsp;check &laquo;&nbsp;+guess);</em><br />
au tout début de <em>GameBean.check()</em>.<br />
Réessayez de nouveau &#8230; et vous remarquerez que chaque fois que l&rsquo;on appuie sur le <em>commandButton</em>, une ligne telle que celle-ci s&rsquo;ajoute dans la console (d&rsquo;eclipse par exemple):</p>
<pre>
    check 45
    check 23
</pre>
<p>Explication ? <em><a4j:form></em> intercepte tout submit déclenché par un de ses fils (ici, le <em>commandButton</em>) et le traduit en requête ajax vers le serveur où elle sera traité.<br />
Mais alors, pourquoi le message ne change pas ?<br />
C&rsquo;est simple, il suffit d&rsquo;indiquer à <em><a4j:form></em> quels composants il faut re-dessiner à la reception d&rsquo;une réponse ajax. Ce comportement est plus qu&rsquo;il y&rsquo;a de naturel, autrement, on devrait re-dessiner tout faute de savoir qu&rsquo;est ce qui a changé, ce qui revient à un submit http classsique et non plus Ajax.<br />
Notre code devient donc:</p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;a4j:form reRender=&quot;out&quot; &gt; <br />
&nbsp; &lt;h:inputText value=&quot;#{gameBean.guess}&quot; /&gt; <br />
&nbsp; &lt;h:outputText value=&quot;#{gameBean.message}&quot; id=&quot;out&quot; /&gt; <br />
&nbsp; &lt;h:commandButton value=&quot;Check&quot; action=&quot;#{gameBean.check}&quot; /&gt; <br />
&lt;/a4j:form&gt;</div></div>

</pre>
<p>J&rsquo;ai ajouté :</p>
<ul>
<li>l&rsquo;attribut reRender=&nbsp;&raquo;out&nbsp;&raquo; dans &lt;a4j:form&gt;</li>
<li>L&rsquo;attribut id=&nbsp;&raquo;out&nbsp;&raquo; dans &lt;h:outputText&gt;</li>
</ul>
<p>Ce qui tout naturellement veut dire &laquo;&nbsp;re-dessiner le composant dans l&rsquo;identifiant est out à la reception d&rsquo;une réponse ajax&nbsp;&raquo;.<br />
<strong>N.B: reRender n&rsquo;est pas limité à un seul identifiant, et peut prendre une liste d&rsquo;attributs à re-dessiner, comme par exemple reRender=&nbsp;&raquo;out, x, y, z&nbsp;&raquo;.</strong></p>
<p>En relançant l&rsquo;application avec ces modifications, on aura notre guess-game version AJAX !<br />
Pour approfondir la chose, vous pouvez essayer d&rsquo;ajouter un compteur trials qui indique au fur et à mesure combien d&rsquo;essaies le joueur a fait + un bouton rejouer qui ne s&rsquo;affiche que lorsque la réponse est bonne (le second point, je vous le dis d&rsquo;avance, est un casse-gueule <img src="https://blog.developpez.com/djo-mos/wp-includes/images/smilies/icon_smile.gif" alt=":-)" class="wp-smiley" /> &#8230; j&rsquo;expliquerais pourquoi dans un prochain post).</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
