<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Piwaï</title>
	<atom:link href="http://blog.piwai.info/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.piwai.info</link>
	<description>Honni soit qui mal y code</description>
	<lastBuildDate>Tue, 27 Dec 2011 09:24:34 +0000</lastBuildDate>
	<language>fr</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.piwai.info' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/3d59c087a30aed75a59598e39e250588?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Piwaï</title>
		<link>http://blog.piwai.info</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.piwai.info/osd.xml" title="Piwaï" />
	<atom:link rel='hub' href='http://blog.piwai.info/?pushpress=hub'/>
		<item>
		<title>Paris Android Dev Lab</title>
		<link>http://blog.piwai.info/2011/11/06/paris-android-dev-lab/</link>
		<comments>http://blog.piwai.info/2011/11/06/paris-android-dev-lab/#comments</comments>
		<pubDate>Sun, 06 Nov 2011 18:03:59 +0000</pubDate>
		<dc:creator>Piwaï</dc:creator>
				<category><![CDATA[J'y étais]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[dev lab]]></category>
		<category><![CDATA[fragment]]></category>
		<category><![CDATA[galaxy tab]]></category>
		<category><![CDATA[paug]]></category>
		<category><![CDATA[tablette]]></category>

		<guid isPermaLink="false">http://blog.piwai.info/?p=428</guid>
		<description><![CDATA[Introduction Un Android Developer Labs (ADL) s&#8217;est déroulé à Paris jeudi 27 et vendredi 28 octobre 2011, traitant de l&#8217;optimisation des applications Android pour les tablettes. J&#8217;ai eu la chance d&#8217;être invité à cet évènement ; j&#8217;en ai donc profité pour prendre des notes afin de pouvoir retranscrire le déroulement de cette journée (l&#8217;ADL du [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=428&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Un <a href="http://android-developers.blogspot.com/2011/08/android-developer-labs-2011.html">Android Developer Labs</a> (ADL) s&#8217;est déroulé à Paris jeudi 27 et vendredi 28 octobre 2011, traitant de l&#8217;<strong>optimisation</strong> des applications <strong>Android</strong> pour les <strong>tablettes</strong>.</p>
<p>J&#8217;ai eu la chance d&#8217;être invité à cet évènement ; j&#8217;en ai donc profité pour prendre des notes afin de pouvoir retranscrire le déroulement de cette journée (l&#8217;ADL du vendredi).</p>
<p><span id="more-428"></span></p>
<h2>Apéro Android</h2>
<p>Avant tout, laissez-moi vous parler de l&#8217;<a href="http://www.paug.fr/2011/10/apero-android-le-27-octobre-avec-les.html">apéro Android</a>. Sachant que les places pour l&#8217;ADL étaient limitées, le Paris Android User Group (<a href="http://www.paug.fr/">PAUG</a>) a organisé un <strong>apéro Android</strong> le jeudi soir, pour permettre à tous de discuter et de rencontrer les <em>Android Developer Advocates</em>.</p>
<p><img src="http://piwai.files.wordpress.com/2011/10/aperoandroid.png?w=914" alt="" title="aperoandroid"   class="aligncenter size-full wp-image-429" /></p>
<p>Les Googlers sont très ouverts et abordables, et nous avons passé une soirée sympatique, en partie aux frais de <a href="http://www.frandroid.com/">FrAndroid</a>. Je vous conseille vivement ce type de rencontre ; c&#8217;est un bon moyen d&#8217;apprendre et de rencontrer des gens intéressants tout en passant un bon moment.</p>
<p><a href="http://code.google.com/p/androidannotations/"><img src="http://piwai.files.wordpress.com/2011/11/logo.png?w=914" alt="" title="logo"   class="alignleft size-full wp-image-462" /></a></p>
<p>Au cours de la soirée, j&#8217;ai eu le plaisir de constater que deux <em>Android Developer Advocates</em> (<a href="https://plus.google.com/118292708268361843293/posts">Nick Butcher</a> et <a href="https://plus.google.com/115995639636688350464/posts">Richard Hyndman</a>) connaissaient <a href="http://code.google.com/p/androidannotations/">AndroidAnnotations</a>, suite au <a href="http://uk.droidcon.com/programme/day-2#kaeppler-development">talk</a> de <a href="http://twitter.com/twoofour">Matthias Kaeppler</a> à la <strong>DroidCon</strong> 2011.</p>
<h2>L&#8217;ADL</h2>
<p>Le programme de la journée était le suivant : </p>
<ul>
<li>Introduction aux tablettes</li>
<li>Quoi de neuf dans Ice Cream Sandwich</li>
<li>Android Market pour développeurs</li>
<li>Développer pour téléphones et tablettes</li>
<li>Codelab</li>
</ul>
<p>J&#8217;ai pris des notes du mieux possible ; j&#8217;espère que vous me saurez gré des lacunes éventuelles et de la faible mise en forme.</p>
<h3>Introduction aux tablettes</h3>
<p>Cette présentation fut consacrée aux spécificités liées à <strong>Honeycomb</strong> et au développement pour <strong>tablettes</strong>.</p>
<p>Notez qu&#8217;Honeycomb est uniquement orienté tablette : l&#8217;équipe Android n&#8217;avait pas le temps de réaliser un OS pour téléphones en parallèle.</p>
<h4>System bar</h4>
<p>Auparavant, les informations système et les notifications étaient situées dans une barre <strong>en haut</strong> de l&#8217;écran.</p>
<p><img src="http://piwai.files.wordpress.com/2011/11/top_bar.png?w=914" alt="" title="top_bar"   class="aligncenter size-full wp-image-443" /></p>
<p>Désormais, cette barre se situe <strong>en bas</strong> de l&#8217;écran, et contient en outre les boutons de <strong>navigation</strong>. Cela permet de se débarrasser des boutons <strong>physiques</strong>, qui étaient mal placés lorsque l&#8217;on passait en <strong>mode paysage</strong>.</p>
<p><img src="http://piwai.files.wordpress.com/2011/11/bottom_bar.png?w=914" alt="" title="bottom_bar"   class="aligncenter size-full wp-image-444" /></p>
<p>Les <strong>notifications</strong> sont désormais accessibles sans couvrir totalement l&#8217;écran, de même qu&#8217;un certain nombre de <strong>réglages</strong> et <strong>informations</strong> bien pratiques.</p>
<p><img src="http://piwai.files.wordpress.com/2011/11/bottom_bar_notif.png?w=914" alt="" title="bottom_bar_notif"   class="aligncenter size-full wp-image-445" /></p>
<p>Cette barre peut distraire l&#8217;<strong>attention visuelle</strong> lorsque vous souhaitez une <strong>expérience immersive</strong>. Il est possible de la <strong>cacher</strong> en utilisant le code suivant :</p>
<p><pre class="brush: java;">
mView.setSystemUiVisibility(View.STATUS_BAR_HIDDEN)
</pre><br />
<em>Note : je me demande bien pourquoi cette méthode n&#8217;est pas statique et appartient à View ; si vous avez une idée, n&#8217;hésitez pas à commenter.<br />
</em></p>
<p>Dans le screenshot suivant, comme vous le voyez, la barre ne disparaît <strong>pas totalement</strong>. Elle devient noire, mais les icônes sont remplacés par des points gris <strong>toujours cliquables</strong>. </p>
<p><img src="http://piwai.files.wordpress.com/2011/11/bottom_bar_dark.png?w=914" alt="" title="bottom_bar_dark"   class="aligncenter size-full wp-image-446" /><br />
<em>Note : ce screenshot montre le dernier niveau de <a href="https://market.android.com/details?id=com.robotinvader.knightmare">Wind-up Knight</a>, un <strong>jeu sympa</strong> qui est un bon exemple de l&#8217;efficacité du paiement <strong>in-app</strong> (la preuve, je n&#8217;ai pas résisté et ce fût l&#8217;occasion de réaliser mon premier paiement in-app).</em></p>
<h4>Action bar</h4>
<p>Vous souvenez-vous d&#8217;Android 1.X, où la barre de titre occupait une place énorme qui ne servait à rien ?</p>
<p><img src="http://piwai.files.wordpress.com/2011/11/title_1_5.png?w=914" alt="" title="title_1_5"   class="aligncenter size-full wp-image-450" /></p>
<p>Autant utiliser cet espace !</p>
<p>C&#8217;est le principe de l&#8217;<strong>action bar</strong>. Celle-ci comporte tout d&#8217;abord une <strong>icône cliquable</strong> qui permet de retourner à tout moment à l&#8217;<strong>écran d&#8217;accueil</strong>.Elle affiche ensuite des éléments liés à la <strong>navigation</strong>, et pour finir des <strong>icônes d&#8217;action</strong>.</p>
<p>Cette <strong>action bar</strong> n&#8217;est pas nécessairement un composant Android, il s&#8217;agit plutôt d&#8217;un <strong>design pattern</strong> de <strong>UI</strong>, que toute application Android digne de ce nom devrait respecter.</p>
<p>Le projet <strong>ActionBarCompat</strong>, disponible dans les samples depuis <strong>ADT 14</strong>, met à disposition tout le code et les ressources nécessaires à la création d&#8217;une action bar fonctionnant sur toutes les versions d&#8217;Android.</p>
<div id="attachment_451" class="wp-caption aligncenter" style="width: 490px"><img src="http://piwai.files.wordpress.com/2011/11/action_bar_compat.png?w=914" alt="" title="action_bar_compat"   class="size-full wp-image-451" /><p class="wp-caption-text">ActionBarCompat sur mon Nexus One (Gingerbread)</p></div>
<p>Les <strong>menu items</strong> dans l&#8217;<strong>Options Menu</strong> peuvent être rendus disponibles dans les boutons d&#8217;action. Il suffit juste d&#8217;ajouter l&#8217;attribut suivant aux items dans votre <strong>menu.xml</strong> :</p>
<p><pre class="brush: xml;">
    android:showAsAction=&quot;ifRoom|withText&quot;;
</pre></p>
<h4>Les fragments</h4>
<p>Sans trop rentrer dans les détails : les fragments sont des composants de UI, réutilisables. L&#8217;utilisation de Fragment permet de repenser la UI, il ne suffit plus de se contenter d&#8217;avoir un design fluide qui s&#8217;élargit par rapport à la taille de l&#8217;écran, il faut organiser les fragments différents suivant l&#8217;écran et la place disponible.</p>
<p>Pour être tout à fait honnête, je ne suis qu&#8217;à moitié convaincu par ce nouveau système de fragment. Le principe reste proche de celui des activités : il s&#8217;agit d&#8217;un <strong>controller</strong>, chargé d&#8217;<strong>orchestrer</strong> le <strong>code métier</strong> lié à un assemblage de composants graphiques (des <strong>View</strong>).</p>
<p><img src="http://piwai.files.wordpress.com/2011/11/fragment.png?w=914" alt="" title="fragment"   class="aligncenter size-full wp-image-474" /></p>
<p>En soit, ce n&#8217;est pas une mauvaise idée. Par contre, on se retrouve encore avec un <strong>modèle par héritage</strong>, comme pour les <strong>activités</strong>. Tout fragment doit hériter de <strong>Fragment</strong>. Il existe un <strong>ListFragment</strong>, un <strong>XXXFragment</strong>, etc, qui tous héritent de <strong>Fragment</strong>.</p>
<p>Le problème, c&#8217;est que dès lors que l&#8217;on souhaite factoriser du code commun à plusieurs Fragments, il va falloir recréer une sous classe pour chacun des types de Fragment. <strong>AbstractCustomFragment</strong>, <strong>AbstractCustomListFragment</strong>, etc. Et évidemment, si deux frameworks s&#8217;amusent à créer leurs propres fragments à étendre, il devient compliqué de les combiner.</p>
<p><img src="http://piwai.files.wordpress.com/2011/11/fragment_inheritance.png?w=914&#038;h=145" alt="" title="fragment_inheritance" width="914" height="145" class="aligncenter size-full wp-image-475" /></p>
<p>Pour faire un parallèle, j&#8217;ai l&#8217;impression que l&#8217;équipe Android persiste à proposer des <strong>servlets</strong>, quand il serait bien plus utile de proposer des <strong>controllers</strong> Spring.</p>
<p>A bien y réfléchir, une <strong>Activity</strong> et un <strong>Fragment</strong> ont ceci de commun qu&#8217;ils répondent à des <strong>évènements</strong> (principe des <strong>callbacks</strong> type <strong>onCreate()</strong>), qu&#8217;ils renvoient des éléments de configuration (e.g. getLastNonConfigurationInstance()), et qu&#8217;ils fournissent des helpers (<strong>getLoaderManager()</strong>, <strong>getPreferences()</strong>, etc).</p>
<p>Pour moi, ces différentes responsabilités devraient appartenir à différents composants.</p>
<h4>Les Loaders</h4>
<p>Les <a href="http://developer.android.com/guide/topics/fundamentals/loaders.html">Loaders</a> sont un nouveau moyen pour récupérer des données en tâche de fond, en gérant convenablement les problématiques liées au cycle de vie des composants Android.</p>
<div id="attachment_484" class="wp-caption aligncenter" style="width: 650px"><a href="http://commons.wikimedia.org/wiki/File:Samsung_loader.JPEG"><img src="http://piwai.files.wordpress.com/2011/11/640px-samsung_loader.jpeg?w=914" alt="" title="640px-Samsung_loader"   class="size-full wp-image-484" /></a><p class="wp-caption-text">Samsung loader, by A1C Beatrice Cassetty, U.S. Air Force (public domain)</p></div>
<p>C&#8217;est une alternative très intéressante à l&#8217;<a href="http://developer.android.com/reference/android/os/AsyncTask.html">AsyncTask</a>, qui malgré plusieurs bonnes idées souffre de quelques problèmes :</p>
<ul>
<li>Pas de gestion du cycle de vie (activité mise en pause, détruite définitivement, détruite mais pour raison de changement de configuration, etc)</li>
<li>Pas facile à utiliser : le paramètre générique PARAM n&#8217;est pas vraiment utile (en plus, c&#8217;est une <strong>vararg</strong>, quelle horreur !), il n&#8217;y a pas de gestion des exceptions.</li>
</ul>
<p>A noter qu&#8217;un des premiers risques avec les <strong>AsyncTask</strong>, c&#8217;est d&#8217;en faire des classes anonymes et de leaker des références vers leur <strong>outer class</strong>, qui est bien souvent une <strong>activité</strong>.</p>
<p>Et pour simplifier votre code de gestion des Threads sur Android, pourquoi ne pas essayer <a href="http://code.google.com/p/androidannotations/wiki/WorkingWithThreads">@Background et @UiThread</a> sur <a href="http://code.google.com/p/androidannotations">AndroidAnnotations</a> ?</p>
<h4>hardwareAccelerated</h4>
<p>Pensez à activer le flag suivant dans votre manifest :</p>
<p><pre class="brush: xml;">
android:hardwareAccelerated=&quot;true&quot;
</pre></p>
<p>Cela permet de bénéficier de l&#8217;accélération matérielle pour le rendering, gratos. Il est désactivé par défaut car certaines implémentations dessinant via des canvas peuvent ralentir ou faire crasher votre appli.</p>
<p>Ce n&#8217;est normalement pas le cas des composants standards. Comment décider s&#8217;il faut l&#8217;utiliser ? C&#8217;est simple :</p>
<ul>
<li>Activez <strong>hardwareAccelerated</strong></li>
<li>Testez votre application sur Honeycomb. Si elle ne plante pas, c&#8217;est bon, vous pouvez dormir tranquille!</li>
</ul>
<h4>Renderscript</h4>
<p><a href="http://developer.android.com/guide/topics/renderscript/index.html">Renderscript</a> est une <em>nouvelle</em> API C permettant de faire du <strong>3D rendering</strong> haute performance. Nouvelle&#8230; pas tant que ça! Si j&#8217;ai bonne mémoire, <a href="https://plus.google.com/111962077049890418486/">Romain Guy</a> nous présentait déjà Renderscript au précédent Android Dev Lab, il y a de cela deux ans. Bon, il est vrai que l&#8217;API n&#8217;a probablement plus rien à voir (initialement, ça n&#8217;était même pas du C), seul le concept reste identique.</p>
<p>Les applications <strong>Google Books</strong> et <strong>YouTube</strong> utilisent renderscript : Google Books pour <strong>tourner les pages</strong>, et YouTube pour l&#8217;écran avec toutes les vidéos visibles en même temps.</p>
<p><img src="http://piwai.files.wordpress.com/2011/11/youtube.png?w=914" alt="" title="youtube"   class="aligncenter size-full wp-image-486" /></p>
<h4>Développement pour tablettes, quelques règles simples</h4>
<ul>
<li>Mesurer en <a href="http://developer.android.com/guide/practices/screens_support.html#density-independence">dp</a> plutôt qu&#8217;en pixels</li>
<li>Utiliser des layouts extensibles</li>
<li>Centraliser les dimensions dans <strong>dimens.xml</strong>, de façon à pouvoir les overrider grâce au mécanisme de ressources</li>
<li>Supporter le mode paysage et ne pas bloquer en mode portrait. N&#8217;oubliez pas que la manière d&#8217;utiliser une tablette est essentiellement en paysage. Beaucoup d&#8217;application ont un écran de chargement de l&#8217;application en portrait, ce n&#8217;est pas très malin !</li>
</ul>
<h4>Mettre à jour votre application pour Honeycomb</h4>
<ul>
<li>Ajoutez des graphiques pour les hautes résolutions (<strong>xhdpi</strong>)</li>
<li>Utilisez des fragments, même pour les anciennes versions d&#8217;Android (grâce à la <a href="http://developer.android.com/sdk/compatibility-library.html">compatibility library</a>)</li>
<li>N&#8217;oubliez pas d&#8217;ajouter <code>&lt;uses-sdk android:targetSdkVersion="14" /&gt;</code> dans votre manifest, notamment pour bénéficier automatique de la nouvelle Action bar sur Honeycomb</li>
</ul>
<p>Voilà qui conclu la première moitié de ce compte rendu sur l&#8217;Android Dev Lab, je vous conterai la fin de cette journée lors du prochain article.</p>
<br />Classé dans:<a href='http://blog.piwai.info/category/jy-etais/'>J'y étais</a> Tagged: <a href='http://blog.piwai.info/tag/android/'>android</a>, <a href='http://blog.piwai.info/tag/dev-lab/'>dev lab</a>, <a href='http://blog.piwai.info/tag/fragment/'>fragment</a>, <a href='http://blog.piwai.info/tag/galaxy-tab/'>galaxy tab</a>, <a href='http://blog.piwai.info/tag/paug/'>paug</a>, <a href='http://blog.piwai.info/tag/tablette/'>tablette</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/piwai.wordpress.com/428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/piwai.wordpress.com/428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/piwai.wordpress.com/428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/piwai.wordpress.com/428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/piwai.wordpress.com/428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/piwai.wordpress.com/428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/piwai.wordpress.com/428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/piwai.wordpress.com/428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/piwai.wordpress.com/428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/piwai.wordpress.com/428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/piwai.wordpress.com/428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/piwai.wordpress.com/428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/piwai.wordpress.com/428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/piwai.wordpress.com/428/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=428&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piwai.info/2011/11/06/paris-android-dev-lab/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/06c6a07275076c6b525e2b14018ad78e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pyricau</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/aperoandroid.png" medium="image">
			<media:title type="html">aperoandroid</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/11/logo.png" medium="image">
			<media:title type="html">logo</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/11/top_bar.png" medium="image">
			<media:title type="html">top_bar</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/11/bottom_bar.png" medium="image">
			<media:title type="html">bottom_bar</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/11/bottom_bar_notif.png" medium="image">
			<media:title type="html">bottom_bar_notif</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/11/bottom_bar_dark.png" medium="image">
			<media:title type="html">bottom_bar_dark</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/11/title_1_5.png" medium="image">
			<media:title type="html">title_1_5</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/11/action_bar_compat.png" medium="image">
			<media:title type="html">action_bar_compat</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/11/fragment.png" medium="image">
			<media:title type="html">fragment</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/11/fragment_inheritance.png" medium="image">
			<media:title type="html">fragment_inheritance</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/11/640px-samsung_loader.jpeg" medium="image">
			<media:title type="html">640px-Samsung_loader</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/11/youtube.png" medium="image">
			<media:title type="html">youtube</media:title>
		</media:content>
	</item>
		<item>
		<title>Coup de balai : déblayer les branches d&#8217;un repo Git</title>
		<link>http://blog.piwai.info/2011/10/30/coup-de-balai-deblayer-les-branches-dun-repo-git/</link>
		<comments>http://blog.piwai.info/2011/10/30/coup-de-balai-deblayer-les-branches-dun-repo-git/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 21:30:34 +0000</pubDate>
		<dc:creator>Piwaï</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[branches]]></category>
		<category><![CDATA[cleaning]]></category>
		<category><![CDATA[feature branch]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://blog.piwai.info/?p=338</guid>
		<description><![CDATA[Comme je vous l&#8217;indiquais dans un précédent article, chez Siine, nous hébergeons nos projets sur GitHub, et chaque User Story fait l’objet d’une branche dédiée. Lorsqu&#8217;une branche qui a fait l&#8217;objet d&#8217;une pull request est validée, elle est mergée sur la branche d&#8217;intégration. Nous n&#8217;avons cependant pas pris l&#8217;habitude de supprimer ces branches une fois [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=338&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Comme je vous l&#8217;indiquais dans un <a href="http://blog.piwai.info/2011/10/14/tas-mis-a-jour-les-specs/">précédent article</a>, chez <a href="http://www.siine.com/">Siine</a>, nous hébergeons nos projets sur <a href="http://github.com/">GitHub</a>, et chaque User Story fait l’objet d’une <a href="http://blog.piwai.info/2011/10/09/roooh-jai-encore-oublie-ma-branche-git/">branche dédiée</a>.</p>
<p>Lorsqu&#8217;une <strong>branche</strong> qui a fait l&#8217;objet d&#8217;une <strong>pull request</strong> est validée, elle est <strong>mergée</strong> sur la branche d&#8217;intégration. Nous n&#8217;avons cependant pas pris l&#8217;habitude de <strong>supprimer</strong> ces branches une fois mergées. Je pense que nous aurions probablement du les supprimer au fur et à mesure, car nous nous retrouvons aujourd&#8217;hui avec de <strong>nombreuses branches mergées</strong>, qui ne servent à rien et qui <strong>polluent</strong> nos repository.</p>
<div id="attachment_435" class="wp-caption aligncenter" style="width: 464px"><a href="http://commons.wikimedia.org/wiki/File:Branches_konary.jpg"><img src="http://piwai.files.wordpress.com/2011/10/454px-branches_konary.jpg?w=914" alt="" title="454px-Branches_konary"   class="size-full wp-image-435" /></a><p class="wp-caption-text">Branches konary by Krzysztof</p></div>
<p><span id="more-338"></span><br />
Notez que GitHub conserve <strong>l&#8217;historique</strong> des pull request même quand les branches sont supprimées. Je ne vois vraiment aucune raison de conserver des branches mergées. Et vous ?</p>
<p>Quoi qu&#8217;il en soit, il est tout à fait possible de corriger cela, en quelques <strong>commandes</strong> <strong>Git</strong> bien senties. </p>
<p>On récupère toutes les données du <strong>repository remote</strong><br />
<pre class="brush: bash;">
git fetch --all
</pre></p>
<p>On supprime de notre <strong>repository local</strong> toutes les branches remote qui n&#8217;existent plus<br />
<pre class="brush: bash;">
git remote prune origin
</pre></p>
<div id="attachment_437" class="wp-caption aligncenter" style="width: 370px"><a href="http://commons.wikimedia.org/wiki/File:Valor_prune.jpg"><img src="http://piwai.files.wordpress.com/2011/10/360px-valor_prune.jpg?w=914" alt="" title="360px-Valor_prune"   class="size-full wp-image-437" /></a><p class="wp-caption-text">Valor prune by Glysiak</p></div>
<p>On compte toutes les <strong>branches remote mergées </strong>:<br />
<pre class="brush: bash;">
git branch -r --merged origin/integration | wc -l
</pre><br />
Le paramètre <code>-r</code> signifie <strong>remote</strong>, et <code>--merged origin/integration</code> permet de lister les branches mergées dans <strong>origin/integration</strong>.</p>
<p>Vous l&#8217;aurez noté, <code>wc -l</code> est une commande Unix permettant de compter le <strong>nombre de lignes</strong> du flux d&#8217;entrée. Ainsi, on pourrait l&#8217;utiliser pour compter le <strong>nombre de branches</strong> du repository remote :<br />
<pre class="brush: bash;">
git branch -r | wc -l
</pre></p>
<p>Il n&#8217;y a plus qu&#8217;à <strong>supprimer les branches mergées</strong> :</p>
<p><pre class="brush: bash;">
# Supprimer la branche sur le remote
git push origin :my_branch
# Et supprimer la branche qui la track en local
git branch -d my_branch
</pre></p>
<p>Notez aussi que GitHub met à disposition ce listing sans avoir à entrer une seule ligne de commande, en cliquant sur <a href="https://github.com/pyricau/FunkyJFunctional/branches">Branches</a>.</p>
<p><img src="http://piwai.files.wordpress.com/2011/10/capture-d_c3a9cran-2011-10-30-c3a0-23-16-37.png?w=914&#038;h=246" alt="" title="branches" width="914" height="246" class="aligncenter size-full wp-image-433" /></p>
<p>Pour finir : si lister les branches mergées permet de faire le ménage, à l&#8217;inverse il peut être intéressant de prendre connaissance des <strong>branches non mergées</strong>, car il se peut que certaines d&#8217;entre elles aient été oubliées et soient à <strong>l&#8217;abandon</strong>. Pour cela, rien de plus simple :<br />
<pre class="brush: bash;">
git branch -r --no-merged origin/integration
</pre></p>
<br />Classé dans:<a href='http://blog.piwai.info/category/tech/'>Tech</a> Tagged: <a href='http://blog.piwai.info/tag/branches/'>branches</a>, <a href='http://blog.piwai.info/tag/cleaning/'>cleaning</a>, <a href='http://blog.piwai.info/tag/feature-branch/'>feature branch</a>, <a href='http://blog.piwai.info/tag/git/'>git</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/piwai.wordpress.com/338/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/piwai.wordpress.com/338/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/piwai.wordpress.com/338/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/piwai.wordpress.com/338/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/piwai.wordpress.com/338/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/piwai.wordpress.com/338/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/piwai.wordpress.com/338/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/piwai.wordpress.com/338/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/piwai.wordpress.com/338/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/piwai.wordpress.com/338/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/piwai.wordpress.com/338/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/piwai.wordpress.com/338/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/piwai.wordpress.com/338/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/piwai.wordpress.com/338/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=338&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piwai.info/2011/10/30/coup-de-balai-deblayer-les-branches-dun-repo-git/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/06c6a07275076c6b525e2b14018ad78e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pyricau</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/454px-branches_konary.jpg" medium="image">
			<media:title type="html">454px-Branches_konary</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/360px-valor_prune.jpg" medium="image">
			<media:title type="html">360px-Valor_prune</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/capture-d_c3a9cran-2011-10-30-c3a0-23-16-37.png" medium="image">
			<media:title type="html">branches</media:title>
		</media:content>
	</item>
		<item>
		<title>Sexy dialogs, huhu</title>
		<link>http://blog.piwai.info/2011/10/23/sexy-dialogs-huhu/</link>
		<comments>http://blog.piwai.info/2011/10/23/sexy-dialogs-huhu/#comments</comments>
		<pubDate>Sun, 23 Oct 2011 18:58:00 +0000</pubDate>
		<dc:creator>Piwaï</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[dialog]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[layout]]></category>
		<category><![CDATA[textview]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://blog.piwai.info/?p=387</guid>
		<description><![CDATA[Introduction On reproche souvent aux applications Android d&#8217;être&#8230; moches. Et ce serait la faute du framework Android, qui fournirait des composants qui n&#8217;ont pas la Apple sexy touch. Peut-être est-ce le cas, mais faudrait voir à ne pas être trop paresseux. Prenons le cas des boîtes de dialogue. A priori, il n&#8217;y a rien de [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=387&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>On reproche souvent aux <strong>applications Android</strong> d&#8217;être&#8230; <strong>moches</strong>. Et ce serait la faute du framework Android, qui fournirait des composants qui n&#8217;ont pas la <em>Apple sexy touch</em>. Peut-être est-ce le cas, mais faudrait voir à ne pas être trop <strong>paresseux</strong>.</p>
<p>Prenons le cas des <strong>boîtes de dialogue</strong>. A priori, il n&#8217;y a rien de plus <strong>ennuyeux</strong>, et rien ne ressemble plus à une boîte de dialogue&#8230; qu&#8217;une autre boîte de dialogue. Sauf si vous décidez de changer leur style graphique, ce qui risque d&#8217;une part de perdre vos utilisateurs, et d&#8217;autre part de vous demander du boulot.</p>
<p>Je vous propose d&#8217;aborder quelques techniques simples pour donner <strong>un peu de vie</strong> à vos <strong>boîtes de dialogues</strong>, sans trop vous fatiguer.<br />
<span id="more-387"></span></p>
<h2>Dialogue fadasse</h2>
<p>Voici un exemple classique de boîte de dialogue :</p>
<p><pre class="brush: java;">
new AlertDialog.Builder(this)
		.setMessage(&quot;Un message pas sexy&quot;)
		.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				// Do something
			}
		})
		.show();
</pre><br />
<em>Je préfère créer et gérer manuellement mes boîtes de dialogue plutôt qu&#8217;utiliser <code>showDialog()</code> et <code>onCreateDialog()</code>, que je n&#8217;ai jamais réussi à utiliser correctement dès que les cas d&#8217;utilisation se corsent.</em></p>
<p><img src="http://piwai.files.wordpress.com/2011/10/pas_sexy.png?w=914" alt="" title="pas_sexy"   class="aligncenter size-full wp-image-399" /></p>
<h2>Une vue custom</h2>
<p>Je vous propose de personnaliser le message affiché par notre boîte de dialogue. Plutôt que <code>setMessage()</code>, il suffit d&#8217;appeller <code>setView()</code>, qui prend en paramètre n&#8217;importe quel type de <code>View</code>.</p>
<p>Par exemple une <code>TextView</code>, définie ici dans un <code>layout</code> :<br />
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;TextView
    xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:layout_width=&quot;fill_parent&quot; 
    android:layout_height=&quot;wrap_content&quot; 
    android:textSize=&quot;30sp&quot;
    android:padding=&quot;20dp&quot;
    /&gt;
</pre><br />
<em>Petit rappel, vos layouts xml n&#8217;ont <strong>aucune raison</strong> de commencer systématiquement par un <code>LinearLayout</code> ou un <code>RelativeLayout</code>.</em></p>
<p>Ensuite, il suffit de gonfler (<em>inflate</em> <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ) ce <code>layout</code>, et de le définir comme vue de la boîte de dialogue :<br />
<pre class="brush: java;">
TextView messageView = (TextView) View.inflate(this, R.layout.dialog, null);
messageView.setText(&quot;Un message à peine plus sexy&quot;);

new AlertDialog.Builder(this) //
		.setView(messageView) //
		.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// Do something
			}
		}) //
		.show();
</pre><br />
<em>Notez l&#8217;utilisation de <code>View.inflate()</code>, plutôt que <code>LayoutInflater.from(context).inflate()</code>, ou encore <strong>pire</strong>, <code>((LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate()</code></em></p>
<p>Et voilà le travail :<br />
<img src="http://piwai.files.wordpress.com/2011/10/sexy1.png?w=914" alt="" title="sexy1"   class="aligncenter size-full wp-image-403" /></p>
<h2>Un peu de style</h2>
<p>Dans un <a href="http://blog.piwai.info/2011/10/01/un-peu-de-style-dans-la-textview/">précédent article</a>, nous avons découvert <code>Html.fromHtml()</code> qui se marie très bien avec une <code>TextView</code>. Mettons-le à profit :</p>
<p><pre class="brush: java;">
TextView messageView = (TextView) View.inflate(this, R.layout.dialog, null);
CharSequence message = Html.fromHtml(&quot;I like &lt;b&gt;sexy&lt;/b&gt; &lt;font color=\&quot;#42dd42\&quot;&gt;turtles&lt;/font&gt;!&quot;);
messageView.setText(message);
</pre></p>
<p><img src="http://piwai.files.wordpress.com/2011/10/sexy2.png?w=914" alt="" title="sexy2"   class="aligncenter size-full wp-image-404" /></p>
<p>Évidemment, c&#8217;est mieux avec l&#8217;i18n, ajoutons donc une entrée à <strong>strings.xml</strong> :</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;resources&gt;
    &lt;!-- ... --&gt;
    &lt;string name=&quot;dialog_message&quot;&gt;&lt;![CDATA[I like &lt;b&gt;sexy&lt;/b&gt; &lt;font color=&quot;#42dd42&quot;&gt;turtles&lt;/font&gt;!&quot;]]&gt;&lt;/string&gt;
&lt;/resources&gt;
</pre></p>
<p>Et notre code devient :</p>
<p><pre class="brush: java;">
CharSequence message = Html.fromHtml(getString(R.string.dialog_message));
</pre></p>
<h2>Et avec une photo sexy ?</h2>
<p>Saviez-vous que <code>Html.fromHtml()</code> supporte la balise <code>img</code>, et permet de charger des images locales, grâce à un <a href="http://developer.android.com/reference/android/text/Html.ImageGetter.html">ImageGetter</a> ? </p>
<p>Ajoutons une image à notre message :</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;resources&gt;
    &lt;!-- ... --&gt;
    &lt;string name=&quot;dialog_message&quot;&gt;&lt;![CDATA[I like &lt;img src=&quot;turtle&quot; /&gt; &lt;b&gt;sexy&lt;/b&gt; &lt;font color=\&quot;#42dd42\&quot;&gt;turtles&lt;/font&gt;!&quot;]]&gt;&lt;/string&gt;
&lt;/resources&gt;
</pre></p>
<p>Ainsi que la <strong>ressource</strong> correspondante :</p>
<p><img src="http://piwai.files.wordpress.com/2011/10/turtle_res.png?w=914" alt="" title="turtle_res"   class="aligncenter size-full wp-image-405" /></p>
<p>Il n&#8217;y a plus qu&#8217;à créer un <code>ImageGetter</code> qui sait charger un <code>Drawable</code> à partir de son <strong>nom</strong> de ressource :</p>
<p><pre class="brush: java;">
ImageGetter imageGetter = new ImageGetter() {
	@Override
	public Drawable getDrawable(String source) {
		String name = source.replace(&quot;/&quot;, &quot;&quot;);
		Resources resources = getResources();
		int drawableId = resources.getIdentifier(name, &quot;drawable&quot;, getPackageName());
		if (drawableId != 0) {
			Drawable drawable = resources.getDrawable(drawableId);
			drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
			return drawable;
		} else {
			return null;
		}
	}
};

CharSequence message = Html.fromHtml(getString(R.string.dialog_message), imageGetter, null);
</pre></p>
<p>Et le tour est joué :</p>
<div id="attachment_402" class="wp-caption aligncenter" style="width: 490px"><a href="http://commons.wikimedia.org/wiki/File:Trachemys_scripta_elegans.JPG"><img src="http://piwai.files.wordpress.com/2011/10/sexy3.png?w=914" alt="" title="sexy3"   class="size-full wp-image-402" /></a><p class="wp-caption-text">turtle&#039;s head by Betta.1</p></div>
<h2>Conclusion</h2>
<p>Ces quelques lignes de code permettent de <strong>rapidement</strong> mettre en avant les <strong>informations importantes</strong> au sein d&#8217;une <strong>boîte de dialogue</strong>, sans pour autant <strong>déstabiliser</strong> l&#8217;utilisateur.</p>
<p>Bien entendu, <strong>l&#8217;abus</strong> de boîte de dialogues est <strong>dangereux</strong> pour la santé mentale des utilisateurs, à afficher avec <strong>modération</strong> !</p>
<br />Classé dans:<a href='http://blog.piwai.info/category/tech/'>Tech</a> Tagged: <a href='http://blog.piwai.info/tag/android/'>android</a>, <a href='http://blog.piwai.info/tag/dialog/'>dialog</a>, <a href='http://blog.piwai.info/tag/html/'>html</a>, <a href='http://blog.piwai.info/tag/java/'>java</a>, <a href='http://blog.piwai.info/tag/layout/'>layout</a>, <a href='http://blog.piwai.info/tag/textview/'>textview</a>, <a href='http://blog.piwai.info/tag/ui/'>ui</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/piwai.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/piwai.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/piwai.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/piwai.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/piwai.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/piwai.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/piwai.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/piwai.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/piwai.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/piwai.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/piwai.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/piwai.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/piwai.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/piwai.wordpress.com/387/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=387&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piwai.info/2011/10/23/sexy-dialogs-huhu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/06c6a07275076c6b525e2b14018ad78e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pyricau</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/pas_sexy.png" medium="image">
			<media:title type="html">pas_sexy</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/sexy1.png" medium="image">
			<media:title type="html">sexy1</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/sexy2.png" medium="image">
			<media:title type="html">sexy2</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/turtle_res.png" medium="image">
			<media:title type="html">turtle_res</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/sexy3.png" medium="image">
			<media:title type="html">sexy3</media:title>
		</media:content>
	</item>
		<item>
		<title>T&#8217;as mis à jour les specs ?</title>
		<link>http://blog.piwai.info/2011/10/14/tas-mis-a-jour-les-specs/</link>
		<comments>http://blog.piwai.info/2011/10/14/tas-mis-a-jour-les-specs/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 18:49:18 +0000</pubDate>
		<dc:creator>Piwaï</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[branch]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[documents]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[spec]]></category>

		<guid isPermaLink="false">http://blog.piwai.info/?p=298</guid>
		<description><![CDATA[Introduction Il est généralement admis qu&#8217;utiliser un système de gestion de version (décentralisé de préférence) pour le code d&#8217;un projet est une bonne chose. Mais qu&#8217;en est-il des documents de spécifications fonctionnelles et techniques ? Loin de l&#8217;approche monolithique du cycle en V, les adeptes des méthodes agiles ont à coeur de faire évoluer ces [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=298&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Il est généralement admis qu&#8217;utiliser un système de <strong>gestion de version</strong> (<strong>décentralisé</strong> de préférence) pour le <strong>code</strong> d&#8217;un projet est une <strong>bonne chose</strong>.</p>
<p>Mais qu&#8217;en est-il des documents de <strong>spécifications</strong> fonctionnelles et techniques ? Loin de l&#8217;approche monolithique du cycle en V, les adeptes des <strong>méthodes agiles</strong> ont à coeur de <strong>faire évoluer</strong> ces documents très fréquemment. D&#8217;aucuns pourraient penser que les posts-it de Scrum remplacent avantageusement tout document de spécification&#8230;</p>
<div id="attachment_367" class="wp-caption aligncenter" style="width: 650px"><a href="https://secure.wikimedia.org/wikipedia/commons/wiki/File:Archaeological_post-it_label_-_geograph.org.uk_-_1303183.jpg"><img src="http://piwai.files.wordpress.com/2011/10/archaeological_post-it_label_-_geograph-org-uk_-_1303183.jpg?w=914" alt="" title="Archaeological_post-it_label_-_geograph.org.uk_-_1303183"   class="size-full wp-image-367" /></a><p class="wp-caption-text">Archaeological post-it label by Evelyn Simak</p></div>
<p><span id="more-298"></span></p>
<h2>Versionner les spécifications</h2>
<p>N&#8217;oubliez pas, <em>être agile</em> ne constitue pas une excuse pour ne pas écrire de documentation. Pareil pour le <a href="http://en.wikipedia.org/wiki/Emergent_Design">design émergeant</a>. Bien au contraire, il est d&#8217;autant plus important de consigner et conserver le savoir fonctionnel et technique.</p>
<div id="attachment_365" class="wp-caption aligncenter" style="width: 650px"><a href="https://secure.wikimedia.org/wikipedia/commons/wiki/File:SteacieLibrary.jpg"><img src="http://piwai.files.wordpress.com/2011/10/640px-steacielibrary.jpg?w=914" alt="" title="640px-SteacieLibrary"   class="size-full wp-image-365" /></a><p class="wp-caption-text">Steacie Science and Engineering Library at York University, by Raysonho@Open Grid Scheduler</p></div>
<p>Vous qui posez un tag sur votre code dans votre système de gestion de version (VCS) lors d&#8217;une nouvelle release, êtes-vous capables de retrouver <strong>plus tard</strong> les spécifications fonctionnelles et techniques correspondant à cette release ?</p>
<p><img src="http://piwai.files.wordpress.com/2011/10/git_tag.png?w=914" alt="" title="git tab"   class="aligncenter size-full wp-image-363" /></p>
<p>Un moyen simple pour y parvenir est d&#8217;héberger ces documents dans le <strong>même VCS que le code</strong>. Ainsi, tout tag/branche contiendra automatiquement la bonne version des spécifications.</p>
<h2>Diff de specs ?</h2>
<p>Allons plus loin : un VCS n&#8217;a pas pour seul but de conserver l&#8217;<strong>historique d&#8217;un projet</strong> ; il permet aussi d&#8217;appréhender les <strong>changements</strong> réalisés, grâce aux outils de <strong>diff</strong>. C&#8217;est évidemment essentiel pour assembler le travail parallèle des différents développeurs, pour comprendre l&#8217;origine d&#8217;un bug, pour toute revue de code, etc.</p>
<p>Le problème des outils de diff est qu&#8217;ils fonctionnent très bien pour tout ce qui est <strong>textuel</strong>, et beaucoup moins bien lorsqu&#8217;ils ont affaire à des fichiers <strong>binaires</strong>. Malheureusement, les <strong>documents de spécifications</strong> sont bien souvent des fichiers <strong>Word</strong> ou <strong>LibreOffice</strong>, qui entrent dans cette catégorie.</p>
<p>Il existe pourtant un format textuel tout à fait adapté: <a href="http://fr.wikipedia.org/wiki/Markdown">Markdown</a>. La syntaxe de ce langage est réellement accessible, même pour les membres non techniques de votre équipe :</p>
<p><pre class="brush: plain;">
# Titre du document
## Mon sous titre

Un paragraphe contenant un [lien absolu](http://www.google.com), un
[lien relatif](../autrePage), et une ![image](image.png).

* une liste à puces
* avec une sous liste
  * contenant un élément *en italique*
  * et un élément **en gras**
</pre></p>
<p>De plus, les documents Markdown peuvent aisément être visualisés en HTML ou PDF, si vous ne disposez pas d&#8217;un <a href="http://mouapp.com/">éditeur dédié</a>. Il existe même <a href="http://freewisdom.org/projects/python-markdown/odt2txt">des scripts</a> pour convertir de l&#8217;ODT en Markdown.</p>
<p><a href="http://www.canalplus.fr/c-divertissement/pid3848-c-bref.html?tab=1">Bref</a>, vous n&#8217;avez aucune excuse valable <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> .</p>
<h2>Retour d&#8217;expérience</h2>
<p>Chez <a href="http://www.siine.com">Siine</a>, nous hébergeons nos projets sur <a href="http://github.com">GitHub</a>, et chaque <strong>User Story</strong> fait l&#8217;objet d&#8217;une <a href="http://blog.piwai.info/2011/10/09/roooh-jai-encore-oublie-ma-branche-git/">branche dédiée</a>.</p>
<p>Les <strong>spécifications</strong> fonctionnelles et techniques relatives à une User Story sont écrites en <strong>Markdown</strong>, sur la <strong>branche dédiée</strong> à cette User Story. </p>
<p>Lorsque la <strong>User Story</strong> est prête à être intégrée sur la branche de développement, le développeur crée une <a href="http://help.github.com/send-pull-requests/">pull request</a>. Il suffit alors d&#8217;ouvrir l&#8217;onglet <strong>Diff</strong> de la pull request pour tout de suite identifier les <strong>changements</strong> fonctionnels et techniques introduits par cette User Story.</p>
<p><img src="http://piwai.files.wordpress.com/2011/10/spec_diff.png?w=914&#038;h=295" alt="" title="Spec Diff" width="914" height="295" class="aligncenter size-full wp-image-361" /></p>
<h2>Diagrammes</h2>
<p>Tous les <strong>fichiers binaires</strong> ne peuvent pas forcément être remplacés par des fichiers <strong>textuels</strong> ; c&#8217;est le cas des <strong>diagrammes techniques</strong>.</p>
<p>A moins que&#8230; en êtes-vous si sûr ?</p>
<p><a href="http://websequencediagrams.com">websequencediagrams.com</a> et <a href="http://yuml.me">yuml.me</a> vous proposent d&#8217;exprimer le contenu de vos diagrammes sous forme de texte, et se chargent de générer l&#8217;image correspondante.</p>
<h3>websequencediagrams</h3>
<p><strong>websequencediagrams</strong> permet de générer des diagrammes de séquence, et offre même le luxe de choisir le style utilisé.</p>
<p><pre class="brush: plain;">
UI-&gt;StuffManager: doSomeStuff()
note over StuffManager: HandlesStuff
activate StuffManager
StuffManager-&gt;DataStore:gimmeDaStuff()
activate DataStore
DataStore-&gt;StuffManager:
deactivate DataStore
StuffManager-&gt;DataStore:updateDaStuff()
activate DataStore
DataStore-&gt;StuffManager:
deactivate DataStore
StuffManager--&gt;UI:
deactivate StuffManager
</pre></p>
<p><a href="http://www.websequencediagrams.com/?lz=VUktPlN0dWZmTWFuYWdlcjogZG9Tb21lAA8FKCkKbm90ZSBvdmVyIAAYDkhhbmRsZXMANgUKYWN0aXZhdGUAFw0KAEsMLT5EYXRhU3RvcmU6Z2ltbWVEYQBaCAA0CQAZCQoAIwkAgQ0PCmRlABsTAFAYdXBkYXQAEFktPlVJAIEEDQCCOgw&amp;s=qsd"><img src="http://piwai.files.wordpress.com/2011/10/websequencediagrams1.png?w=914" alt="" title="websequencediagrams"   class="aligncenter size-full wp-image-359" /></a></p>
<h3>yUML</h3>
<p><strong>yUML</strong> permet de générer des diagrammes UML de <a href="http://yuml.me/diagram/class/draw">classe</a>, d&#8217;<a href="http://yuml.me/diagram/activity/draw">activité</a>, et de <a href="http://yuml.me/diagram/usecase/draw">cas d&#8217;utilisation</a>.</p>
<p><pre class="brush: plain;">
[Activity]^[MyActivity]
[MyActivity]-[note: I like turtles!]
[Step]^[FirstStep]
[Step]^[SecondStep]
[Step]^[FinalStep]
[MyActivity]++-&gt;[StateHolder]
[MyActivity]++-*&gt;[Step]
[FirstStep]+-&gt;[StateHolder]
[SecondStep]+-&gt;[StateHolder]
</pre></p>
<p><a href="http://yuml.me/diagram/class/[Activity]^[MyActivity], [MyActivity]-[note: I like turtles!], [Step]^[FirstStep], [Step]^[SecondStep], [Step]^[FinalStep], [MyActivity]++-&gt;[StateHolder], [MyActivity]++-*&gt;[Step], [FirstStep]+-&gt;[StateHolder], [SecondStep]+-&gt;[StateHolder]."><img src="http://piwai.files.wordpress.com/2011/10/yuml_class.png?w=914" alt="" title="yUML class"   class="aligncenter size-full wp-image-355" /></a></p>
<p>Connaissez-vous d&#8217;autres outils bien pratiques de ce type ?</p>
<br />Classé dans:<a href='http://blog.piwai.info/category/tech/'>Tech</a> Tagged: <a href='http://blog.piwai.info/tag/agile/'>agile</a>, <a href='http://blog.piwai.info/tag/branch/'>branch</a>, <a href='http://blog.piwai.info/tag/design/'>design</a>, <a href='http://blog.piwai.info/tag/documents/'>documents</a>, <a href='http://blog.piwai.info/tag/git/'>git</a>, <a href='http://blog.piwai.info/tag/markdown/'>markdown</a>, <a href='http://blog.piwai.info/tag/spec/'>spec</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/piwai.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/piwai.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/piwai.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/piwai.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/piwai.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/piwai.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/piwai.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/piwai.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/piwai.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/piwai.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/piwai.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/piwai.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/piwai.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/piwai.wordpress.com/298/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=298&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piwai.info/2011/10/14/tas-mis-a-jour-les-specs/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/06c6a07275076c6b525e2b14018ad78e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pyricau</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/archaeological_post-it_label_-_geograph-org-uk_-_1303183.jpg" medium="image">
			<media:title type="html">Archaeological_post-it_label_-_geograph.org.uk_-_1303183</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/640px-steacielibrary.jpg" medium="image">
			<media:title type="html">640px-SteacieLibrary</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/git_tag.png" medium="image">
			<media:title type="html">git tab</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/spec_diff.png" medium="image">
			<media:title type="html">Spec Diff</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/websequencediagrams1.png" medium="image">
			<media:title type="html">websequencediagrams</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/yuml_class.png" medium="image">
			<media:title type="html">yUML class</media:title>
		</media:content>
	</item>
		<item>
		<title>Roooh, j&#8217;ai encore oublié ma branche Git !</title>
		<link>http://blog.piwai.info/2011/10/09/roooh-jai-encore-oublie-ma-branche-git/</link>
		<comments>http://blog.piwai.info/2011/10/09/roooh-jai-encore-oublie-ma-branche-git/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 06:15:31 +0000</pubDate>
		<dc:creator>Piwaï</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[branch]]></category>
		<category><![CDATA[branche]]></category>
		<category><![CDATA[feature branch]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[pull request]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://blog.piwai.info/?p=303</guid>
		<description><![CDATA[Introduction La startup pour laquelle je bosse depuis peu héberge son code source sur GitHub, et ça, c&#8217;est carrément cool. En plus, nous sommes récemment passé d&#8217;un workflow old school (tout le monde commit comme des sauvages sur la même branche) à un workflow de type feature branching. Encore plus cool ! Le merge d&#8217;une [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=303&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>La <strong>startup</strong> pour laquelle je bosse <a href="http://blog.piwai.info/2011/08/31/whenpiwai-quitexcilys-thenreturnnew-blog/">depuis peu</a> héberge son <strong>code source</strong> sur <a href="http://github.com">GitHub</a>, et ça, c&#8217;est carrément cool.</p>
<p>En plus, nous sommes récemment passé d&#8217;un <strong>workflow</strong> old school (tout le monde commit comme des sauvages sur la même branche) à un workflow de type <a href="http://nvie.com/posts/a-successful-git-branching-model">feature branching</a>. Encore plus cool !<br />
<span id="more-303"></span></p>
<p>Le merge d&#8217;une <strong>feature branch</strong> sur la branche d&#8217;<strong>intégration</strong> ne se fait qu&#8217;après <strong>validation</strong> (revue de code et tests fonctionnels) par quelqu&#8217;un qui n&#8217;a pas développé la feature. Dans cette optique, les <a href="http://help.github.com/send-pull-requests/">pull requests</a> de GitHub se révèlent particulièrement pratiques.</p>
<p><img class="aligncenter size-full wp-image-311" title="Pull Request" src="http://piwai.files.wordpress.com/2011/10/pull_request.png?w=914&#038;h=638" alt="" width="914" height="638" /></p>
<p>Mais trêve de bavardage, venons-en à l&#8217;objet de cet article.</p>
<h2>Roooh, j&#8217;ai encore oublié ma branche Git !</h2>
<p>Avec le <strong>feature branching</strong>, on se retrouve à changer fréquemment de branche.</p>
<p>Du coup, j&#8217;ai tendance à ne plus savoir sur <strong>quelle branche je me trouve</strong>, ou encore à oublier le nom précis de la branche, et à taper <code>git branch</code> toutes les trois commandes.</p>
<p>Un membre de l&#8217;équipe nous a envoyé un <strong>script</strong> plutôt pratique, qui ajoute le <strong>nom de la branche</strong> en cours au prompt de votre terminal :</p>
<p><img class="aligncenter size-full wp-image-314" title="Terminal" src="http://piwai.files.wordpress.com/2011/10/terminal.png?w=914" alt=""   /></p>
<p>Le petit truc cool en plus, c&#8217;est que le nom s&#8217;affiche en <span style="color:#ff0000;"><strong>rouge</strong></span> si vous avez des <strong>modifications locales</strong> (dirty working tree), et en <span style="color:#008000;"><strong>vert</strong></span> dans le cas contraire.</p>
<p>Instructions à ajouter à votre fichier <strong>~/.bashrc</strong> (ou <strong>~/.profile</strong> sur Mac) :</p>
<p><pre class="brush: bash;">
# git branch name in prompt
c_red=`tput setaf 1`
c_green=`tput setaf 2`
c_sgr0=`tput sgr0`

parse_git_branch () {
  if git rev-parse --git-dir &gt;/dev/null 2&gt;&amp;1
  then
          gitver=$(git branch 2&gt;/dev/null| sed -n '/^\*/s/^\* //p')
  else
          return 0
  fi
  echo -e &quot;($gitver) &quot;
}

branch_color () {
        if git rev-parse --git-dir &gt;/dev/null 2&gt;&amp;1
        then
                color=&quot;&quot;
                if git diff --quiet 2&gt;/dev/null &gt;&amp;2
                then
                        color=&quot;${c_green}&quot;
                else
                        color=${c_red}
                fi
        else
                return 0
        fi
        echo -ne $color
}

PS1=&quot;\[\$(branch_color)\]\$(parse_git_branch)\[$(tput sgr0)\]$PS1&quot;
</pre></p>
<p>Dans le même ordre d&#8217;idée, voici un <a href="http://www.codethatmatters.com/2010/01/git-autocomplete-in-mac-os-x/">article bien pratique</a> pour disposer de l&#8217;autocomplétion des noms de branches.</p>
<p>À vous, partagez vos astuces <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  !</p>
<br />Classé dans:<a href='http://blog.piwai.info/category/tech/'>Tech</a> Tagged: <a href='http://blog.piwai.info/tag/branch/'>branch</a>, <a href='http://blog.piwai.info/tag/branche/'>branche</a>, <a href='http://blog.piwai.info/tag/feature-branch/'>feature branch</a>, <a href='http://blog.piwai.info/tag/git/'>git</a>, <a href='http://blog.piwai.info/tag/pull-request/'>pull request</a>, <a href='http://blog.piwai.info/tag/script/'>script</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/piwai.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/piwai.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/piwai.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/piwai.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/piwai.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/piwai.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/piwai.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/piwai.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/piwai.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/piwai.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/piwai.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/piwai.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/piwai.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/piwai.wordpress.com/303/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=303&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piwai.info/2011/10/09/roooh-jai-encore-oublie-ma-branche-git/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/06c6a07275076c6b525e2b14018ad78e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pyricau</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/pull_request.png" medium="image">
			<media:title type="html">Pull Request</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/10/terminal.png" medium="image">
			<media:title type="html">Terminal</media:title>
		</media:content>
	</item>
		<item>
		<title>Un peu de style dans la TextView</title>
		<link>http://blog.piwai.info/2011/10/01/un-peu-de-style-dans-la-textview/</link>
		<comments>http://blog.piwai.info/2011/10/01/un-peu-de-style-dans-la-textview/#comments</comments>
		<pubDate>Sat, 01 Oct 2011 09:00:41 +0000</pubDate>
		<dc:creator>Piwaï</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://blog.piwai.info/?p=224</guid>
		<description><![CDATA[Les designers qui définissent les écrans de votre application Android se sont fait plaisir, et vous ont demandé une mise en forme bien chiadée pour les textes de votre application. Avant de vous jeter sur Photoshop pour créer des images correspondant au pixel près à ce qu&#8217;ils attendent, pourquoi ne pas garder votre bonne vieille [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=224&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Les designers qui définissent les écrans de votre <strong>application Android</strong> se sont fait plaisir, et vous ont demandé une <strong>mise en forme</strong> bien chiadée pour les <strong>textes</strong> de votre application.</p>
<p>Avant de vous jeter sur Photoshop pour créer des images correspondant au pixel près à ce qu&#8217;ils attendent, pourquoi ne pas garder votre bonne vieille <a href="http://developer.android.com/reference/android/widget/TextView.html">TextView</a> ?</p>
<p>Pour changer un peu des <a href="http://blog.piwai.info/tag/gwt/">récents articles</a> sur GWT, voici quelques petites astuces pour Android.<br />
<span id="more-224"></span></p>
<h2>Tweak la police</h2>
<p>Par défaut, Android ne propose que trois polices de caractères pour les TextView : <strong>monospace</strong>, <strong>sans</strong> et <strong>serif</strong>.</p>
<p>Toutefois, il est tout à fait possible d&#8217;utiliser votre police préférée, à condition de l&#8217;<strong>embarquer</strong> dans votre application.</p>
<p>Il suffit de copier la police dans le répertoire <strong>assets</strong> de votre projet Android, puis de la charger <strong>au Runtime</strong> :</p>
<p><pre class="brush: java;">
@Override
protected void onCreate(Bundle savedInstanceState) {.
  super.onCreate(savedInstanceState);

  setContentView(R.layout.main);
  TextView myTextView = (TextView) findViewById(R.id.myTextView);

  Typeface myFont = Typeface.createFromAsset(getAssets(), &quot;MyFont.otf&quot;);
  myTextView.setTypeface(myFont);
}
</pre></p>
<p>Il n&#8217;est pas possible de le faire directement dans votre fichier de layout, sauf en créant des <a href="http://stackoverflow.com/questions/2973270/using-a-custom-typeface-in-android/5185587#5185587">composants alternatifs</a>.</p>
<h2>Stylé !</h2>
<p>Votre texte doit comporter des morceaux en couleur, en italique&#8230; ; bref, il doit être <strong>mis en forme</strong>.</p>
<p>Avant d&#8217;envisager la création d&#8217;une TextView pour chaque morceau de texte différent, jetez un oeil à <a href="http://developer.android.com/reference/android/text/Spannable.html">Spannable</a>, et surtout à son cousin germain <a href="http://developer.android.com/reference/android/text/Html.html">Html</a>.</p>
<p><a href="http://developer.android.com/reference/android/text/Html.html#fromHtml%28java.lang.String%29">Html.fromHtml()</a> retourne un <a href="http://developer.android.com/reference/android/text/Spanned.html">Spanned</a>, qui peut être utilisé pour définir le contenu d&#8217;une TextView.</p>
<p>Par exemple :<br />
<pre class="brush: java;">
Spanned spanned = Html.fromHtml(&quot;Hello &lt;b&gt;World&lt;/b&gt;!&quot;)
myTextView.setText(spanned);
</pre></p>
<p>Bien entendu, une <strong>String</strong> en dur dans le code, <strong>c&#8217;est moche</strong> (pas très <a href="http://en.wikipedia.org/wiki/Internationalization_and_localization">i18n</a>).</p>
<p>Pour y remédier, il suffit d&#8217;encadrer dans un <strong>CDATA</strong> le texte contenant le markup Html, au sein de vos fichiers de ressources.</p>
<p>Exemple de <em>res/values/strings.xml</em> :<br />
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;resources&gt;
  &lt;string name=&quot;styled_content&quot;&gt;&lt;![CDATA[I like turtles!&lt;br /&gt;Hello &lt;font color=&quot;#99cc33&quot;&gt;&lt;b&gt;World&lt;/b&gt;&lt;/font&gt;!]]&gt;&lt;/string&gt;
&lt;/resources&gt;
</pre></p>
<p>Malheureusement, vous ne pouvez pas utiliser ces ressources directement dans vos fichiers de <strong>layout</strong> ; il faut en passer par du <strong>code Java</strong> :<br />
<pre class="brush: java;">
@Override
protected void onCreate(Bundle savedInstanceState) {.
  super.onCreate(savedInstanceState);

  setContentView(R.layout.main);
  TextView myTextView = (TextView) findViewById(R.id.myTextView);

  myTextView.setText(Html.fromHtml(getString(R.string.styled_content)));
}
</pre></p>
<p>Notez que le support du HTML reste <strong>limité</strong> (nombre de balises supportées, HTML mal formé, balises les unes dans les autres&#8230;)</p>
<h2>Bonus</h2>
<ul>
<li><strong>Linkify</strong> permet de créer des TextViews contenant des liens cliquables de toute sorte. A ce sujet, je vous recommande l&#8217;<a href="http://developer.android.com/resources/articles/wikinotes-linkify.html">excellent article</a> disponible sur la doc Android.</li>
<li>Quels liens entre design Web et design Android ? Un <a href="http://android-developers.blogspot.com/2011/09/thinking-like-web-designer.html">article tout récent</a> sur le blog Android aborde le sujet.</li>
</ul>
<br />Classé dans:<a href='http://blog.piwai.info/category/tech/'>Tech</a> Tagged: <a href='http://blog.piwai.info/tag/android/'>android</a>, <a href='http://blog.piwai.info/tag/java/'>java</a>, <a href='http://blog.piwai.info/tag/ui/'>ui</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/piwai.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/piwai.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/piwai.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/piwai.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/piwai.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/piwai.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/piwai.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/piwai.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/piwai.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/piwai.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/piwai.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/piwai.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/piwai.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/piwai.wordpress.com/224/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=224&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piwai.info/2011/10/01/un-peu-de-style-dans-la-textview/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/06c6a07275076c6b525e2b14018ad78e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pyricau</media:title>
		</media:content>
	</item>
		<item>
		<title>Quand mamie craque du Wifi</title>
		<link>http://blog.piwai.info/2011/09/23/quand-mamie-craque-du-wifi/</link>
		<comments>http://blog.piwai.info/2011/09/23/quand-mamie-craque-du-wifi/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 22:35:02 +0000</pubDate>
		<dc:creator>Piwaï</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[backtrack]]></category>
		<category><![CDATA[crack]]></category>
		<category><![CDATA[WEP]]></category>
		<category><![CDATA[wifi]]></category>

		<guid isPermaLink="false">http://piwai.wordpress.com/?p=42</guid>
		<description><![CDATA[Imaginons que vous ayez besoin de craquer le mot de passe de votre propre réseau Wifi, protégé par une clé WEP. Je parle bien de votre propre réseau Wifi, car je suis sûr qu&#8217;il ne vous viendrait jamais à l&#8217;idée de craquer l&#8217;accès de votre voisin, sachant que c&#8217;est totalement illégal. Craquer une clé WEP [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=42&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Imaginons que vous ayez besoin de <strong>craquer</strong> le mot de passe de votre propre réseau Wifi, protégé par une <strong>clé WEP</strong>. Je parle bien de <em>votre propre réseau Wifi</em>, car je suis sûr qu&#8217;il ne vous viendrait jamais à l&#8217;idée de craquer l&#8217;accès de votre voisin, sachant que c&#8217;est totalement <strong>illégal</strong>. </p>
<p>Craquer une clé WEP peut être l&#8217;affaire de quelques minutes, et pourtant, aujourd&#8217;hui encore, de très nombreux réseaux Wifi de particuliers sont protégés par WEP. Même le <a href="http://www.nytimes.com/2011/02/17/technology/personaltech/17basics.html">New York Times</a> en parle. Faites passer le mot, il faut que cela change.</p>
<p>Les techniques pour y parvenir se sont considérablement améliorées ces dernières années. Parallèlement à ces techniques, c&#8217;est aussi leur facilité de mise en œuvre qui a formidablement évolué.</p>
<p>Aujourd&#8217;hui, quelques clics suffisent : même <strong>mamie peut craquer du Wifi</strong>, et c&#8217;est l&#8217;objet de cet article.</p>
<p><span id="more-42"></span></p>
<h2>Mise en place</h2>
<h3>Matos</h3>
<p>En termes de matériel, une carte Wifi suffit. La plupart des cartes conviennent et disposent aujourd&#8217;hui de drivers adaptés.</p>
<p>Vous obtiendrez de très bons résultats avec l&#8217;<a href="http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&amp;field-keywords=AWUS036H&amp;x=0&amp;y=0">Alfa AWUS036H</a>, a priori la carte la plus puissante du marché (1000mW). Attention par contre, il me semble qu&#8217;elle est interdite à la vente en France, effet micro onde garanti <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> .</p>
<h3>OS</h3>
<p>Les drivers patchés pour le crack Wifi sont essentiellement disponibles sous Linux. Plus précisément, la distribution <a href="http://www.backtrack-linux.org/downloads/">Backtrack</a> contient tout le nécessaire. Elle est disponible en <strong>Live CD</strong> et en <strong>Live USB</strong>.</p>
<p>Version mamie : vous trouvez une clé USB avec quelques gigas de libres ; vous suivez <a href="http://www.backtrack-linux.org/tutorials/usb-live-install/">ce tutoriel</a> ; vous branchez la clé USB ; et vous redémarrez pour booter sur la clé USB (cf. <a href="http://www.siteduzero.com/tutoriel-3-12696-tester-et-installer-ubuntu.html#ss_part_2">ce tutoriel</a> &gt; <strong>Modifier l&#8217;ordre de boot</strong>).</p>
<p>Backtrack démarre, se logue tout seul, et présente une ligne de commande une fois démarré.</p>
<p>Il suffit de taper <strong>startx</strong> pour lancer l&#8217;environnement graphique. </p>
<p><pre class="brush: bash;">
root@root:~# startx
</pre><br />
<em>Notez que le layout de clavier étant par défaut un qwerty, il vous faudra probablement taper <strong>stqrtx</strong>.</em></p>
<p>Une fois l&#8217;environnement graphique démarré, vous pouvez changer le layout de clavier dans <em>System &gt; Preferences &gt; Keyboard &gt; Layouts</em>.</p>
<h2>Wifite : à un clic du crack</h2>
<p>Le plus dur est fait ! Il ne vous reste plus qu&#8217;à récupérer <a href="http://code.google.com/p/wifite/">Wifite</a> et le lancer.</p>
<p>Téléchargez le script python à cette adresse : <a href="http://wifite.googlecode.com/svn/trunk/wifite.py">http://wifite.googlecode.com/svn/trunk/wifite.py</a>.</p>
<p>Rendez-le exécutable : <strong>chmod +x</strong> ; ou bien clic-droit sur le fichier, sélectionnez <em>Properties &gt; Permissions</em> et cochez<br />
z <em>Execute: Allow executing file as program</em>.</p>
<p>Exécutez le script (double clic sur le fichier &gt; <em>Run</em>).</p>
<p>Et hop, une bonne grosse interface à la <strong>clicouille</strong> :</p>
<p><img src="http://piwai.files.wordpress.com/2011/08/wifite1.png?w=914" alt="" title="wifite1"   class="aligncenter size-full wp-image-277" /></p>
<p>Sélectionnez l&#8217;interface réseau à utiliser (en général, il n&#8217;y en a qu&#8217;une). Étant donné que l&#8217;on s&#8217;intéresse ici au WEP, vous pouvez sélectionner uniquement <em>WEP</em> dans <em>encryption type</em>.</p>
<p>De <a href="http://code.google.com/p/wifite/">nombreux paramètres</a> sont disponibles, mais <strong>pour mamie</strong>, il suffit de cliquer sur <strong>h4x0r 1t n40</strong>, et d&#8217;aller <strong>prendre une tisane</strong>.</p>
<p><img src="http://piwai.files.wordpress.com/2011/08/wifite2.png?w=914" alt="" title="wifite2"   class="aligncenter size-full wp-image-279" /></p>
<p>Wifite se charge de tout, et note les mots de passe crackés dans le fichier <strong>log.txt</strong> créé à côté du script <strong>wifite.py</strong>.</p>
<p><img src="http://piwai.files.wordpress.com/2011/08/wifite3.png?w=914" alt="" title="wifite3"   class="aligncenter size-full wp-image-281" /></p>
<p><strong>Bingo !</strong></p>
<br />Classé dans:<a href='http://blog.piwai.info/category/tech/'>Tech</a> Tagged: <a href='http://blog.piwai.info/tag/backtrack/'>backtrack</a>, <a href='http://blog.piwai.info/tag/crack/'>crack</a>, <a href='http://blog.piwai.info/tag/wep/'>WEP</a>, <a href='http://blog.piwai.info/tag/wifi/'>wifi</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/piwai.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/piwai.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/piwai.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/piwai.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/piwai.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/piwai.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/piwai.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/piwai.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/piwai.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/piwai.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/piwai.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/piwai.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/piwai.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/piwai.wordpress.com/42/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=42&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piwai.info/2011/09/23/quand-mamie-craque-du-wifi/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/06c6a07275076c6b525e2b14018ad78e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pyricau</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/08/wifite1.png" medium="image">
			<media:title type="html">wifite1</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/08/wifite2.png" medium="image">
			<media:title type="html">wifite2</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/08/wifite3.png" medium="image">
			<media:title type="html">wifite3</media:title>
		</media:content>
	</item>
		<item>
		<title>Les mains dans le cambUiBinder</title>
		<link>http://blog.piwai.info/2011/09/13/les-mains-dans-le-cambuibinder/</link>
		<comments>http://blog.piwai.info/2011/09/13/les-mains-dans-le-cambuibinder/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 06:13:02 +0000</pubDate>
		<dc:creator>Piwaï</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[uibinder]]></category>

		<guid isPermaLink="false">http://blog.piwai.info/?p=138</guid>
		<description><![CDATA[L&#8217;article précédent montrait comment faire de la coloration syntaxique en GWT. Toujours pour Rockslide, je souhaitais pouvoir écrire le code à mettre en forme dans des templates UiBinder, plutôt que dans des Strings statiques portées par des classes Java. Est-ce possible ? Comment y parvenir ? En creusant ces questions, j&#8217;ai réalisé que UiBinder possède [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=138&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>L&#8217;article précédent montrait comment faire de la <a href="http://blog.piwai.info/2011/09/05/coloration-syntaxique-en-gwt/">coloration syntaxique en GWT</a>.</p>
<p>Toujours pour <a href="http://pyricau.github.com/rockslide">Rockslide</a>, je souhaitais pouvoir écrire le code à mettre en forme dans des <strong>templates</strong> <a href="http://code.google.com/webtoolkit/doc/latest/DevGuideUiBinder.html">UiBinder</a>, plutôt que dans des Strings statiques portées par des classes Java.</p>
<p>Est-ce possible ? Comment y parvenir ? En creusant ces questions, j&#8217;ai réalisé que UiBinder possède de nombreuses facettes <strong>non documentées</strong> et qui méritent que l&#8217;on s&#8217;y attarde. Tour du propriétaire.<br />
<span id="more-138"></span></p>
<h2>Widgets customs</h2>
<p>Vous le savez probablement, il est possible d&#8217;inclure ses propres widgets GWT dans un template UiBinder.</p>
<p>Il suffit pour cela d&#8217;étendre la classe <strong>Widget</strong>. Prenons l&#8217;exemple d&#8217;un bouton ouvrant une fenêtre d&#8217;alerte :</p>
<p><pre class="brush: java;">
public class AlertButton extends Button implements ClickHandler {

	public AlertButton() {
		addClickHandler(this);
	}

	@Override
	public void onClick(ClickEvent event) {
		Window.alert(&quot;I like turtles&quot;);
	}
}
</pre></p>
<p>Vous pouvez ensuite l&#8217;inclure dans vos templates UiBinder, en ajoutant un <strong>namespace</strong> correspondant au <strong>package</strong> de votre widget :</p>
<p><pre class="brush: xml; highlight: [4,8];">
&lt;ui:UiBinder
    xmlns:ui='urn:ui:com.google.gwt.uibinder'
    xmlns:g='urn:import:com.google.gwt.user.client.ui'
    xmlns:custom='urn:import:info.piwai.blog.ui'
&gt;

	&lt;g:FlowPanel&gt;
		&lt;custom:AlertButton /&gt;
	&lt;/g:FlowPanel&gt;

&lt;/ui:UiBinder&gt;
</pre></p>
<p>Un peu limité quand même&#8230;</p>
<h2>Et avec des paramètres ?</h2>
<p>Il y a mieux ! Vous pouvez tout à fait passer des paramètres à votre widget. Il suffit d&#8217;ajouter des paramètres de <strong>constructeur</strong> (donc obligatoires) ou des <strong>setters</strong> (donc facultatifs) à votre widget :</p>
<p><pre class="brush: java; highlight: [5];">
public class AlertButton extends Button implements ClickHandler {

	private final String msg;

	@UiConstructor
	public AlertButton(String msg) {
		this.msg = msg;
		addClickHandler(this);
	}

	@Override
	public void onClick(ClickEvent event) {
		Window.alert(msg);
	}
}
</pre><br />
<em>Notez la présence de <strong>@UiConstructor</strong>, nécessaire lorsque le constructeur par défaut n&#8217;est pas défini.</em></p>
<p>Puis d&#8217;utiliser les <strong>attributs correspondants</strong> dans vos templates UiBinder :</p>
<p><pre class="brush: xml; highlight: [8];">
&lt;ui:UiBinder
    xmlns:ui='urn:ui:com.google.gwt.uibinder'
    xmlns:g='urn:import:com.google.gwt.user.client.ui'
    xmlns:custom='urn:import:info.piwai.blog.ui'
&gt;

	&lt;g:FlowPanel&gt;
		&lt;custom:AlertButton msg=&quot;I like turtles&quot; /&gt;
	&lt;/g:FlowPanel&gt;

&lt;/ui:UiBinder&gt;
</pre></p>
<h2>Les attributs, ça pue ?</h2>
<p>Si votre widget implémente <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/HasText.html">HasText</a>, vous pourrez alors définir ce texte directement au <strong>sein de la balise</strong> au lieu d&#8217;utiliser des <strong>attributs</strong>. Modifions <strong>AlertButton</strong> :</p>
<p><pre class="brush: java; highlight: [1,10];">
public class AlertButton extends Button implements ClickHandler, HasText {

	private String msg = &quot;Default Message&quot;;

	public AlertButton() {
		addClickHandler(this);
	}

	@Override
	public void setText(String msg) {
		this.msg = msg;
	}

	@Override
	public void onClick(ClickEvent event) {
		Window.alert(msg);
	}

	@Override
	public void getText() {
		throw new UnsupportedOperationException();
	}
}
</pre><br />
<em>Notez que l&#8217;interface <strong>HasText</strong> impose d&#8217;implémenter <strong>getText()</strong>, mais cette méthode n&#8217;est pas nécessaire pour nos besoins.</em></p>
<p>C&#8217;est déjà plus sympa :<br />
<pre class="brush: xml; highlight: [8];">
&lt;ui:UiBinder
    xmlns:ui='urn:ui:com.google.gwt.uibinder'
    xmlns:g='urn:import:com.google.gwt.user.client.ui'
    xmlns:custom='urn:import:info.piwai.blog.ui'
&gt;

	&lt;g:FlowPanel&gt;
		&lt;custom:AlertButton&gt;I like turtles&lt;/custom:AlertButton&gt;
	&lt;/g:FlowPanel&gt;

&lt;/ui:UiBinder&gt;
</pre></p>
<h2>Quid du HTML ?</h2>
<p>Vous pouvez aussi inclure, au sein de vos widgets, du HTML défini dans votre template UiBinder, grâce à <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/HasHTML.html">HasHTML</a>.</p>
<p>Par exemple, supposons que je souhaite enrichir mon <strong>AlertButton</strong> pour afficher de belles popups, en utilisant une <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/DialogBox.html">DialogBox</a> :</p>
<p><pre class="brush: java; highlight: [1,24];">
public class AlertButton extends Button implements ClickHandler, HasHTML {

	private String html = &quot;&quot;;

	private String title = &quot;Default title&quot;;

	public AlertButton() {
		addClickHandler(this);
	}

	@Override
	public void setHTML(String html) {
		this.html = html;
	}

	@Override
	public void setTitle(final String title) {
		this.title = title;
	}

	@Override
	public void onClick(ClickEvent event) {
		DialogBox dialogBox = new DialogBox();
		dialogBox.setWidget(new HTML(html));
		dialogBox.setText(title);
		dialogBox.center();
	}

	@Override
	public void getText() {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setText(String text) {
		throw new UnsupportedOperationException();
	}

	@Override
	public String getHTML() {
		throw new UnsupportedOperationException();
	}

}
</pre><br />
<em>La méthode <strong>setHTML()</strong> est appelée avec en paramètre le HTML sous forme de String.</em></p>
<p>Je peux désormais spécifier le <strong>contenu HTML</strong> de cette boîte de dialogue dans mon template UiBinder : </p>
<p><pre class="brush: xml; highlight: [10];">
&lt;ui:UiBinder
    xmlns:ui='urn:ui:com.google.gwt.uibinder'
    xmlns:g='urn:import:com.google.gwt.user.client.ui'
    xmlns:custom='urn:import:info.piwai.blog.ui'
&gt;

	&lt;g:FlowPanel&gt;
		&lt;custom:AlertButton title=&quot;I like turtles&quot;&gt;
			&lt;p&gt;
				I &lt;strong&gt;really&lt;/strong&gt; like turtles!&lt;br /&gt;
				What about &lt;em&gt;you&lt;/em&gt;?
			&lt;/p&gt;
		&lt;/custom:AlertButton&gt;
	&lt;/g:FlowPanel&gt;

&lt;/ui:UiBinder&gt;
</pre></p>
<h2>&amp;nbsp; ?</h2>
<p>Comment utiliser des entités HTML dans vos templates UiBinder ? Il suffit d&#8217;ajouter <a href="http://code.google.com/webtoolkit/doc/latest/DevGuideUiBinder.html#HTML_entities">la DTD</a> fournie par Google :</p>
<p><pre class="brush: xml; highlight: [1,11];">
&lt;!DOCTYPE ui:UiBinder SYSTEM &quot;http://dl.google.com/gwt/DTD/xhtml.ent&quot;&gt;
&lt;ui:UiBinder
    xmlns:ui='urn:ui:com.google.gwt.uibinder'
    xmlns:g='urn:import:com.google.gwt.user.client.ui'
    xmlns:custom='urn:import:info.piwai.blog.ui'
&gt;

	&lt;g:FlowPanel&gt;
		&lt;custom:AlertButton title=&quot;I like turtles&quot;&gt;
			&lt;p&gt;
				Turtles &amp;gt; Dolphins!
			&lt;/p&gt;
		&lt;/custom:AlertButton&gt;
	&lt;/g:FlowPanel&gt;

&lt;/ui:UiBinder&gt;
</pre></p>
<h2>Paramètres complexes</h2>
<p><strong>&lt;ui:with /&gt;</strong> permet d&#8217;injecter un objet (créé via <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/core/client/GWT.html#create%28java.lang.Class%29">GWT.create()</a>) dans votre template UiBinder.</p>
<p>Un exemple d&#8217;utilisation serait l&#8217;injection d&#8217;une <strong>Enum</strong> afin de paramétrer un widget.</p>
<p>Reprenons notre fenêtre d&#8217;alerte initiale :</p>
<p><pre class="brush: java; highlight: [5];">
public class AlertButton extends Button implements ClickHandler {

	private final Animal animal;

	@UiConstructor
	public AlertButton(Animal animal) {
		this.animal = animal;
		addClickHandler(this);
	}

	@Override
	public void onClick(ClickEvent event) {
		Window.alert(&quot;I like &quot; + animal.toString());
	}
}
</pre></p>
<p><strong>Animal</strong> est une simple Enum :<br />
<pre class="brush: java;">
public Enum Animal {
  TURTLES, DOLPHINS;
}
</pre></p>
<p>Il ne reste plus qu&#8217;à utiliser l&#8217;Enum en question dans le template UiBinder :<br />
<pre class="brush: xml; highlight: [6,9];">
&lt;ui:UiBinder
    xmlns:ui='urn:ui:com.google.gwt.uibinder'
    xmlns:g='urn:import:com.google.gwt.user.client.ui'
    xmlns:custom='urn:import:info.piwai.blog.ui'
&gt;
	&lt;ui:with field=&quot;animal&quot; type=&quot;info.piwai.blog.Animal&quot;/&gt;

	&lt;g:FlowPanel&gt;
		&lt;custom:AlertButton animal=&quot;{animal.TURTLES}&quot; /&gt;
	&lt;/g:FlowPanel&gt;

&lt;/ui:UiBinder&gt;
</pre><br />
<em>Cerise sur le gateau, on bénéficie de l&#8217;autocomplétion : en tapant <strong>{animal.}</strong>, l&#8217;IDE propose <strong>TURTLES</strong> ou <strong>DOLPHINS</strong> !</em></p>
<h2>Bon, et la coloration syntaxique alors ?</h2>
<p>En combinant tout ce qui a été dit précédemment, il est possible d&#8217;écrire des exemples de code au sein de templates UiBinder, mis en forme par SyntaxHighlighter. On utilisera pour cela un widget implémentant <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/HasHTML.html">HasHTML</a>. </p>
<p>Avant de passer aux choses sérieuses, un rappel. Dans <a href="http://blog.piwai.info/2011/09/05/coloration-syntaxique-en-gwt/">l&#8217;article précédent</a>, nous utilisions le code suivant pour faire de la coloration syntaxique en GWT :</p>
<p><pre class="brush: java;">
public void bindTextAreaCodeToHtml(TextArea textArea, HTML html) {
    JavaScriptObject brush = BrushFactory.newJavaBrush();
    String code = textArea.getValue();
    String htmlCode = SyntaxHighlighter.highlight(code, brush, false);
    html.setHTML(htmlCode);
}
</pre></p>
<p>Une précision : Le <strong>parseur UiBinder</strong> utilisé pour les widgets implémentant <strong>HasHTML</strong> ne garde pas les retours à la ligne, ce qui se révèle gênant lorsque son contenu est du code mis en forme. Pour contourner cela, on peut utiliser une balise <strong>&lt;pre&gt;</strong> dans le template UiBinder.</p>
<p>Trêve de suspens, voici le résultat :</p>
<p><pre class="brush: java; highlight: [1,12,17,24];">
public class Code extends Composite implements HasHTML {

	private JavaScriptObject brush = null;

	private HTML panel = new HTML();

	@UiConstructor
	public Code() {
		initWidget(panel);
	}

	public void setBrush(JavaScriptObject brush) {
		this.brush = brush;
	}

	@Override
	public void setHTML(String html) {
		// On supprime la balise &lt;pre&gt;
		final String code = html.replaceFirst(&quot;&lt;pre&gt;&quot;, &quot;&quot;).replaceFirst(&quot;&lt;/pre&gt;&quot;, &quot;&quot;);
		Scheduler.get().scheduleDeferred(new ScheduledCommand() {
			@Override
			public void execute() {
				if (brush != null) {
					String codeAsHtml = SyntaxHighlighter.highlight(code, brush, false);
					panel.setHTML(codeAsHtml);
				}
			}
		});
	}

	@Override
	public void getText() {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setText(String text) {
		throw new UnsupportedOperationException();
	}

	@Override
	public String getHTML() {
		throw new UnsupportedOperationException();
	}

}
</pre><br />
<em>Notez l&#8217;utilisation du <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/core/client/Scheduler.html">Scheduler</a> pour afficher le code immédiatement <strong>après</strong> la construction du widget. L&#8217;ordre de valorisation des attributs n&#8217;étant pas garanti, cela permet d&#8217;être sûr que la valeur du champ <strong>brush</strong> aura été préalablement injectée au moment de l&#8217;appel à <strong>SyntaxHighlighter</strong>.</em></p>
<p>On peut ensuite utiliser ce widget dans un template UiBinder classique :</p>
<p><pre class="brush: xml; highlight: [8,11,14];">
&lt;!DOCTYPE ui:UiBinder SYSTEM &quot;http://dl.google.com/gwt/DTD/xhtml.ent&quot;&gt;
&lt;ui:UiBinder
    xmlns:ui='urn:ui:com.google.gwt.uibinder'
    xmlns:g='urn:import:com.google.gwt.user.client.ui'
    xmlns:custom='urn:import:info.piwai.blog.ui'
&gt;

	&lt;ui:with field=&quot;brushFactory&quot; type=&quot;info.piwai.blog.BrushFactory&quot;/&gt;

	&lt;g:FlowPanel&gt;
		&lt;custom:Code brush=&quot;{brushFactory.newJavaBrush}&quot;&gt;&lt;pre&gt;
			public class Main {
				public static void main(String[] args) throws Exception {
					List&amp;lt;String&amp;gt; moto = Arrays.asList(&quot;I&quot;, &quot;Like&quot;, &quot;Turtles&quot;);
					System.out.println(moto);
				}
			}&lt;/pre&gt;		
		&lt;/custom:Code&gt;
	&lt;/g:FlowPanel&gt;

&lt;/ui:UiBinder&gt;
</pre><br />
<em>Les caractères <strong>&lt;</strong> et <strong>&gt;</strong> doivent être échappés pour éviter qu&#8217;ils ne soient interprétés par UiBinder et ne conduisent à des erreurs de validation. Ainsi, au lieu de <strong>List&lt;String&gt;</strong>, on écrit <strong>List&amp;lt;String&amp;gt;</strong></em></p>
<p><strong>Edit :</strong> Merci <a href="https://twitter.com/#!/matboniface/status/113509239925915648">@matboniface</a>, j&#8217;avais au départ parlé d&#8217;échapper des entités HTML, ce qui n&#8217;a pas beaucoup de sens.</p>
<h2>Conclusion</h2>
<p>Cet article s&#8217;est révélé <strong>plus long</strong> que ce que j&#8217;avais en tête initialement ! J&#8217;espère qu&#8217;il vous aura fait découvrir des aspects <strong>intéressants</strong> et souvent <strong>méconnus</strong> de <strong>UiBinder</strong>. </p>
<p>N&#8217;hésitez pas à compléter ce billet avec vos <strong>trucs et astuces</strong> UiBinder en <strong>commentaire</strong> !</p>
<p>Vous pouvez aussi vous abonner au <a href="http://blog.piwai.info/feed/">flux RSS</a>. Je me suis fixé comme objectif de publier un article par semaine, on verra si je tiens le rythme <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  .</p>
<br />Classé dans:<a href='http://blog.piwai.info/category/tech/'>Tech</a> Tagged: <a href='http://blog.piwai.info/tag/gwt/'>gwt</a>, <a href='http://blog.piwai.info/tag/java/'>java</a>, <a href='http://blog.piwai.info/tag/uibinder/'>uibinder</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/piwai.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/piwai.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/piwai.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/piwai.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/piwai.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/piwai.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/piwai.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/piwai.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/piwai.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/piwai.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/piwai.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/piwai.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/piwai.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/piwai.wordpress.com/138/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=138&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piwai.info/2011/09/13/les-mains-dans-le-cambuibinder/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/06c6a07275076c6b525e2b14018ad78e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pyricau</media:title>
		</media:content>
	</item>
		<item>
		<title>Coloration Syntaxique en GWT</title>
		<link>http://blog.piwai.info/2011/09/05/coloration-syntaxique-en-gwt/</link>
		<comments>http://blog.piwai.info/2011/09/05/coloration-syntaxique-en-gwt/#comments</comments>
		<pubDate>Mon, 05 Sep 2011 08:59:39 +0000</pubDate>
		<dc:creator>Piwaï</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[syntaxhighlighter]]></category>

		<guid isPermaLink="false">http://blog.piwai.info/?p=126</guid>
		<description><![CDATA[Vous connaissez peut-être Rockslide, qui permet de réaliser une présentation (des slides) en GWT. Qui dit slides techniques dit exemples de code, et donc coloration syntaxique. J&#8217;ai creusé un peu le sujet pour finalement retenir une solution. Comment faire de la coloration syntaxique côté client, en GWT ? Solutions disponibles A ma connaissance, il n&#8217;existe [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=126&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Vous connaissez peut-être <a href="http://pyricau.github.com/rockslide">Rockslide</a>, qui permet de réaliser une présentation (des slides) en <a href="http://code.google.com/webtoolkit">GWT</a>.</p>
<p>Qui dit <strong>slides techniques</strong> dit exemples de <strong>code</strong>, et donc <strong>coloration syntaxique</strong>.</p>
<p>J&#8217;ai creusé un peu le sujet pour finalement retenir <strong>une solution</strong>.</p>
<p><strong>Comment faire de la coloration syntaxique côté client, en GWT</strong> ?<br />
<span id="more-126"></span></p>
<h2>Solutions disponibles</h2>
<p>A ma connaissance, il n&#8217;existe pas de solution de coloration syntaxique spécifique à GWT, ce qui nous laisse trois options :</p>
<ul>
<li>Implémenter une solution en GWT (c&#8217;est mort, je n&#8217;ai pas que ça à faire)</li>
<li>Trouver une solution en Java et adapter la partie graphique (<strong>fausse bonne idée</strong>)</li>
<li>Trouver une solution en Javascript et réaliser un binding GWT (ça, c&#8217;est dans mes cordes)</li>
</ul>
<p>Un rapide tour d&#8217;horizon fait ressortir deux frameworks Javascript très utilisés pour la coloration syntaxique :</p>
<ul>
<li><a href="http://softwaremaniacs.org/soft/highlight/en/">highlight.js</a></li>
<li><a href="http://alexgorbatchev.com/SyntaxHighlighter/">SyntaxHighlighter</a></li>
</ul>
<p>Les deux semblent maintenus, des releases récentes sont disponibles. Mon choix se porte sur <strong>SyntaxHighlighter</strong>, qui semble plus beau. C&#8217;est purement subjectif, mais je trouve que le code mis en couleur par <strong>highlight.js</strong> a un petit air <strong>vieillot</strong>.</p>
<h2>gwt-syntaxhighlighter</h2>
<p>Coup de bol : je tombe sur <a href="http://code.google.com/p/gwt-syntaxhighlighter">gwt-syntaxhighlighter</a>, une intégration assez poussée de <strong>SyntaxHighlighter</strong> dans <strong>GWT</strong>.</p>
<p>Trop poussée, hélas :</p>
<ul>
<li>gwt-syntaxhighlighter utilise des <a href="http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsDeferred.html#generators">Generators</a>, ce qui allonge le <strong>temps de compilation</strong>,</li>
<li>gwt-syntaxhighlighter comporte <strong>quelques bugs</strong> qui ne sont pas corrigés et qui sont difficiles à contourner,</li>
<li>la version de SyntaxHighlighter utilisée n&#8217;est <strong>pas à jour</strong> (les versions récentes apportent pourtant des évolutions intéressantes).</li>
</ul>
<p>De plus, il s&#8217;avère que l&#8217;intégration de SyntaxHighlighter est relativement aisée, beaucoup plus simple que ce que tente de faire <strong>gwt-syntaxhighlighter</strong>.</p>
<h2>Intégration GWT de SyntaxHighlighter</h2>
<h3>Charger les scripts et les CSS</h3>
<p>Tout d&#8217;abord, il faut <a href="http://alexgorbatchev.com/SyntaxHighlighter/download/">télécharger</a> SyntaxHighlighter. Les dossiers <strong>scripts</strong> et <strong>styles</strong> contiennent tout ce dont vous aurez besoin.</p>
<p>Ces fichiers devront être inclus dans l&#8217;application GWT. Il existe <a href="http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModules">différentes méthodes</a>. J&#8217;ai choisi de créer un répertoire <strong>public</strong> au même niveau que le répertoire <strong>client</strong>, et d&#8217;y placer les répertoires <strong>scripts</strong> et <strong>styles</strong>.</p>
<p><img src="http://piwai.files.wordpress.com/2011/09/public.png?w=914" alt="" title="public"   class="aligncenter size-full wp-image-158" /></p>
<p>Ensuite, il suffit de les ajouter au module (fichier <strong>.gwt.xml</strong>) :<br />
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;module&gt;

    &lt;!-- La CSS de base pour SyntaxHighlighter --&gt;
    &lt;stylesheet src=&quot;styles/shCore.css&quot;/&gt;

    &lt;!-- J'utilise le thème Eclipse (8 thèmes disponibles) --&gt;
    &lt;stylesheet src=&quot;styles/shThemeEclipse.css&quot;/&gt;

    &lt;!-- Le javascript de base pour SyntaxHighlighter --&gt;
    &lt;script src=&quot;scripts/shCore.js&quot;/&gt;

    &lt;!-- Les extensions pour les différents langages utilisés --&gt;
    &lt;script src=&quot;scripts/shBrushJava.js&quot;/&gt;
    &lt;script src=&quot;scripts/shBrushXml.js&quot;/&gt;

    &lt;!-- [...] --&gt;
&lt;/module&gt;
</pre></p>
<h3>Go, Go, GO!</h3>
<p>A l&#8217;origine, SyntaxHighlighter fonctionnait en parsant le DOM et en modifiant les nœuds marqués comme conteneurs de code. La dernière release propose une <a href="http://alexgorbatchev.com/SyntaxHighlighter/whatsnew.html#commonjs">approche alternative</a>, qui fonctionne indépendamment du DOM.</p>
<p>Le fonctionnement est simple : une fonction Javascript prend en entrée du code sous forme de String, et renvoie une String contenant le HTML pour afficher le code formaté.</p>
<p>Un <em>brush</em> (pinceau) est nécessaire pour colorer du code. Il existe en fait un brush par langage, et celui-ci définit les mots clés, la syntaxe, etc.</p>
<p>Il nous faut donc une fabrique de pinceaux :</p>
<p><pre class="brush: java;">
public class BrushFactory {
    public native JavaScriptObject newJavaBrush() /*-{
        return new $wnd.SyntaxHighlighter.brushes.Java();
    }-*/;

    public native JavaScriptObject newXmlBrush() /*-{
        return new $wnd.SyntaxHighlighter.brushes.Xml();
    }-*/;
}
</pre></p>
<p>Voici le code <a href="http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html">JSNI</a> utilisant SyntaxHighlighter pour transformer du code en html :<br />
<pre class="brush: java;">
public class SyntaxHighlighter {
    public static native String highlight(String code, JavaScriptObject brush, boolean toolbar) /*-{
        var params = {};
        params['toolbar'] = toolbar;
        brush.init(params);
        return brush.getHtml(code);
    }-*/;
}
</pre><br />
<em>Notez le paramètre toolbar qui permet d&#8217;afficher ou non la barre d&#8217;outil. De <a href="http://alexgorbatchev.com/SyntaxHighlighter/manual/configuration/">nombreux paramètres</a> sont disponibles ; à vous de les intégrer.</em></p>
<p>Ya plus qu&#8217;à utiliser tout ça, par exemple en récupérant le code contenu dans une <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/TextArea.html">TextArea</a> et en l&#8217;affichant via un <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/HTML.html">HTML</a>.</p>
<p><pre class="brush: java;">
public void bindTextAreaCodeToHtml(TextArea textArea, HTML html) {
    JavaScriptObject brush = BrushFactory.newJavaBrush();
    String code = textArea.getValue();
    String htmlCode = SyntaxHighlighter.highlight(code, brush, false);
    html.setHTML(htmlCode);
}
</pre></p>
<h2>Conclusion</h2>
<p>Vous avez désormais toutes les clés en main pour faire de la coloration syntaxique côté client en GWT.</p>
<p>Bien entendu, ce code est à adapter suivant vos besoins. Vous n&#8217;êtes pas obligés d&#8217;utiliser des <strong>static</strong> partout <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  .</p>
<br />Classé dans:<a href='http://blog.piwai.info/category/tech/'>Tech</a> Tagged: <a href='http://blog.piwai.info/tag/gwt/'>gwt</a>, <a href='http://blog.piwai.info/tag/java/'>java</a>, <a href='http://blog.piwai.info/tag/javascript/'>javascript</a>, <a href='http://blog.piwai.info/tag/syntaxhighlighter/'>syntaxhighlighter</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/piwai.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/piwai.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/piwai.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/piwai.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/piwai.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/piwai.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/piwai.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/piwai.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/piwai.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/piwai.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/piwai.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/piwai.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/piwai.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/piwai.wordpress.com/126/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=126&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piwai.info/2011/09/05/coloration-syntaxique-en-gwt/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/06c6a07275076c6b525e2b14018ad78e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pyricau</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/09/public.png" medium="image">
			<media:title type="html">public</media:title>
		</media:content>
	</item>
		<item>
		<title>Les IDE, et la règle des 80 / 120</title>
		<link>http://blog.piwai.info/2011/08/31/les-ide-et-la-regle-des-80-120/</link>
		<comments>http://blog.piwai.info/2011/08/31/les-ide-et-la-regle-des-80-120/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 13:38:09 +0000</pubDate>
		<dc:creator>Piwaï</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[clean code]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://piwai.wordpress.com/?p=4</guid>
		<description><![CDATA[Cet article n&#8217;a strictement rien à voir avec Pareto. Un peu plus avec un tweet datant de quelques mois. La longueur maximale des lignes de code est un débat récurrent dans les équipes de développement. Dès lors que l&#8217;on met en place un formatage du code automatique et partagé par tous les développeurs (notamment pour [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=4&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Cet article n&#8217;a strictement rien à voir avec <a href="http://fr.wikipedia.org/wiki/Loi_de_Pareto">Pareto</a>. Un peu plus avec un <a href="https://twitter.com/MathildeLemee/status/71688421596344320">tweet</a> datant de quelques mois.</p>
<p>La <strong>longueur</strong> maximale des <strong>lignes de code</strong> est un débat récurrent dans les équipes de développement. </p>
<p>Dès lors que l&#8217;on met en place un formatage du code automatique et partagé par tous les développeurs (notamment pour faciliter les diff), l&#8217;éternelle question revient : </p>
<blockquote><p>80 ou 120 ?</p></blockquote>
<blockquote><p>Ça fait 5 ans qu&#8217;on a tous des 19 pouces, on pourrait peut-être passer à 160 non ?</p></blockquote>
<p><span id="more-4"></span></p>
<h2>Que nenni !</h2>
<p>Voici la configuration que j&#8217;utilise :<br />
<img src="http://piwai.files.wordpress.com/2011/08/line_width.png?w=914" alt="" title="Maximum line width"   class="aligncenter size-full wp-image-86" /></p>
<p>Vous avez bien lu, je préfère <strong>1000</strong>. Ou 2000. Ou 10000. Ou&#8230; bon, je suppose que vous avez compris.</p>
<p>Non pas que j&#8217;ai la chance de disposer d&#8217;un écran de cinéma pour coder, pour moi il s&#8217;agit juste de <strong>bonnes pratiques</strong>.</p>
<p>Ce n&#8217;est pas votre IDE qui doit décider de la longueur de vos lignes de code, <strong>c&#8217;est vous</strong>.</p>
<p>Une ligne de code qui dépasse la largeur de l&#8217;écran, c&#8217;est un <a href="http://en.wikipedia.org/wiki/Code_smell">code smell</a>. Laisser l&#8217;IDE ajouter des retours à la ligne, c&#8217;est cacher le code smell.</p>
<p>Un peu comme mettre du déo sans se doucher après un jogging.</p>
<p>Pour la route, quelques cas classiques de longlignite aigüe :</p>
<h2>Le syndrome du développeur C, aka le radin des variables</h2>
<p>A l&#8217;origine, en C, il fallait déclarer toutes les variables locales d&#8217;une procédure au début de celle-ci. Ce n&#8217;est pas forcément une mauvaise idée.</p>
<p>Mais en combinant cela avec l&#8217;idée qu&#8217;une variable locale, c&#8217;est forcément de la mémoire utilisée en plus et donc de la &#8220;performance&#8221; en moins, on prend rapidement la bonne habitude de créer le moins de variables locales possibles.</p>
<p>Un exemple de la vraie vie :<br />
<pre class="brush: java; light: true; wrap-lines: false;">
WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()).getAutowireCapableBeanFactory().autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
</pre></p>
<p><strong>Vous trouvez-ça lisible vous ?</strong></p>
<p>C&#8217;est peut-être super excitant à écrire (ah ça c&#8217;est sûr on est fier hein, on a utilisé aucune variable&#8230;). Et PAN, <strong>+10000€</strong> de <strong>dette technique</strong>.</p>
<p>La solution est simple, elle s&#8217;appelle la variable locale. Découpez votre code, créez des variables locales <strong>même si elles ne servent qu&#8217;une fois</strong>.  Et découpez votre code en petites méthodes. </p>
<p>Moins de <strong>5 lignes</strong>, c&#8217;est bien. Au passage, je vous recommande chaudement la lecture de <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882">Clean Code</a> <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>On comprend déjà mieux :<br />
<pre class="brush: java;">
ServletContext servletContext = this.getServletContext();
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();
beanFactory.autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
</pre></p>
<h2>Le fan de programmation fonctionnelle</h2>
<p>Le mec, un jour, il a découvert Google Guava et ses <a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html">Function</a> ; il a trouvé ça trop cool et a adopté le &#8220;style fonctionnel&#8221; dans tous ses développements. Malheureusement, en Java, cela se traduit par des classes anonymes (à moins d&#8217;utiliser <a href="https://github.com/pyricau/FunkyJFunctional">FJF</a>&#8230; pub <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ), et cela déborde vite de l&#8217;écran !</p>
<p>Encore un exemple de la vraie vie, un peu maquillé et allégé pour l&#8217;occasion :<br />
<pre class="brush: java;">
public class MyPanel extends Composite {
	public MyPanel() {
		final Request request = new Request();

		initWidget(new VerticalPanel() {
			{
				add(new HorizontalPanel() {
					{
						add(new RadioButton(&quot;native&quot;, &quot;native&quot;) {
							{
								setValue(request.isNativeRequest());
								addClickHandler(new ClickHandler() {

									public void onClick(ClickEvent event) {
										request.setNativeRequest(getValue());
									}
								});
							}
						});
					}
				});
				add(new Button(&quot;Run&quot;, new ClickHandler() {
					public void onClick(ClickEvent event) {
						ServicesHolder.requestService.execute(request, new AsyncCallback&lt;Response&gt;() {

							public void onFailure(Throwable caught) {
								Window.alert(caught.getMessage());
							}

							public void onSuccess(Response response) {
								try {
									updateUi(response);
								} catch (Exception e) {
									onFailure(e);
								}
							}
						});
					}
				}));
			}
		});
	}
}
</pre></p>
<p>Quand je tombe sur une classe qui comporte 1000 lignes comme ça, j&#8217;ai beaucoup de mal à suivre le <strong>flux d&#8217;exécution</strong>. Pas vous ?</p>
<h2>L&#8217;utilisation d&#8217;une Fluid interface</h2>
<p>Les <a href="http://en.wikipedia.org/wiki/Fluent_interface">Fluid interfaces</a>, par design, sont faites pour permettre les appels chaînés, afin d&#8217;augmenter la lisibilité du code et éventuellement créer des <a href="http://en.wikipedia.org/wiki/Domain-specific_language">DSL</a>.</p>
<p>Si la chaîne d&#8217;appels de méthode est courte et a un sens grammatical, il paraît alors sensé de la laisser sur une ligne, sans que l&#8217;IDE ne formate cette ligne.</p>
<p>Exemple avec un binding <a href="http://code.google.com/p/google-guice/">Guice</a> :<br />
<pre class="brush: java;">
bind(Geek.class).annotatedWith(Piwai.class).toInstance(piwai);
</pre></p>
<p>Par contre, si la chaîne d&#8217;appels est trop longue, à vous de la découper à votre goût sur plusieurs lignes.</p>
<p>Une astuce simple consiste à ajouter &#8220;//&#8221; en fin de ligne, pour empêcher l&#8217;IDE de recoller ensemble des appels de méthodes que l&#8217;on a décidé de séparer.</p>
<p>Par exemple, pour utiliser un <a href="http://code.google.com/p/androidannotations/wiki/SharedPreferencesHelpers">SharedPreferences helper</a> généré par AndroidAnnotations:<br />
<pre class="brush: java;">
prefs.edit() //
  .clear() //
  .name().put(&quot;John Smith&quot;) //
  .age().put(42) //
  .done();
</pre></p>
<p>A vous maintenant : qui a d&#8217;autres exemples de longlignite aigüe ?</p>
<br />Classé dans:<a href='http://blog.piwai.info/category/tech/'>Tech</a> Tagged: <a href='http://blog.piwai.info/tag/clean-code/'>clean code</a>, <a href='http://blog.piwai.info/tag/ide/'>ide</a>, <a href='http://blog.piwai.info/tag/java/'>java</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/piwai.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/piwai.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/piwai.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/piwai.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/piwai.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/piwai.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/piwai.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/piwai.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/piwai.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/piwai.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/piwai.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/piwai.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/piwai.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/piwai.wordpress.com/4/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piwai.info&amp;blog=25920127&amp;post=4&amp;subd=piwai&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piwai.info/2011/08/31/les-ide-et-la-regle-des-80-120/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/06c6a07275076c6b525e2b14018ad78e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pyricau</media:title>
		</media:content>

		<media:content url="http://piwai.files.wordpress.com/2011/08/line_width.png" medium="image">
			<media:title type="html">Maximum line width</media:title>
		</media:content>
	</item>
	</channel>
</rss>
