<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1544564455280664810</id><updated>2011-12-18T02:26:18.101-08:00</updated><category term='vanilla osbi bpm-conseil smile'/><title type='text'>Gael's blog</title><subtitle type='html'>le blog d'un développeur JAVA &lt;strike&gt;open source...&lt;/strike&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>11</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1544564455280664810.post-649424895362212810</id><published>2011-12-18T02:11:00.000-08:00</published><updated>2011-12-18T02:26:18.110-08:00</updated><title type='text'>Pagination en GWT</title><content type='html'>Les interfaces, c'est efficace..... Et ce qui est formidable avec GWT c'est que tout est interfacé. Vous voulez créer votre propre composant et le lier à un SimplePage, aucun problème, il "suffit" de lui faire implémenter HasData.&lt;br /&gt;&lt;br /&gt;Vous trouverez ci-dessous un exemple (simple) pour un FlexTable. Il y a sans doute des choses à revoir, notamment le cas de chargement de données asynchrone, le premier appel de la fonction refresh (sur le onAttach? le onLoad?)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package org.gch.FlexTable;&lt;br /&gt;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;import com.google.gwt.event.shared.HandlerRegistration;&lt;br /&gt;import com.google.gwt.user.client.Element;&lt;br /&gt;import com.google.gwt.user.client.ui.FlexTable;&lt;br /&gt;import com.google.gwt.view.client.HasData;&lt;br /&gt;import com.google.gwt.view.client.Range;&lt;br /&gt;import com.google.gwt.view.client.RangeChangeEvent;&lt;br /&gt;import com.google.gwt.view.client.RowCountChangeEvent;&lt;br /&gt;import com.google.gwt.view.client.RangeChangeEvent.Handler;&lt;br /&gt;import com.google.gwt.view.client.SelectionModel;&lt;br /&gt;&lt;br /&gt;public class FlexTableHasRows extends FlexTable implements HasData&lt;Element&gt; {&lt;br /&gt; &lt;br /&gt; private Range range = new Range(0, 25);&lt;br /&gt; &lt;br /&gt; private Handler handler;&lt;br /&gt; &lt;br /&gt; private boolean isExact = true;&lt;br /&gt; &lt;br /&gt; private int count;&lt;br /&gt;&lt;br /&gt; private SelectionModel&lt;? super Element&gt; selectionModel;&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public HandlerRegistration addRangeChangeHandler(Handler handler) {&lt;br /&gt;  this.handler = handler;&lt;br /&gt;  return addHandler(handler, RangeChangeEvent.getType());&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public HandlerRegistration addRowCountChangeHandler(com.google.gwt.view.client.RowCountChangeEvent.Handler handler) {&lt;br /&gt;  return addHandler(handler, RowCountChangeEvent.getType());&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public Range getVisibleRange() {&lt;br /&gt;  return range;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public boolean isRowCountExact() {&lt;br /&gt;  return isExact;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void setRowCount(int count) {&lt;br /&gt;  this.count = this.getRowCount();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void setRowCount(int count, boolean isExact) {&lt;br /&gt;  this.count = this.getRowCount();&lt;br /&gt;  this.isExact = isExact;&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void setVisibleRange(int start, int length) {&lt;br /&gt;  range = new Range(start, length);&lt;br /&gt;  RangeChangeEvent.fire(this, getVisibleRange());&lt;br /&gt;  refresh();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void setVisibleRange(Range range) {&lt;br /&gt;  this.range = range;&lt;br /&gt;  RangeChangeEvent.fire(this, getVisibleRange());&lt;br /&gt;  refresh();&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public HandlerRegistration addCellPreviewHandler(com.google.gwt.view.client.CellPreviewEvent.Handler&lt;Element&gt; handler) {&lt;br /&gt;  System.out.println("addCellPreviewHandler");&lt;br /&gt;  return null;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public SelectionModel&lt;? super Element&gt; getSelectionModel() {&lt;br /&gt;  return this.selectionModel;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public Element getVisibleItem(int indexOnPage) {&lt;br /&gt;  Element e = this.getRowFormatter().getElement(range.getStart() + indexOnPage);&lt;br /&gt;  return e;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public int getVisibleItemCount() {&lt;br /&gt;  return range.getLength();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public Iterable&lt;Element&gt; getVisibleItems() {&lt;br /&gt;  List&lt;Element&gt; res = new ArrayList&lt;Element&gt;();&lt;br /&gt;  int end = range.getStart() + range.getLength();&lt;br /&gt;  &lt;br /&gt;  if (end &gt; this.getRowCount()) {&lt;br /&gt;   end = this.getRowCount();&lt;br /&gt;  }&lt;br /&gt;  for (int i = range.getStart(); i &lt; end; i++) {&lt;br /&gt;   res.add(this.getRowFormatter().getElement(i));&lt;br /&gt;  }&lt;br /&gt;  return res;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void setRowData(int start, List&lt;? extends Element&gt; values) {&lt;br /&gt;  //todo parse element&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void setSelectionModel(SelectionModel&lt;? super Element&gt; selectionModel) {&lt;br /&gt;  this.selectionModel = selectionModel;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void setVisibleRangeAndClearData(Range range,&lt;br /&gt;   boolean forceRangeChangeEvent) {&lt;br /&gt;  System.out.println("setVisibleRangeAndClearData");&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; //TODO&lt;br /&gt; public void refresh() {&lt;br /&gt;  for (int i = 0; i &lt; this.getRowCount(); i++) {&lt;br /&gt;   this.getRowFormatter().setVisible(i, false);&lt;br /&gt;  }&lt;br /&gt;  int end = range.getStart() + range.getLength();&lt;br /&gt;  &lt;br /&gt;  if (end &gt; this.getRowCount()) {&lt;br /&gt;   end = this.getRowCount();&lt;br /&gt;  }&lt;br /&gt;  for (int i = range.getStart(); i &lt; end; i++) {&lt;br /&gt;   this.getRowFormatter().setVisible(i, true);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Pour l'utilisation:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;&lt;br /&gt;   VerticalPanel v = new VerticalPanel();&lt;br /&gt;   SimlePager p = new SimplePager();&lt;br /&gt;   FlexTableHasRows flex = new FlexTableHasRows();&lt;br /&gt;   &lt;br /&gt;   for (int i = 0; i &lt; 50; i++) {&lt;br /&gt;      flex.setText(i, 0, i + "");&lt;br /&gt;      flex.setText(i, 1, "Text");&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   flex.refresh();&lt;br /&gt;&lt;br /&gt;   p.setDisplay(flex);&lt;br /&gt;   v.add(flex);&lt;br /&gt;   v.add(p);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1544564455280664810-649424895362212810?l=gcharbonnier.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/649424895362212810/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://gcharbonnier.blogspot.com/2011/12/pagination-en-gwt.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/649424895362212810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/649424895362212810'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/2011/12/pagination-en-gwt.html' title='Pagination en GWT'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1544564455280664810.post-6127632681416655908</id><published>2011-06-01T04:38:00.000-07:00</published><updated>2011-06-01T05:13:29.473-07:00</updated><title type='text'>GWT CellTable et OnMouseOver</title><content type='html'>Enfin! J'ai eu l'occasion il y a quelques jours de me remettre à GWT et d'essayer la version 2.3. Après trois ans de développement en version 1.x, j'ai pu mesurer tous les progrès qui ont été fait avec la sortie de la V2. Pour moi qui suis un fervent défenseur de la non utilisation de composant externe à GWT pour la construction d'interface graphique, l'arrivé du composant CellTable est une aubaine. Malheureusement ce composant n'est pas encore tout à fait abouti, il manque notamment le redimensionnement dynamique des colonnes et l'interaction avec la grille n'est pas prévu. Cela étant dit en farfouillant un peu dans les sources il est possible de rendre la grille sensible aux évènements souris. En voici un exemple:&lt;br/&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;package org.gch.tables;&lt;br /&gt;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import com.google.gwt.dom.client.Element;&lt;br /&gt;import com.google.gwt.dom.client.TableCellElement;&lt;br /&gt;import com.google.gwt.dom.client.TableRowElement;&lt;br /&gt;import com.google.gwt.dom.client.TableSectionElement;&lt;br /&gt;import com.google.gwt.user.cellview.client.CellTable;&lt;br /&gt;import com.google.gwt.user.cellview.client.Column;&lt;br /&gt;import com.google.gwt.user.client.Event;&lt;br /&gt;import com.google.gwt.user.client.ui.Widget;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public abstract class MyCellTable&lt;t&gt; extends CellTable&lt;t&gt; {&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public MyCellTable() {&lt;br /&gt;this.setSize("100%", "100%");&lt;br /&gt;this.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);&lt;br /&gt;&lt;br /&gt;sinkEvents(Event.ONMOUSEUP | Event.ONDBLCLICK | Event.ONCONTEXTMENU);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;protected void onBrowserEvent2(Event event) {&lt;br /&gt;super.onBrowserEvent2(event);&lt;br /&gt;&lt;br /&gt;String eventType = event.getType();&lt;br /&gt;final Element target = event.getEventTarget().cast();&lt;br /&gt;&lt;br /&gt;// Find the cell where the event occurred.&lt;br /&gt;TableCellElement tableCell = findNearestParentCell(target);&lt;br /&gt;if (tableCell == null) {&lt;br /&gt;return;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Element trElem = tableCell.getParentElement();&lt;br /&gt;if (trElem == null) {&lt;br /&gt;return;&lt;br /&gt;}&lt;br /&gt;TableRowElement tr = TableRowElement.as(trElem);&lt;br /&gt;Element sectionElem = tr.getParentElement();&lt;br /&gt;if (sectionElem == null) {&lt;br /&gt;return;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;TableSectionElement section = TableSectionElement.as(sectionElem);&lt;br /&gt;&lt;br /&gt;if("mouseover".equals(eventType) &amp;amp;&amp;amp;  tableCell.getCellIndex() == this.getColumnIndex(column)) {&lt;br /&gt;event.preventDefault();&lt;br /&gt;List&lt;t&gt; visibles = this.getVisibleItems();&lt;br /&gt;T o = visibles.get(tr.getSectionRowIndex());&lt;br /&gt;&lt;br /&gt;//Do something with "o"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private TableCellElement findNearestParentCell(Element elem) {&lt;br /&gt;while ((elem != null)) {&lt;br /&gt;String tagName = elem.getTagName();&lt;br /&gt;if ("td".equalsIgnoreCase(tagName)&lt;br /&gt;  || "th".equalsIgnoreCase(tagName)) {&lt;br /&gt; return elem.cast();&lt;br /&gt;}&lt;br /&gt;elem = elem.getParentElement();&lt;br /&gt;}&lt;br /&gt;return null;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1544564455280664810-6127632681416655908?l=gcharbonnier.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/6127632681416655908/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://gcharbonnier.blogspot.com/2011/06/gwt-celltable-et-onmouseover.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/6127632681416655908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/6127632681416655908'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/2011/06/gwt-celltable-et-onmouseover.html' title='GWT CellTable et OnMouseOver'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1544564455280664810.post-8938918630946385029</id><published>2011-05-04T10:28:00.000-07:00</published><updated>2011-05-04T11:51:03.340-07:00</updated><title type='text'>L’évènement du siècle!</title><content type='html'>&lt;div style="text-align: justify;"&gt;Vous êtes au courant, j'en suis certain. Impossible de le manquer! Vendredi 29 avril 2011 a eu lieu la mise en ligne de la version 3.4 de vanilla....&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;En ce qui me concerne c'est un peu comme croiser une ex que je viens tout juste de plaquer. Je ne l'ai pas encore tout à fait oubliée et je dois bien reconnaître qu'elle a de beaux atouts. La version de démo est bluffante, les exemples sont sexy et prometteurs. Les développeurs ont de quoi être contents.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Mais la rupture est consommée et très vite les points de discorde refont surface: plus de 40 downloads disponibles (sans compter les versions mobiles), de nouveaux logiciels alors que certains ne sont pas utilisés, un portail en version inférieur à GWT 2.0 mais surtout qui utilise toujours GWT-ext..... &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Pour filer la métaphore jusqu'au bout, il est possible que cette ex soit plus heureuse aujourd'hui, il n'en reste pas moins que c'est moi qui suis parti et que pour moi c'est une certitude.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1544564455280664810-8938918630946385029?l=gcharbonnier.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/8938918630946385029/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://gcharbonnier.blogspot.com/2011/05/levenement-du-siecle.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/8938918630946385029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/8938918630946385029'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/2011/05/levenement-du-siecle.html' title='L’évènement du siècle!'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1544564455280664810.post-2318175515450749668</id><published>2011-04-22T04:17:00.000-07:00</published><updated>2011-04-22T04:47:29.826-07:00</updated><title type='text'>TETRIS et HTML 5</title><content type='html'>Il y a quelques semaines de cela, après trois ans à utiliser GWT et donc à ne plus avoir à le faire, j'ai du mettre le nez dans du code javascript. Cela fut pour moi l'occasion de faire un tour sur le site de la W3C et de me renseigner un peu plus sur HTML 5 que d'aucun nous annonce comme le remplaçant de flash.&lt;div&gt;Afin de lier l'utile à l'agréable, je me suis lancé dans la réalisation d'un TETRIS tout en javascript.&lt;/div&gt;&lt;div&gt;Vous trouverez le code ci-dessous.&lt;/div&gt;&lt;div&gt;Pour mettre au point ce code il m'aura fallut quelques heures (5 ou 6) ,  ce qui  me parait raisonnable. Au niveau des transformations permises, il est dommage que ce soit le "canvas" qui bouge et non pas les éléments qu'il contient.&lt;/div&gt;&lt;div&gt;Je suis assez fier de ma façon de faire tourner les pièces... Je ne stocke pas toutes les positions possibles mais je n'utilise pas non plus de vraies matrices de rotation (je n'en ai pas trouvé d'évidente, si quelqu'un a je suis preneur). J'utilise la cyclicité des positions mais là non plus sans faire appel à de la congruence stricte.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Quelques liens intéressants:&lt;/div&gt;&lt;div&gt;&lt;a href="http://fr.wikipedia.org/wiki/Tetris"&gt;http://fr.wikipedia.org/wiki/Tetris&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.colinfahey.com/tetris/tetris_en.html"&gt;http://www.colinfahey.com/tetris/tetris_en.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.lafermeduweb.net/billet/-tutorial-creer-un-jeu-web-avec-du-html-5-canvas-et-javascript-390.html"&gt;case briques&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="brush:javascript"&gt;//////////////////////////////////////////&lt;br /&gt;// Les constantes    //&lt;br /&gt;//////////////////////////////////////////&lt;br /&gt;var maxY = 20;&lt;br /&gt;var maxX = 10;&lt;br /&gt;var cellSize = 20;&lt;br /&gt;var startX = 20;&lt;br /&gt;var startY = 20;&lt;br /&gt;var nextX = maxX*20 + startX + 10;&lt;br /&gt;var nextY = startY + 10;&lt;br /&gt;&lt;br /&gt;//////////////////&lt;br /&gt;//La grille     //&lt;br /&gt;//////////////////&lt;br /&gt;var grille = new Array();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;////////////////////////////////////&lt;br /&gt;// Matrices des formes  //&lt;br /&gt;////////////////////////////////////&lt;br /&gt;function initCasesO() {&lt;br /&gt;var casesO = new Array();&lt;br /&gt;casesO[0] = new Array();&lt;br /&gt;casesO[1] = new Array();&lt;br /&gt;casesO[2] = new Array();&lt;br /&gt;casesO[3] = new Array();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;casesO[0][0] = 0;&lt;br /&gt;casesO[0][1] = 0;&lt;br /&gt;casesO[0][2] = 0;&lt;br /&gt;casesO[0][3] = 0;&lt;br /&gt;&lt;br /&gt;casesO[1][0] = 0;&lt;br /&gt;casesO[1][1] = 1;&lt;br /&gt;casesO[1][2] = 1;&lt;br /&gt;casesO[1][3] = 0;&lt;br /&gt;&lt;br /&gt;casesO[2][0] = 0;&lt;br /&gt;casesO[2][1] = 1;&lt;br /&gt;casesO[2][2] = 1;&lt;br /&gt;casesO[2][3] = 0;&lt;br /&gt;&lt;br /&gt;casesO[3][0] = 0;&lt;br /&gt;casesO[3][1] = 0;&lt;br /&gt;casesO[3][2] = 0;&lt;br /&gt;casesO[3][3] = 0;&lt;br /&gt;&lt;br /&gt;return casesO;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function initCasesI() {&lt;br /&gt;var casesI = new Array();&lt;br /&gt;casesI[0] = new Array();&lt;br /&gt;casesI[1] = new Array();&lt;br /&gt;casesI[2] = new Array();&lt;br /&gt;casesI[3] = new Array();&lt;br /&gt;&lt;br /&gt;casesI[0][0] = 0;&lt;br /&gt;casesI[0][1] = 0;&lt;br /&gt;casesI[0][2] = 1;&lt;br /&gt;casesI[0][3] = 0;&lt;br /&gt;&lt;br /&gt;casesI[1][0] = 0;&lt;br /&gt;casesI[1][1] = 0;&lt;br /&gt;casesI[1][2] = 1;&lt;br /&gt;casesI[1][3] = 0;&lt;br /&gt;&lt;br /&gt;casesI[2][0] = 0;&lt;br /&gt;casesI[2][1] = 0;&lt;br /&gt;casesI[2][2] = 1;&lt;br /&gt;casesI[2][3] = 0;&lt;br /&gt;&lt;br /&gt;casesI[3][0] = 0;&lt;br /&gt;casesI[3][1] = 0;&lt;br /&gt;casesI[3][2] = 1;&lt;br /&gt;casesI[3][3] = 0;&lt;br /&gt;&lt;br /&gt;return casesI;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function initCasesS() {&lt;br /&gt;var casesS = new Array();&lt;br /&gt;casesS[0] = new Array();&lt;br /&gt;casesS[1] = new Array();&lt;br /&gt;casesS[2] = new Array();&lt;br /&gt;casesS[3] = new Array();&lt;br /&gt;&lt;br /&gt;casesS[0][0] = 0;&lt;br /&gt;casesS[0][1] = 0;&lt;br /&gt;casesS[0][2] = 0;&lt;br /&gt;casesS[0][3] = 0;&lt;br /&gt;&lt;br /&gt;casesS[1][0] = 0;&lt;br /&gt;casesS[1][1] = 0;&lt;br /&gt;casesS[1][2] = 1;&lt;br /&gt;casesS[1][3] = 1;&lt;br /&gt;&lt;br /&gt;casesS[2][0] = 0;&lt;br /&gt;casesS[2][1] = 1;&lt;br /&gt;casesS[2][2] = 1;&lt;br /&gt;casesS[2][3] = 0;&lt;br /&gt;&lt;br /&gt;casesS[3][0] = 0;&lt;br /&gt;casesS[3][1] = 0;&lt;br /&gt;casesS[3][2] = 0;&lt;br /&gt;casesS[3][3] = 0;&lt;br /&gt;&lt;br /&gt;return casesS;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function initCasesZ() {&lt;br /&gt;var casesZ = new Array();&lt;br /&gt;casesZ[0] = new Array();&lt;br /&gt;casesZ[1] = new Array();&lt;br /&gt;casesZ[2] = new Array();&lt;br /&gt;casesZ[3] = new Array();&lt;br /&gt;&lt;br /&gt;casesZ[0][0] = 0;&lt;br /&gt;casesZ[0][1] = 0;&lt;br /&gt;casesZ[0][2] = 0;&lt;br /&gt;casesZ[0][3] = 0;&lt;br /&gt;&lt;br /&gt;casesZ[1][0] = 0;&lt;br /&gt;casesZ[1][1] = 1;&lt;br /&gt;casesZ[1][2] = 1;&lt;br /&gt;casesZ[1][3] = 0;&lt;br /&gt;&lt;br /&gt;casesZ[2][0] = 0;&lt;br /&gt;casesZ[2][1] = 0;&lt;br /&gt;casesZ[2][2] = 1;&lt;br /&gt;casesZ[2][3] = 1;&lt;br /&gt;&lt;br /&gt;casesZ[3][0] = 0;&lt;br /&gt;casesZ[3][1] = 0;&lt;br /&gt;casesZ[3][2] = 0;&lt;br /&gt;casesZ[3][3] = 0;&lt;br /&gt;&lt;br /&gt;return casesZ;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function initCasesL() {&lt;br /&gt;var casesL = new Array();&lt;br /&gt;casesL[0] = new Array();&lt;br /&gt;casesL[1] = new Array();&lt;br /&gt;casesL[2] = new Array();&lt;br /&gt;casesL[3] = new Array();&lt;br /&gt;&lt;br /&gt;casesL[0][0] = 0;&lt;br /&gt;casesL[0][1] = 0.25;&lt;br /&gt;casesL[0][2] = 0.5;&lt;br /&gt;casesL[0][3] = 0.5;&lt;br /&gt;&lt;br /&gt;casesL[1][0] = 0;&lt;br /&gt;casesL[1][1] = 1;&lt;br /&gt;casesL[1][2] = 1;&lt;br /&gt;casesL[1][3] = 1;&lt;br /&gt;&lt;br /&gt;casesL[2][0] = 0;&lt;br /&gt;casesL[2][1] = 1;&lt;br /&gt;casesL[2][2] = 0.5;&lt;br /&gt;casesL[2][3] = 0.75;&lt;br /&gt;&lt;br /&gt;casesL[3][0] = 0;&lt;br /&gt;casesL[3][1] = 0;&lt;br /&gt;casesL[3][2] = 0;&lt;br /&gt;casesL[3][3] = 0;&lt;br /&gt;&lt;br /&gt;return casesL;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function initCasesJ() {&lt;br /&gt;var casesJ = new Array();&lt;br /&gt;casesJ[0] = new Array();&lt;br /&gt;casesJ[1] = new Array();&lt;br /&gt;casesJ[2] = new Array();&lt;br /&gt;casesJ[3] = new Array();&lt;br /&gt;&lt;br /&gt;casesJ[0][0] = 0;&lt;br /&gt;casesJ[0][1] = 0.5;&lt;br /&gt;casesJ[0][2] = 0.5;&lt;br /&gt;casesJ[0][3] = 0.75;&lt;br /&gt;&lt;br /&gt;casesJ[1][0] = 0;&lt;br /&gt;casesJ[1][1] = 1;&lt;br /&gt;casesJ[1][2] = 1;&lt;br /&gt;casesJ[1][3] = 1;&lt;br /&gt;&lt;br /&gt;casesJ[2][0] = 0;&lt;br /&gt;casesJ[2][1] = 0.25;&lt;br /&gt;casesJ[2][2] = 0.5;&lt;br /&gt;casesJ[2][3] = 1;&lt;br /&gt;&lt;br /&gt;casesJ[3][0] = 0;&lt;br /&gt;casesJ[3][1] = 0;&lt;br /&gt;casesJ[3][2] = 0;&lt;br /&gt;casesJ[3][3] = 0;&lt;br /&gt;&lt;br /&gt;return casesJ;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function initCasesT() {&lt;br /&gt;var casesT = new Array();&lt;br /&gt;casesT[0] = new Array();&lt;br /&gt;casesT[1] = new Array();&lt;br /&gt;casesT[2] = new Array();&lt;br /&gt;casesT[3] = new Array();&lt;br /&gt;&lt;br /&gt;casesT[0][0] = 0;&lt;br /&gt;casesT[0][1] = 0;&lt;br /&gt;casesT[0][2] = 0;&lt;br /&gt;casesT[0][3] = 0;&lt;br /&gt;&lt;br /&gt;casesT[1][0] = 0;&lt;br /&gt;casesT[1][1] = 3;&lt;br /&gt;casesT[1][2] = 1;&lt;br /&gt;casesT[1][3] = 1;&lt;br /&gt;&lt;br /&gt;casesT[2][0] = 0;&lt;br /&gt;casesT[2][1] = 0;&lt;br /&gt;casesT[2][2] = 2;&lt;br /&gt;casesT[2][3] = 0;&lt;br /&gt;&lt;br /&gt;casesT[3][0] = 0;&lt;br /&gt;casesT[3][1] = 0;&lt;br /&gt;casesT[3][2] = 0;&lt;br /&gt;casesT[3][3] = 0;&lt;br /&gt;&lt;br /&gt;return casesT;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//////////////////////////&lt;br /&gt;// Matrices de "rotation"//&lt;br /&gt;/////////////////////////&lt;br /&gt;var rotateI = new Array();&lt;br /&gt;rotateI[0] = new Array();&lt;br /&gt;rotateI[1] = new Array();&lt;br /&gt;rotateI[2] = new Array();&lt;br /&gt;rotateI[3] = new Array();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;rotateI[0][0] = 0;&lt;br /&gt;rotateI[0][1] = 0;&lt;br /&gt;rotateI[0][2] = 1;&lt;br /&gt;rotateI[0][3] = 0;&lt;br /&gt;&lt;br /&gt;rotateI[1][0] = 1;&lt;br /&gt;rotateI[1][1] = 1;&lt;br /&gt;rotateI[1][2] = 0;&lt;br /&gt;rotateI[1][3] = 1;&lt;br /&gt;&lt;br /&gt;rotateI[2][0] = 0;&lt;br /&gt;rotateI[2][1] = 0;&lt;br /&gt;rotateI[2][2] = 1;&lt;br /&gt;rotateI[2][3] = 0;&lt;br /&gt;&lt;br /&gt;rotateI[3][0] = 0;&lt;br /&gt;rotateI[3][1] = 0;&lt;br /&gt;rotateI[3][2] = 1;&lt;br /&gt;rotateI[3][3] = 0;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;var rotateS = new Array();&lt;br /&gt;rotateS[0] = new Array();&lt;br /&gt;rotateS[1] = new Array();&lt;br /&gt;rotateS[2] = new Array();&lt;br /&gt;rotateS[3] = new Array();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;rotateS[0][0] = 0;&lt;br /&gt;rotateS[0][1] = 0;&lt;br /&gt;rotateS[0][2] = 1;&lt;br /&gt;rotateS[0][3] = 0;&lt;br /&gt;&lt;br /&gt;rotateS[1][0] = 0;&lt;br /&gt;rotateS[1][1] = 0;&lt;br /&gt;rotateS[1][2] = 0;&lt;br /&gt;rotateS[1][3] = 0;&lt;br /&gt;&lt;br /&gt;rotateS[2][0] = 0;&lt;br /&gt;rotateS[2][1] = 1;&lt;br /&gt;rotateS[2][2] = 1;&lt;br /&gt;rotateS[2][3] = 1;&lt;br /&gt;&lt;br /&gt;rotateS[3][0] = 0;&lt;br /&gt;rotateS[3][1] = 0;&lt;br /&gt;rotateS[3][2] = 0;&lt;br /&gt;rotateS[3][3] = 0;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;var rotateZ = new Array();&lt;br /&gt;rotateZ[0] = new Array();&lt;br /&gt;rotateZ[1] = new Array();&lt;br /&gt;rotateZ[2] = new Array();&lt;br /&gt;rotateZ[3] = new Array();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;rotateZ[0][0] = 0;&lt;br /&gt;rotateZ[0][1] = 0;&lt;br /&gt;rotateZ[0][2] = 0;&lt;br /&gt;rotateZ[0][3] = 1;&lt;br /&gt;&lt;br /&gt;rotateZ[1][0] = 0;&lt;br /&gt;rotateZ[1][1] = 1;&lt;br /&gt;rotateZ[1][2] = 0;&lt;br /&gt;rotateZ[1][3] = 1;&lt;br /&gt;&lt;br /&gt;rotateZ[2][0] = 0;&lt;br /&gt;rotateZ[2][1] = 0;&lt;br /&gt;rotateZ[2][2] = 0;&lt;br /&gt;rotateZ[2][3] = 1;&lt;br /&gt;&lt;br /&gt;rotateZ[3][0] = 0;&lt;br /&gt;rotateZ[3][1] = 0;&lt;br /&gt;rotateZ[3][2] = 0;&lt;br /&gt;rotateZ[3][3] = 0;&lt;br /&gt;&lt;br /&gt;var rotateL = new Array();&lt;br /&gt;rotateL[0] = new Array();&lt;br /&gt;rotateL[1] = new Array();&lt;br /&gt;rotateL[2] = new Array();&lt;br /&gt;rotateL[3] = new Array();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;rotateL[0][0] = 0;&lt;br /&gt;rotateL[0][1] = 0.25;&lt;br /&gt;rotateL[0][2] = 0.5;&lt;br /&gt;rotateL[0][3] = 0.25;&lt;br /&gt;&lt;br /&gt;rotateL[1][0] = 0;&lt;br /&gt;rotateL[1][1] = 0.5;&lt;br /&gt;rotateL[1][2] = 1;&lt;br /&gt;rotateL[1][3] = 0.5;&lt;br /&gt;&lt;br /&gt;rotateL[2][0] = 0;&lt;br /&gt;rotateL[2][1] = 0.25;&lt;br /&gt;rotateL[2][2] = 0.5;&lt;br /&gt;rotateL[2][3] = 0.25;&lt;br /&gt;&lt;br /&gt;rotateL[3][0] = 0;&lt;br /&gt;rotateL[3][1] = 0;&lt;br /&gt;rotateL[3][2] = 0;&lt;br /&gt;rotateL[3][3] = 0;&lt;br /&gt;&lt;br /&gt;var rotateJ = new Array();&lt;br /&gt;rotateJ[0] = new Array();&lt;br /&gt;rotateJ[1] = new Array();&lt;br /&gt;rotateJ[2] = new Array();&lt;br /&gt;rotateJ[3] = new Array();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;rotateJ[0][0] = 0;&lt;br /&gt;rotateJ[0][1] = 0.25;&lt;br /&gt;rotateJ[0][2] = 0.5;&lt;br /&gt;rotateJ[0][3] = 0.25;&lt;br /&gt;&lt;br /&gt;rotateJ[1][0] = 0;&lt;br /&gt;rotateJ[1][1] = 0.5;&lt;br /&gt;rotateJ[1][2] = 1;&lt;br /&gt;rotateJ[1][3] = 0.5;&lt;br /&gt;&lt;br /&gt;rotateJ[2][0] = 0;&lt;br /&gt;rotateJ[2][1] = 0.25;&lt;br /&gt;rotateJ[2][2] = 0.5;&lt;br /&gt;rotateJ[2][3] = 0.25;&lt;br /&gt;&lt;br /&gt;rotateJ[3][0] = 0;&lt;br /&gt;rotateJ[3][1] = 0;&lt;br /&gt;rotateJ[3][2] = 0;&lt;br /&gt;rotateJ[3][3] = 0;&lt;br /&gt;&lt;br /&gt;var rotateT = new Array();&lt;br /&gt;rotateT[0] = new Array();&lt;br /&gt;rotateT[1] = new Array();&lt;br /&gt;rotateT[2] = new Array();&lt;br /&gt;rotateT[3] = new Array();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;rotateT[0][0] = 0;&lt;br /&gt;rotateT[0][1] = 0;&lt;br /&gt;rotateT[0][2] = 1;&lt;br /&gt;rotateT[0][3] = 0;&lt;br /&gt;&lt;br /&gt;rotateT[1][0] = 0;&lt;br /&gt;rotateT[1][1] = 1;&lt;br /&gt;rotateT[1][2] = 0;&lt;br /&gt;rotateT[1][3] = 1;&lt;br /&gt;&lt;br /&gt;rotateT[2][0] = 0;&lt;br /&gt;rotateT[2][1] = 0;&lt;br /&gt;rotateT[2][2] = 1;&lt;br /&gt;rotateT[2][3] = 0;&lt;br /&gt;&lt;br /&gt;rotateT[3][0] = 0;&lt;br /&gt;rotateT[3][1] = 0;&lt;br /&gt;rotateT[3][2] = 0;&lt;br /&gt;rotateT[3][3] = 0;&lt;br /&gt;&lt;br /&gt;/////////////////////////////&lt;br /&gt;// Les objets   //&lt;br /&gt;/////////////////////////////&lt;br /&gt;function Figure(forme) {&lt;br /&gt;this.currentX = 3;&lt;br /&gt;this.currentY = -1;&lt;br /&gt;this.forme = forme;&lt;br /&gt;this.color = forme.color;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Figure.prototype.descendre = function() {&lt;br /&gt;this.currentY++;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Figure.prototype.moveR = function() {&lt;br /&gt;this.currentX++;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Figure.prototype.moveL = function() {&lt;br /&gt;this.currentX--;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Figure.prototype.rotate = function() {&lt;br /&gt;this.forme.rotate();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function Forme(cases, color, type) {&lt;br /&gt;this.color = color&lt;br /&gt;this.cases = cases;&lt;br /&gt;this.type = type;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Forme.prototype.rotate = function() {&lt;br /&gt;if (this.type == 'I') {&lt;br /&gt;for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     this.cases[i][j] = (this.cases[i][j] + rotateI[i][j])%2;    }   }  }  else if (this.type == 'S') {   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     this.cases[i][j] = (this.cases[i][j] + rotateS[i][j])%2;    }   }    }  else if (this.type == 'Z') {   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     this.cases[i][j] = (this.cases[i][j] + rotateZ[i][j])%2;    }   }  }  else if (this.type == 'L') {   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     if(this.cases[i][j] == 1) {      this.cases[i][j] = 0;     }     this.cases[i][j] = (this.cases[i][j] + rotateL[i][j]);    }   }  }  else if (this.type == 'J') {   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     if(this.cases[i][j] == 1) {      this.cases[i][j] = 0;     }     this.cases[i][j] = (this.cases[i][j] + rotateJ[i][j]);    }   }  }  else if (this.type == 'T') {   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     this.cases[i][j] = (this.cases[i][j] + rotateT[i][j])%4;    }   }  } }  Forme.prototype.simuleRotate = function() {  var newArray = new Array();  for (var i = 0; i &amp;lt; 4; i++) {   newArray[i] = new Array();   for (var j = 0; j &amp;lt; 4; j++) {    newArray[i][j] = this.cases[i][j];   }  }    if (this.type == 'I') {   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     newArray[i][j] = (newArray[i][j] + rotateI[i][j])%2;    }   }  }  else if (this.type == 'S') {   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     newArray[i][j] = (newArray[i][j] + rotateS[i][j])%2;    }   }  }  else if (this.type == 'Z') {   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     newArray[i][j] = (newArray[i][j] + rotateZ[i][j])%2;    }   }  }  else if (this.type == 'L') {   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     if(newArray[i][j] == 1) {      newArray[i][j] = 0;     }     newArray[i][j] = (newArray[i][j] + rotateL[i][j]);    }   }  }  else if (this.type == 'J') {   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     if(newArray[i][j] == 1) {      newArray[i][j] = 0;     }     newArray[i][j] = (newArray[i][j] + rotateJ[i][j]);    }   }  }  else if (this.type == 'T') {   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     newArray[i][j] = (newArray[i][j] + rotateT[i][j])%4;    }   }  }     return newArray; }   //////////////////////////////////// //Initialisation   // /////////////////////////////////// var fig = randomFigure(); var next = randomFigure(); var ctx;  var choice = 0;  function initGrille() {  for (var i = 0; i &amp;lt; 20; i++) {   grille[i] = new Array();  } }  window.addEventListener('load', function () {   initGrille();      var c = document.getElementById("myCanvas");  ctx = c.getContext("2d");  // Boucle de rafraichissement du contexte 2D  boucleJeu = setInterval(refresh, 200);      // Gestion des évènements    window.document.onkeydown = checkDeplace;   }, false);    function refresh() {   var c=document.getElementById("myCanvas");  ctx=c.getContext("2d");  ctx.fillStyle = "#ffffff";  ctx.clearRect(0, 0, 500, 500);  ctx.fill();     ctx.fillStyle = "#000000";  ctx.moveTo(startX, startY);  ctx.lineTo(startX, startY + maxY*cellSize);  ctx.lineTo(startX + maxX*cellSize, startY + maxY*cellSize);    ctx.stroke();   //Affichage de la figure  for (var i = 0; i &amp;lt; 4; i++) {   for (var j = 0; j &amp;lt; 4; j++) {    if (fig.forme.cases[i][j] &amp;gt;= 1) {&lt;br /&gt;  ctx.fillStyle = fig.color;&lt;br /&gt;  ctx.fillRect((fig.currentX + j)* cellSize + startX, (fig.currentY + i) * cellSize + startY, cellSize, cellSize);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Affichage des cases remplies&lt;br /&gt;for (var i = 0; i &amp;lt; 20; i++) {   for (var j = 0; j &amp;lt; 10; j++) {    if (undefined != grille[i][j]) {     ctx.fillStyle = grille[i][j];     ctx.fillRect((j+1)* cellSize, (i+1) * cellSize, cellSize, cellSize);    }   }  }    //Affichage de la prochaine figure  for (var i = 0; i &amp;lt; 4; i++) {   for (var j = 0; j &amp;lt; 4; j++) {    if (next.forme.cases[i][j] &amp;gt;= 1) {&lt;br /&gt;  ctx.fillStyle = next.color;&lt;br /&gt;  ctx.fillRect(nextX + j* cellSize, nextY + i * cellSize, cellSize, cellSize);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if (canMoveDown()) {&lt;br /&gt;fig.descendre();&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;fillGrid();&lt;br /&gt;treatLine();&lt;br /&gt;&lt;br /&gt;if (grille[0][6]  == undefined)  {&lt;br /&gt; fig = next;&lt;br /&gt; next = randomFigure();&lt;br /&gt;}&lt;br /&gt;else  {&lt;br /&gt; return;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function randomFigure() {&lt;br /&gt;var _fig;&lt;br /&gt;choice = Math.floor(Math.random()*7);&lt;br /&gt;if (choice == 0) {&lt;br /&gt;_fig = new Figure(new Forme(initCasesO(), "#FFFF00", 'O'));&lt;br /&gt;}&lt;br /&gt;else if (choice == 1) {&lt;br /&gt;_fig = new Figure(new Forme(initCasesS(), "#008000", 'S'));&lt;br /&gt;}&lt;br /&gt;else  if (choice == 2) {&lt;br /&gt;_fig = new Figure(new Forme(initCasesI(), "#00FFFF", 'I'));&lt;br /&gt;}&lt;br /&gt;else if (choice == 3) {&lt;br /&gt;_fig = new Figure(new Forme(initCasesZ(), "#FF0000", 'Z'));&lt;br /&gt;}&lt;br /&gt;else if (choice == 4) {&lt;br /&gt;_fig = new Figure(new Forme(initCasesL(), "#FFA500", 'L'));&lt;br /&gt;}&lt;br /&gt;else if (choice == 5) {&lt;br /&gt;_fig = new Figure(new Forme(initCasesJ(), "#0000FF", 'J'));&lt;br /&gt;}&lt;br /&gt;else if (choice == 6) {&lt;br /&gt;_fig = new Figure(new Forme(initCasesT(), "#FF00FF", 'T'));&lt;br /&gt;}&lt;br /&gt;return _fig;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*Looking for line to be deleted*/&lt;br /&gt;function treatLine() {&lt;br /&gt;var linesToDelete = new Array();&lt;br /&gt;for (var i = 0; i &amp;lt; 20; i++) {   var del = true;   for (var j = 0; j &amp;lt; 10; j++) {    if (undefined == grille[i][j]) {     del = false;     break;    }   }   if (del == true) {    linesToDelete[linesToDelete.length] = i;   }  }    var deleted = 0;  for (var l = linesToDelete.length - 1; l &amp;gt; -1; l--) {&lt;br /&gt;deleteLine(linesToDelete[l]  + deleted);&lt;br /&gt;deleted++;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*Delete line*/&lt;br /&gt;function deleteLine(l) {&lt;br /&gt;for (var i = 19; i &amp;gt; 0; i--) {&lt;br /&gt;for (var j = 0; j &amp;lt; 10; j++) {    if (i &amp;lt;= l) {     grille[i][j] = grille[i-1][j];    }   }  } }  /*Fill the grid with the coordinate of the figure which is stopped*/ function fillGrid() {  for (var i = 0; i &amp;lt; 4; i++) {   for (var j = 0; j &amp;lt; 4; j++) {    if (fig.forme.cases[i][j] &amp;gt;= 1) {&lt;br /&gt;  grille[fig.currentY + i][fig.currentX + j] = fig.color;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*Check if the figure can move down*/&lt;br /&gt;function canMoveDown() {&lt;br /&gt;if (fig.currentY + 4 == maxY) {&lt;br /&gt;for (var j = 0; j &amp;lt; 4; j++) {    if (fig.forme.cases[3][j] &amp;gt;= 1) {&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;else if (fig.currentY + 4 == maxY + 1) {&lt;br /&gt;for (var j = 0; j &amp;lt; 4; j++) {    if (fig.forme.cases[2][j] &amp;gt;= 1) {&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;else if (fig.currentY + 4 == maxY + 2) {&lt;br /&gt;for (var j = 0; j &amp;lt; 4; j++) {    if (fig.forme.cases[1][j] &amp;gt;= 1) {&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;for (var i = 0; i &amp;lt; 4; i++) {   for (var j = 0; j &amp;lt; 4; j++) {    if (fig.forme.cases[i][j] &amp;gt;= 1) {&lt;br /&gt;  if (undefined != grille[fig.currentY + i + 1][fig.currentX + j]) {&lt;br /&gt;   return false;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return true;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*Check if a figure can flip*/&lt;br /&gt;function isFlipValide(array) {&lt;br /&gt;for (var i = 0; i &amp;lt; 4; i++) {   for (var j = 0; j &amp;lt; 4; j++) {    if (array[i][j] &amp;gt;= 1 ) {&lt;br /&gt;  if (fig.currentX + j &amp;lt; 0 || fig.currentY + i &amp;gt;= maxY || fig.currentX + j &amp;gt;= maxX || grille[fig.currentY + i][fig.currentX + j] != undefined) {&lt;br /&gt;   return false;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return true;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*Check if a figure move: left, right or flip*/&lt;br /&gt;function checkDeplace(e) {&lt;br /&gt;// Flêche de droite préssée&lt;br /&gt;if (e.keyCode == 39) {&lt;br /&gt;var test = true;&lt;br /&gt;for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     if (fig.forme.cases[i][j] &amp;gt;= 1) {&lt;br /&gt;   //La figure est contre la bordure droite&lt;br /&gt;   if (fig.currentX + j + 1 == maxX) {&lt;br /&gt;    test = false;&lt;br /&gt;    break;&lt;br /&gt;   }&lt;br /&gt;   //Il y a une figure à droite&lt;br /&gt;   else if (fig.currentX + j + 1 &amp;lt; maxX &amp;amp;&amp;amp; grille[fig.currentY + i][fig.currentX + j + 1] != undefined) {       test = false;       break;      }     }    }   }   if (test) {    fig.moveR();   }  }  // Flêche de gauche préssée  else if (e.keyCode == 37) {   var test = true;   for (var i = 0; i &amp;lt; 4; i++) {    for (var j = 0; j &amp;lt; 4; j++) {     if (fig.forme.cases[i][j] &amp;gt;= 1) {&lt;br /&gt;   //La figure est contre la bordure gauche&lt;br /&gt;   if (fig.currentX + j == 0) {&lt;br /&gt;    test = false;&lt;br /&gt;    break;&lt;br /&gt;   }&lt;br /&gt;   //Il y a une figure à gauche&lt;br /&gt;   else if (fig.currentX + j - 1 &amp;gt; -1 &amp;amp;&amp;amp; grille[fig.currentY + i][fig.currentX + j - 1] != undefined) {&lt;br /&gt;    test = false;&lt;br /&gt;    break;&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;if (test) {&lt;br /&gt; fig.moveL();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;else if(e.keyCode == 32) {&lt;br /&gt;if (isFlipValide(fig.forme.simuleRotate()) == true) {&lt;br /&gt; fig.rotate();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function pause(millis)  {&lt;br /&gt;var date = new Date();&lt;br /&gt;var curDate = null;&lt;br /&gt;&lt;br /&gt;do {&lt;br /&gt;curDate = new Date();&lt;br /&gt;}&lt;br /&gt;while(curDate-date &amp;lt; millis); }    &lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1544564455280664810-2318175515450749668?l=gcharbonnier.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/2318175515450749668/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://gcharbonnier.blogspot.com/2011/04/html-5-mon-amour.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/2318175515450749668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/2318175515450749668'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/2011/04/html-5-mon-amour.html' title='TETRIS et HTML 5'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1544564455280664810.post-5056991769096992198</id><published>2011-01-20T07:55:00.000-08:00</published><updated>2011-01-20T08:00:59.938-08:00</updated><title type='text'>Voeux</title><content type='html'>Ô toi surfeur égaré qui lit ses quelques lignes, je te souhaite une bonne et heureuse année 2011.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pour moi cette année est déjà l'année du renouveau. En effet je change de société et par la même occasion de statu aussi je ne ferai plus de développements open-source.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Les trois années passées chez BPM auront été riches en apprentissage tant technique qu'humain, tant positif que négatif....&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1544564455280664810-5056991769096992198?l=gcharbonnier.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/5056991769096992198/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://gcharbonnier.blogspot.com/2011/01/voeux.html#comment-form' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/5056991769096992198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/5056991769096992198'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/2011/01/voeux.html' title='Voeux'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1544564455280664810.post-725543232939154839</id><published>2010-10-24T02:00:00.000-07:00</published><updated>2010-10-24T02:21:19.781-07:00</updated><title type='text'>Laveur de cerveaux?</title><content type='html'>Cette semaine, plusieurs articles ont eu comme sujet "Power Point". Ils ont pour origine le livre de Franck Frommer,  «Pensée Powerpoint : enquête sur un logiciel qui rend stupide».&lt;br /&gt;L'article de &lt;a href="http://www.telerama.fr/"&gt;Télérama &lt;/a&gt;sur le sujet conclue : "Le problème ce n'est pas le logiciel lui-même, mais l'usage que l'on en fait. Ça ne fait que valoriser une façon de penser, l'idéologie dominante: simplicité, efficacité, moindre coût."&lt;div&gt;Cette conclusion s'applique elle aussi au logiciel de la BI. En effet, lorsque qu'un non informaticien me demande à quoi sert la BI, je réponds "la BI a pour but de rendre intelligible les données que stocke une entreprise". Cet objectif est noble et nécessaire tant la quantité de données stockées est importantes. Hélas, les outils dont nous disposons ont les mêmes travers que les PPT. Ansi, les solutions uniquement "sexy" et rapide à mettre en place sont privilégiées à la mise en place de solutions viables et pertinentes, ses dernières nécessitant temps et réflexion donc argent.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1544564455280664810-725543232939154839?l=gcharbonnier.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/725543232939154839/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://gcharbonnier.blogspot.com/2010/10/laveur-de-cerveaux.html#comment-form' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/725543232939154839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/725543232939154839'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/2010/10/laveur-de-cerveaux.html' title='Laveur de cerveaux?'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1544564455280664810.post-9014538859932916021</id><published>2010-07-27T04:34:00.000-07:00</published><updated>2010-07-29T06:17:55.847-07:00</updated><title type='text'>Une api GTW partagée</title><content type='html'>Le but de ce post est de montrer comment créer simplement dans eclipse une api graphique GWT réutilisable dans plusieurs projets.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Pré-requis&lt;/span&gt;:&lt;br /&gt;Avoir sur son poste une version d'éclipse contenant le plugin GWT ce dernier correctement configurer pour utiliser une version 2.x de l'api GWT.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Etape 1: création du projet.&lt;/span&gt;&lt;br /&gt;En cliquant sur l'icône de création d'un projet GWT la fenêtre ci-dessous s'affiche. Pour l'exemple j'ai choisi d'appeler mon projet ApiGwt avec comme package principal org.graphical.api:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XuU6jH6grbY/TFFw3FiqY9I/AAAAAAAAABI/KnD6THAub3U/s1600/2010-07-29_141437.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 292px;" src="http://2.bp.blogspot.com/_XuU6jH6grbY/TFFw3FiqY9I/AAAAAAAAABI/KnD6THAub3U/s400/2010-07-29_141437.png" alt="" id="BLOGGER_PHOTO_ID_5499300711678763986" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Par défaut GWT créé des classes d'exemples. Supprimer toutes les classes existantes ainsi que les packages org.graphical.api.server et org.graphical.api.shared&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Etape 2: mise à jour du fichier XML de déclaration du module.&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span&gt;Editer le fichier ApiGwt.gwt.xml et modifier le en supprimant les lignes surlignées en jaunes ci dessous.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XuU6jH6grbY/TFFyZ9U9PUI/AAAAAAAAABQ/TmGW1UxUKfk/s1600/2010-07-28_145939.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 164px;" src="http://4.bp.blogspot.com/_XuU6jH6grbY/TFFyZ9U9PUI/AAAAAAAAABQ/TmGW1UxUKfk/s400/2010-07-28_145939.png" alt="" id="BLOGGER_PHOTO_ID_5499302410280844610" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Le projet est maintenant prêt et peut-être utiliser pour créer les classes que l'on souhaite partager.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Etape 3: Création d'une classe simple.&lt;/span&gt;&lt;br /&gt;Afin d'avoir un plus grande lisibilité dans le code source, il est intéressant de créer un nouveau dossier source. Pour cela faire un clic droit sur le projet puis new -&gt; source folder&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XuU6jH6grbY/TFFzd661lqI/AAAAAAAAABY/sERw-JQiM_w/s1600/2010-07-29_140141.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 210px;" src="http://4.bp.blogspot.com/_XuU6jH6grbY/TFFzd661lqI/AAAAAAAAABY/sERw-JQiM_w/s400/2010-07-29_140141.png" alt="" id="BLOGGER_PHOTO_ID_5499303577865524898" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;J'ai appelé "ui" ce nouveau dossier source. Dans ce dossier il faut créer deux packages:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;org.graphical.api.client.ui&lt;/li&gt;&lt;li&gt;org.graphical.api.client.ui.dialogs&lt;/li&gt;&lt;/ul&gt;Il est maintenant nécessaire de déclarer ces packages comme étant des modules GWT. Pour cela dans le package org.graphical.api.client.ui il faut créer un fichier ApiGwtUI.gwt.xml. Le contenu de ce fichier est le suivant:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&lt;!-- DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6.4//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.6.4/distro-source/core/src/gwt-module.dtd"--&gt;&lt;br /&gt;&lt;module to="apigwtui"&gt;&lt;br /&gt;&lt;!-- Inherit the core Web Toolkit stuff.                        --&gt;&lt;br /&gt;&lt;inherits name="com.google.gwt.user.User"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/inherits&gt;&lt;br /&gt;&lt;/module&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note: penser à décommenter le doctype.&lt;br /&gt;&lt;br /&gt;Afin de fournir un exemple, dans le package org.graphical.api.client.ui.dialogs, je créé la classe MyDialog dont le code est:&lt;br /&gt;&lt;pre class="brush:java"&gt;&lt;br /&gt;package org.graphical.api.client.ui.dialogs;&lt;br /&gt;&lt;br /&gt;import com.google.gwt.user.client.ui.DialogBox;&lt;br /&gt;import com.google.gwt.user.client.ui.HTML;&lt;br /&gt;&lt;br /&gt;public class MyDialog extends DialogBox {&lt;br /&gt;&lt;br /&gt; public MyDialog() {&lt;br /&gt;    super();&lt;br /&gt;    this.setText("Mon titre");&lt;br /&gt;    this.setWidget(new HTML("Bla bla bla"));&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-weight: bold;"&gt;Etape 4: déclaration du nouveau module dans le fichier XML de déclaration principal.&lt;br /&gt;&lt;/span&gt;Pour cela il suffit de rajouter la ligne suivante dans le fichier ApiGwt.gwt.xm:&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&lt;!-- Other module inherits                                      --&gt;&lt;br /&gt;&lt;inherits name="org.graphical.api.client.ui.ApiGwtUI"&gt;&lt;br /&gt;&lt;/inherits&gt;&lt;/pre&gt;A ce stade il est possible d'exporter les packages créés sous forme de jar afin de les utiliser dans un autre projet GWT. Le soucis est que pour le moment nous n'avons pas testé notre classe.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Etape 5: création d'un package de tests.&lt;br /&gt;&lt;/span&gt;Afin de bien séparer les tests du reste je créé un nouveau dossier source nommé "tests". Dans ce dossier je créé deux packages:&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;org.graphical.api.tests&lt;/li&gt;&lt;li&gt;org.graphical.api.tests.client&lt;/li&gt;&lt;/ul&gt;Dans le premier package (org.graphical.api.tests), je crée le fichier de déclaration d'un module GWT: ApiGwtTests.gwt.xml dont le contenu est:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&lt;!-- DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6.4//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.6.4/distro-source/core/src/gwt-module.dtd"--&gt;&lt;br /&gt;&lt;module to="apigwttests"&gt;&lt;br /&gt;&lt;!-- Inherit the core Web Toolkit stuff.                        --&gt;&lt;br /&gt;&lt;inherits name="com.google.gwt.user.User"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;inherits name="com.google.gwt.user.theme.standard.Standard"&gt;&lt;br /&gt;&lt;inherits name="org.graphical.api.ApiGwt"&gt;&lt;br /&gt;&lt;br /&gt;&lt;entry-point class="org.graphical.api.tests.client.Tests"&gt;&lt;br /&gt;&lt;br /&gt;&lt;source path="client"&gt;&lt;br /&gt;&lt;/entry-point&gt;&lt;/inherits&gt;&lt;/inherits&gt;&lt;/inherits&gt;&lt;/module&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;La ligne  &lt;pre class="brush:xml"&gt;&lt;entry-point class="org.graphical.api.tests.client.Tests"&gt;&lt;/entry-point&gt;&lt;/pre&gt;&lt;br /&gt;permet de déclarer quelle est la classe qui implémente "EntryPoint".&lt;br /&gt;&lt;br /&gt;Dans le deuxième package org.graphical.api.tests.client je crée la classe "Tests":&lt;br /&gt;&lt;pre class="brush:java"&gt;package org.graphical.api.tests.client;&lt;br /&gt;&lt;br /&gt;import org.graphical.api.client.ui.dialogs.MyDialog;&lt;br /&gt;&lt;br /&gt;import com.google.gwt.core.client.EntryPoint;&lt;br /&gt;&lt;br /&gt;public class Tests implements EntryPoint {&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void onModuleLoad() {&lt;br /&gt;    MyDialog myDialog = new MyDialog();&lt;br /&gt;    myDialog.show();&lt;br /&gt;    myDialog.center();&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Une dernière modification est nécessaire avant de pouvoir lancer la classe de test. Il faut éditer le fichier ApiGwt.html et remplacer la ligne:&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&lt;script type="text/javascript" language="javascript" src="apigwt/apigwt.nocache.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;par la ligne:&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&lt;script type="text/javascript" language="javascript" src="apigwttests/apigwttests.nocache.js"&gt;&lt;/script&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Une fois cela fait faire un clic droit sur ApiGwtTests.gwt.xml puis run as -&gt; web application.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;L'étape 5 n'est pas nécessaire, en effet il aurait été possible de faire les tests directement dans la classe d'entrée créé automatiquement par GWT. L'intéret de cette solution est qu'elle permet de bien isoler les tests et le reste du code et aussi de faire des exports incluant uniquement les classes effectivement utiles.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Etape 6: export sous forme de jar.&lt;br /&gt;&lt;/span&gt;L'arborescence finale est la suivante:&lt;br /&gt;&lt;br /&gt;Pour exporter sous forme de jar faire un clic droit sur le projet puis export-&gt;java-&gt;jar file et sélectionner les packages a exporter comme suit:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XuU6jH6grbY/TFF9DRPl-0I/AAAAAAAAABg/HsNjSDy50Vc/s1600/2010-07-29_150703.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 242px;" src="http://2.bp.blogspot.com/_XuU6jH6grbY/TFF9DRPl-0I/AAAAAAAAABg/HsNjSDy50Vc/s400/2010-07-29_150703.png" alt="" id="BLOGGER_PHOTO_ID_5499314115117972290" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Etape 7 : Utilisation du jar créé.&lt;br /&gt;&lt;/span&gt;Pour utiliser le jar créé il suffit de la placer dans le répertoire lib de votre projet GWT, de l'ajouter au classpath de celui-ci et enfin de le déclarer dans le fichier &lt;votreprojet&gt;.gwt.xml en y ajoutant la ligne suivante:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;inherits name="org.graphical.api.ApiGwt"&gt;&lt;/inherits&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion:&lt;/span&gt;&lt;br /&gt;Cette démarche me parait intéressante et facile à mettre en place. Lors de mes différents essais je n'ai trouvé qu'un lien sur le sujet (&lt;a href="http://java.ociweb.com/mark/programming/GWT.html#Reuse" target="_blank"&gt;http://java.ociweb.com/mark/programming/GWT.html#Reuse&lt;/a&gt;) que j'ai trouvé un peu léger même si tout y est dit, d'où l'idée de ce post.&lt;br /&gt;&lt;/votreprojet&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1544564455280664810-9014538859932916021?l=gcharbonnier.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/9014538859932916021/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://gcharbonnier.blogspot.com/2010/07/override-public-void-setpixelsizeint.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/9014538859932916021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/9014538859932916021'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/2010/07/override-public-void-setpixelsizeint.html' title='Une api GTW partagée'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_XuU6jH6grbY/TFFw3FiqY9I/AAAAAAAAABI/KnD6THAub3U/s72-c/2010-07-29_141437.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1544564455280664810.post-4516538663108227201</id><published>2010-05-04T11:04:00.000-07:00</published><updated>2010-06-23T02:08:00.722-07:00</updated><title type='text'>Charabia</title><content type='html'>Il y a un peu plus de deux ans, lorsque j'ai fait mes premiers pas en temps que salarié du privé ma première action a été de créer un répertoire définitions dans mes favoris. Dans ce répertoire je plaçais tous les liens wikipédia vers les acronymes que je découvrait pour la première fois.&lt;br /&gt;Je vous laisse imaginer ce qu'une simple phrase telle que "Pour le design d'un cube OLAP, il est nécessaire de créer un DWH à l'aide d'un ETL" pouvait déclencher comme recherches!&lt;br /&gt;&lt;br /&gt;Vendredi dernier l'émission de France Inter &lt;a href="http://sites.radiofrance.fr/franceinter/em/nousautres/" target="_blank"&gt;Nous Autres&lt;/a&gt;, m'a refait vivre ses grands moments avec beaucoup d'humour. L'interview diffusé était tout simplement jouissif, je vous le conseille.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1544564455280664810-4516538663108227201?l=gcharbonnier.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/4516538663108227201/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://gcharbonnier.blogspot.com/2010/05/charabia.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/4516538663108227201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/4516538663108227201'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/2010/05/charabia.html' title='Charabia'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1544564455280664810.post-5657298889213121245</id><published>2010-04-17T01:05:00.000-07:00</published><updated>2010-04-17T01:43:23.910-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vanilla osbi bpm-conseil smile'/><title type='text'>Le retour</title><content type='html'>Après bientôt un an d'absence me voici de retour!!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;La raison de cette absence prolongée, la recherche d'un appartement. Il a fallut un peu plus de huit mois pour trouver le mouton à cinq pâtes... Emménagement prévu mi juin.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;La raison de mon retour, la publication par Smile du livre blanc &lt;a href="http://www.smile.fr/livres-blancs/erp-et-decisionnel/decisionnel" target="_blank"&gt;"Bi open source décisionnel 2010"&lt;/a&gt;. En effet ce livre blanc à fait débat au sein de ma société (bpm-conseil). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A titre personnel, je ne suis pas surpris que la suite vanilla ne soit pas citée dans ce livre et je ne m'en émeu pas outre mesure. Evidemment, j'aurai préféré que nous soyons présent mais je ne vois ici aucune forme de "censure". J'estime de plus qu'il aurait été difficile de nous jugé objectivement car &lt;a href="http://www.osbi.fr/?p=1083" target="_blank"&gt;comme le dit Sylvain Decloix&lt;/a&gt;, de nombreuses copies d'écrans n'étant pas à jour je doute que Smile ai eu (pris?) le temps de regarder les dernières avancées de vanilla.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pour moi sa relative confidentialité est la seule raison objective de l'absence de vanilla dans ce livre blanc. Quoiqu'il en soit, cette raison est de moins en moins valable si j'en juge par le nombre de formations qui sont organisées autour de vanilla, notamment sur le triptyque FreeMetadata, FreeDashboard, BIRT. Le bon travail réalisé en 2008 avec le Grand Lyon nous a ouvert les portes de nombreuses collectivités désireuses de remplacées BO par une solution OpenSource. Enfin la stabilisation de la plateforme et l'augmentation constante des performances nous ouvre les portes de grands comptes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Gaël&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1544564455280664810-5657298889213121245?l=gcharbonnier.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/5657298889213121245/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://gcharbonnier.blogspot.com/2010/04/le-retour.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/5657298889213121245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/5657298889213121245'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/2010/04/le-retour.html' title='Le retour'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1544564455280664810.post-1877597585666761597</id><published>2009-05-03T05:14:00.000-07:00</published><updated>2009-05-03T08:00:45.065-07:00</updated><title type='text'>Vanilla 2.0</title><content type='html'>&lt;div style="text-align: justify;"&gt;Cher lecteur,&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Il y a 15 jours a eu lieu une rencontre entre les équipes de bpm-conseil et ses partenaires. L'objectif de ses deux journées était de présenter les nouveautés et les évolutions de la plateforme vanilla depuis la version 1.2.&lt;br /&gt;&lt;br /&gt;Parmis les évolutions majeurs, la plus marquante est le rôle central joué par notre métadata. En effet du dashboard au cube en passant par les rapports, tout type de document BI peut être designer à partir d'un métadata. Plus fort encore, pour les rapports, vous avez le choix. Que vous préfériez BIRT pour son interface graphique très facile à utiliser ou IReport pour ses performances il existe un plugin rendant ses deux moteurs compatibles avec le métadata de vanilla.&lt;br /&gt;&lt;br /&gt;Côtés nouveautés à court terme deux projets ont attiré l'attention. Le BiGateway et le Workflow designer.&lt;br /&gt;&lt;br /&gt;Le Bi Gateway, dont voici un aperçu de l'interface, permet de réaliser la migration de données.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XuU6jH6grbY/Sf2OqVGbytI/AAAAAAAAAAM/jw9qZz9waCM/s1600-h/GTW_2.png" target="_blank"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 194px;" src="http://4.bp.blogspot.com/_XuU6jH6grbY/Sf2OqVGbytI/AAAAAAAAAAM/jw9qZz9waCM/s320/GTW_2.png" alt="" id="BLOGGER_PHOTO_ID_5331574391746317010" border="0" /&gt;&lt;/a&gt;Cet outil fait de vanilla une platforme complète allant de la création de Data Warehouse&lt;b&gt; &lt;/b&gt;à la restitution intelligible de données.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;L'interface du Workflow designer, dont une première version avait été sorti en début d'année, a été entièrement revue. Cette dernière est ainsi beaucoup plus souple.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XuU6jH6grbY/Sf2QQYMe6VI/AAAAAAAAAAU/PHxxUuCJ4Io/s1600-h/wk.png" target="_blank"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 200px;" src="http://3.bp.blogspot.com/_XuU6jH6grbY/Sf2QQYMe6VI/AAAAAAAAAAU/PHxxUuCJ4Io/s320/wk.png" alt="" id="BLOGGER_PHOTO_ID_5331576144923650386" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Cet outil va rendre obsolète le dernier composant qui rendait, aux yeux de certains, pentaho attractif.&lt;br /&gt;&lt;br /&gt;A moyen terme, un produit très attendu est le Map Designer. Entièrement développé en GWT, cette application web a pour but la restitution d'indicateurs géolocalisés. Ce projet me tenant tout particulièrement à coeur j'y consacrerai mon prochain billet.&lt;br /&gt;&lt;br /&gt;A bientôt autour de vanilla.&lt;br /&gt;&lt;br /&gt;Gaël&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1544564455280664810-1877597585666761597?l=gcharbonnier.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/1877597585666761597/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://gcharbonnier.blogspot.com/2009/05/vanilla-20.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/1877597585666761597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/1877597585666761597'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/2009/05/vanilla-20.html' title='Vanilla 2.0'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_XuU6jH6grbY/Sf2OqVGbytI/AAAAAAAAAAM/jw9qZz9waCM/s72-c/GTW_2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1544564455280664810.post-6270954941269045323</id><published>2009-03-29T04:58:00.000-07:00</published><updated>2009-03-29T11:25:39.931-07:00</updated><title type='text'>Hello world</title><content type='html'>Ce premier post pour me présenter "au monde".&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Il y a un peu plus d'un an j'ai quitté l'éducation nationale pour me lancer dans une nouvelle aventure professionnelle: l'informatique. Cela faisait plusieurs années que je vivais cette passion en marge de mes activités d'enseignement (j'avais le temps ;-)). Embauché chez bpm conseil, je suis tombé par hasard dans l'osbi (open source BI) et je remercie pour cela Patrick Beaucamp, car peu nombreux sont ceux qui m'aurait donné ma chance.&lt;br /&gt;&lt;br /&gt;A l'époque je pensais que j'en avais fini avec les petites mesquineries, les gueguerres pour avoir mon vendredi après-midi de libre ou une équerre dans ma salle. C'était sans compter l'ambiance "conviviale" qui règne dans le petit monde de l'osbi, où chacun se réjouit de la réussite des autres. En effet je ne compte plus les remarques désobligeantes par ce qu'il manque un fichier source ou un fichier de licence... Mais franchement l'essentiel est ailleurs.&lt;br /&gt;&lt;br /&gt;J'ai longtemps hésité avant d'ouvrir se blog et d'y exposer mon travail. Mais lorsque j'ai vu que la classe principale de IReport faisait plus de 10 000 lignes, je me suis dis: "pourquoi pas? je ne fais pas pire". Quoiqu'il en soit la critique lorsqu'elle est constructive fait progresser.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Gaël&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1544564455280664810-6270954941269045323?l=gcharbonnier.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gcharbonnier.blogspot.com/feeds/6270954941269045323/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://gcharbonnier.blogspot.com/2009/03/fgfd.html#comment-form' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/6270954941269045323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1544564455280664810/posts/default/6270954941269045323'/><link rel='alternate' type='text/html' href='http://gcharbonnier.blogspot.com/2009/03/fgfd.html' title='Hello world'/><author><name>gael.charbonnier</name><uri>http://www.blogger.com/profile/00837719523346922371</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
