vendredi 22 avril 2011

TETRIS et HTML 5

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.
Afin de lier l'utile à l'agréable, je me suis lancé dans la réalisation d'un TETRIS tout en javascript.
Vous trouverez le code ci-dessous.
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.
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.

Quelques liens intéressants:
//////////////////////////////////////////
// Les constantes //
//////////////////////////////////////////
var maxY = 20;
var maxX = 10;
var cellSize = 20;
var startX = 20;
var startY = 20;
var nextX = maxX*20 + startX + 10;
var nextY = startY + 10;

//////////////////
//La grille //
//////////////////
var grille = new Array();


////////////////////////////////////
// Matrices des formes //
////////////////////////////////////
function initCasesO() {
var casesO = new Array();
casesO[0] = new Array();
casesO[1] = new Array();
casesO[2] = new Array();
casesO[3] = new Array();


casesO[0][0] = 0;
casesO[0][1] = 0;
casesO[0][2] = 0;
casesO[0][3] = 0;

casesO[1][0] = 0;
casesO[1][1] = 1;
casesO[1][2] = 1;
casesO[1][3] = 0;

casesO[2][0] = 0;
casesO[2][1] = 1;
casesO[2][2] = 1;
casesO[2][3] = 0;

casesO[3][0] = 0;
casesO[3][1] = 0;
casesO[3][2] = 0;
casesO[3][3] = 0;

return casesO;
}

function initCasesI() {
var casesI = new Array();
casesI[0] = new Array();
casesI[1] = new Array();
casesI[2] = new Array();
casesI[3] = new Array();

casesI[0][0] = 0;
casesI[0][1] = 0;
casesI[0][2] = 1;
casesI[0][3] = 0;

casesI[1][0] = 0;
casesI[1][1] = 0;
casesI[1][2] = 1;
casesI[1][3] = 0;

casesI[2][0] = 0;
casesI[2][1] = 0;
casesI[2][2] = 1;
casesI[2][3] = 0;

casesI[3][0] = 0;
casesI[3][1] = 0;
casesI[3][2] = 1;
casesI[3][3] = 0;

return casesI;
}

function initCasesS() {
var casesS = new Array();
casesS[0] = new Array();
casesS[1] = new Array();
casesS[2] = new Array();
casesS[3] = new Array();

casesS[0][0] = 0;
casesS[0][1] = 0;
casesS[0][2] = 0;
casesS[0][3] = 0;

casesS[1][0] = 0;
casesS[1][1] = 0;
casesS[1][2] = 1;
casesS[1][3] = 1;

casesS[2][0] = 0;
casesS[2][1] = 1;
casesS[2][2] = 1;
casesS[2][3] = 0;

casesS[3][0] = 0;
casesS[3][1] = 0;
casesS[3][2] = 0;
casesS[3][3] = 0;

return casesS;
}

function initCasesZ() {
var casesZ = new Array();
casesZ[0] = new Array();
casesZ[1] = new Array();
casesZ[2] = new Array();
casesZ[3] = new Array();

casesZ[0][0] = 0;
casesZ[0][1] = 0;
casesZ[0][2] = 0;
casesZ[0][3] = 0;

casesZ[1][0] = 0;
casesZ[1][1] = 1;
casesZ[1][2] = 1;
casesZ[1][3] = 0;

casesZ[2][0] = 0;
casesZ[2][1] = 0;
casesZ[2][2] = 1;
casesZ[2][3] = 1;

casesZ[3][0] = 0;
casesZ[3][1] = 0;
casesZ[3][2] = 0;
casesZ[3][3] = 0;

return casesZ;
}

function initCasesL() {
var casesL = new Array();
casesL[0] = new Array();
casesL[1] = new Array();
casesL[2] = new Array();
casesL[3] = new Array();

casesL[0][0] = 0;
casesL[0][1] = 0.25;
casesL[0][2] = 0.5;
casesL[0][3] = 0.5;

casesL[1][0] = 0;
casesL[1][1] = 1;
casesL[1][2] = 1;
casesL[1][3] = 1;

casesL[2][0] = 0;
casesL[2][1] = 1;
casesL[2][2] = 0.5;
casesL[2][3] = 0.75;

casesL[3][0] = 0;
casesL[3][1] = 0;
casesL[3][2] = 0;
casesL[3][3] = 0;

return casesL;
}

function initCasesJ() {
var casesJ = new Array();
casesJ[0] = new Array();
casesJ[1] = new Array();
casesJ[2] = new Array();
casesJ[3] = new Array();

casesJ[0][0] = 0;
casesJ[0][1] = 0.5;
casesJ[0][2] = 0.5;
casesJ[0][3] = 0.75;

casesJ[1][0] = 0;
casesJ[1][1] = 1;
casesJ[1][2] = 1;
casesJ[1][3] = 1;

casesJ[2][0] = 0;
casesJ[2][1] = 0.25;
casesJ[2][2] = 0.5;
casesJ[2][3] = 1;

casesJ[3][0] = 0;
casesJ[3][1] = 0;
casesJ[3][2] = 0;
casesJ[3][3] = 0;

return casesJ;
}

function initCasesT() {
var casesT = new Array();
casesT[0] = new Array();
casesT[1] = new Array();
casesT[2] = new Array();
casesT[3] = new Array();

casesT[0][0] = 0;
casesT[0][1] = 0;
casesT[0][2] = 0;
casesT[0][3] = 0;

casesT[1][0] = 0;
casesT[1][1] = 3;
casesT[1][2] = 1;
casesT[1][3] = 1;

casesT[2][0] = 0;
casesT[2][1] = 0;
casesT[2][2] = 2;
casesT[2][3] = 0;

casesT[3][0] = 0;
casesT[3][1] = 0;
casesT[3][2] = 0;
casesT[3][3] = 0;

return casesT;
}

//////////////////////////
// Matrices de "rotation"//
/////////////////////////
var rotateI = new Array();
rotateI[0] = new Array();
rotateI[1] = new Array();
rotateI[2] = new Array();
rotateI[3] = new Array();


rotateI[0][0] = 0;
rotateI[0][1] = 0;
rotateI[0][2] = 1;
rotateI[0][3] = 0;

rotateI[1][0] = 1;
rotateI[1][1] = 1;
rotateI[1][2] = 0;
rotateI[1][3] = 1;

rotateI[2][0] = 0;
rotateI[2][1] = 0;
rotateI[2][2] = 1;
rotateI[2][3] = 0;

rotateI[3][0] = 0;
rotateI[3][1] = 0;
rotateI[3][2] = 1;
rotateI[3][3] = 0;


var rotateS = new Array();
rotateS[0] = new Array();
rotateS[1] = new Array();
rotateS[2] = new Array();
rotateS[3] = new Array();


rotateS[0][0] = 0;
rotateS[0][1] = 0;
rotateS[0][2] = 1;
rotateS[0][3] = 0;

rotateS[1][0] = 0;
rotateS[1][1] = 0;
rotateS[1][2] = 0;
rotateS[1][3] = 0;

rotateS[2][0] = 0;
rotateS[2][1] = 1;
rotateS[2][2] = 1;
rotateS[2][3] = 1;

rotateS[3][0] = 0;
rotateS[3][1] = 0;
rotateS[3][2] = 0;
rotateS[3][3] = 0;


var rotateZ = new Array();
rotateZ[0] = new Array();
rotateZ[1] = new Array();
rotateZ[2] = new Array();
rotateZ[3] = new Array();


rotateZ[0][0] = 0;
rotateZ[0][1] = 0;
rotateZ[0][2] = 0;
rotateZ[0][3] = 1;

rotateZ[1][0] = 0;
rotateZ[1][1] = 1;
rotateZ[1][2] = 0;
rotateZ[1][3] = 1;

rotateZ[2][0] = 0;
rotateZ[2][1] = 0;
rotateZ[2][2] = 0;
rotateZ[2][3] = 1;

rotateZ[3][0] = 0;
rotateZ[3][1] = 0;
rotateZ[3][2] = 0;
rotateZ[3][3] = 0;

var rotateL = new Array();
rotateL[0] = new Array();
rotateL[1] = new Array();
rotateL[2] = new Array();
rotateL[3] = new Array();


rotateL[0][0] = 0;
rotateL[0][1] = 0.25;
rotateL[0][2] = 0.5;
rotateL[0][3] = 0.25;

rotateL[1][0] = 0;
rotateL[1][1] = 0.5;
rotateL[1][2] = 1;
rotateL[1][3] = 0.5;

rotateL[2][0] = 0;
rotateL[2][1] = 0.25;
rotateL[2][2] = 0.5;
rotateL[2][3] = 0.25;

rotateL[3][0] = 0;
rotateL[3][1] = 0;
rotateL[3][2] = 0;
rotateL[3][3] = 0;

var rotateJ = new Array();
rotateJ[0] = new Array();
rotateJ[1] = new Array();
rotateJ[2] = new Array();
rotateJ[3] = new Array();


rotateJ[0][0] = 0;
rotateJ[0][1] = 0.25;
rotateJ[0][2] = 0.5;
rotateJ[0][3] = 0.25;

rotateJ[1][0] = 0;
rotateJ[1][1] = 0.5;
rotateJ[1][2] = 1;
rotateJ[1][3] = 0.5;

rotateJ[2][0] = 0;
rotateJ[2][1] = 0.25;
rotateJ[2][2] = 0.5;
rotateJ[2][3] = 0.25;

rotateJ[3][0] = 0;
rotateJ[3][1] = 0;
rotateJ[3][2] = 0;
rotateJ[3][3] = 0;

var rotateT = new Array();
rotateT[0] = new Array();
rotateT[1] = new Array();
rotateT[2] = new Array();
rotateT[3] = new Array();


rotateT[0][0] = 0;
rotateT[0][1] = 0;
rotateT[0][2] = 1;
rotateT[0][3] = 0;

rotateT[1][0] = 0;
rotateT[1][1] = 1;
rotateT[1][2] = 0;
rotateT[1][3] = 1;

rotateT[2][0] = 0;
rotateT[2][1] = 0;
rotateT[2][2] = 1;
rotateT[2][3] = 0;

rotateT[3][0] = 0;
rotateT[3][1] = 0;
rotateT[3][2] = 0;
rotateT[3][3] = 0;

/////////////////////////////
// Les objets //
/////////////////////////////
function Figure(forme) {
this.currentX = 3;
this.currentY = -1;
this.forme = forme;
this.color = forme.color;
}

Figure.prototype.descendre = function() {
this.currentY++;
}

Figure.prototype.moveR = function() {
this.currentX++;
}

Figure.prototype.moveL = function() {
this.currentX--;
}

Figure.prototype.rotate = function() {
this.forme.rotate();
}

function Forme(cases, color, type) {
this.color = color
this.cases = cases;
this.type = type;
}

Forme.prototype.rotate = function() {
if (this.type == 'I') {
for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { this.cases[i][j] = (this.cases[i][j] + rotateI[i][j])%2; } } } else if (this.type == 'S') { for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { this.cases[i][j] = (this.cases[i][j] + rotateS[i][j])%2; } } } else if (this.type == 'Z') { for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { this.cases[i][j] = (this.cases[i][j] + rotateZ[i][j])%2; } } } else if (this.type == 'L') { for (var i = 0; i < 4; i++) { for (var j = 0; j < 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 < 4; i++) { for (var j = 0; j < 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 < 4; i++) { for (var j = 0; j < 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 < 4; i++) { newArray[i] = new Array(); for (var j = 0; j < 4; j++) { newArray[i][j] = this.cases[i][j]; } } if (this.type == 'I') { for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { newArray[i][j] = (newArray[i][j] + rotateI[i][j])%2; } } } else if (this.type == 'S') { for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { newArray[i][j] = (newArray[i][j] + rotateS[i][j])%2; } } } else if (this.type == 'Z') { for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { newArray[i][j] = (newArray[i][j] + rotateZ[i][j])%2; } } } else if (this.type == 'L') { for (var i = 0; i < 4; i++) { for (var j = 0; j < 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 < 4; i++) { for (var j = 0; j < 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 < 4; i++) { for (var j = 0; j < 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 < 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 < 4; i++) { for (var j = 0; j < 4; j++) { if (fig.forme.cases[i][j] >= 1) {
ctx.fillStyle = fig.color;
ctx.fillRect((fig.currentX + j)* cellSize + startX, (fig.currentY + i) * cellSize + startY, cellSize, cellSize);
}
}
}

//Affichage des cases remplies
for (var i = 0; i < 20; i++) { for (var j = 0; j < 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 < 4; i++) { for (var j = 0; j < 4; j++) { if (next.forme.cases[i][j] >= 1) {
ctx.fillStyle = next.color;
ctx.fillRect(nextX + j* cellSize, nextY + i * cellSize, cellSize, cellSize);
}
}
}


if (canMoveDown()) {
fig.descendre();
}
else {
fillGrid();
treatLine();

if (grille[0][6] == undefined) {
fig = next;
next = randomFigure();
}
else {
return;
}
}

}

function randomFigure() {
var _fig;
choice = Math.floor(Math.random()*7);
if (choice == 0) {
_fig = new Figure(new Forme(initCasesO(), "#FFFF00", 'O'));
}
else if (choice == 1) {
_fig = new Figure(new Forme(initCasesS(), "#008000", 'S'));
}
else if (choice == 2) {
_fig = new Figure(new Forme(initCasesI(), "#00FFFF", 'I'));
}
else if (choice == 3) {
_fig = new Figure(new Forme(initCasesZ(), "#FF0000", 'Z'));
}
else if (choice == 4) {
_fig = new Figure(new Forme(initCasesL(), "#FFA500", 'L'));
}
else if (choice == 5) {
_fig = new Figure(new Forme(initCasesJ(), "#0000FF", 'J'));
}
else if (choice == 6) {
_fig = new Figure(new Forme(initCasesT(), "#FF00FF", 'T'));
}
return _fig;

}

/*Looking for line to be deleted*/
function treatLine() {
var linesToDelete = new Array();
for (var i = 0; i < 20; i++) { var del = true; for (var j = 0; j < 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 > -1; l--) {
deleteLine(linesToDelete[l] + deleted);
deleted++;
}
}

/*Delete line*/
function deleteLine(l) {
for (var i = 19; i > 0; i--) {
for (var j = 0; j < 10; j++) { if (i <= 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 < 4; i++) { for (var j = 0; j < 4; j++) { if (fig.forme.cases[i][j] >= 1) {
grille[fig.currentY + i][fig.currentX + j] = fig.color;
}
}
}
}

/*Check if the figure can move down*/
function canMoveDown() {
if (fig.currentY + 4 == maxY) {
for (var j = 0; j < 4; j++) { if (fig.forme.cases[3][j] >= 1) {
return false;
}
}
}
else if (fig.currentY + 4 == maxY + 1) {
for (var j = 0; j < 4; j++) { if (fig.forme.cases[2][j] >= 1) {
return false;
}
}

}
else if (fig.currentY + 4 == maxY + 2) {
for (var j = 0; j < 4; j++) { if (fig.forme.cases[1][j] >= 1) {
return false;
}
}

}
for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { if (fig.forme.cases[i][j] >= 1) {
if (undefined != grille[fig.currentY + i + 1][fig.currentX + j]) {
return false;
}
}
}
}

return true;

}

/*Check if a figure can flip*/
function isFlipValide(array) {
for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { if (array[i][j] >= 1 ) {
if (fig.currentX + j < 0 || fig.currentY + i >= maxY || fig.currentX + j >= maxX || grille[fig.currentY + i][fig.currentX + j] != undefined) {
return false;
}
}
}
}
return true;
}

/*Check if a figure move: left, right or flip*/
function checkDeplace(e) {
// Flêche de droite préssée
if (e.keyCode == 39) {
var test = true;
for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { if (fig.forme.cases[i][j] >= 1) {
//La figure est contre la bordure droite
if (fig.currentX + j + 1 == maxX) {
test = false;
break;
}
//Il y a une figure à droite
else if (fig.currentX + j + 1 < maxX && 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 < 4; i++) { for (var j = 0; j < 4; j++) { if (fig.forme.cases[i][j] >= 1) {
//La figure est contre la bordure gauche
if (fig.currentX + j == 0) {
test = false;
break;
}
//Il y a une figure à gauche
else if (fig.currentX + j - 1 > -1 && grille[fig.currentY + i][fig.currentX + j - 1] != undefined) {
test = false;
break;
}
}
}
}
if (test) {
fig.moveL();
}
}
else if(e.keyCode == 32) {
if (isFlipValide(fig.forme.simuleRotate()) == true) {
fig.rotate();
}
}
}

function pause(millis) {
var date = new Date();
var curDate = null;

do {
curDate = new Date();
}
while(curDate-date < millis); }

jeudi 20 janvier 2011

Voeux

Ô toi surfeur égaré qui lit ses quelques lignes, je te souhaite une bonne et heureuse année 2011.

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.

Les trois années passées chez BPM auront été riches en apprentissage tant technique qu'humain, tant positif que négatif....

dimanche 24 octobre 2010

Laveur de cerveaux?

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».
L'article de Télérama 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."
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.


mardi 27 juillet 2010

Une api GTW partagée

Le but de ce post est de montrer comment créer simplement dans eclipse une api graphique GWT réutilisable dans plusieurs projets.

Pré-requis:
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.

Etape 1: création du projet.
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:



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

Etape 2: mise à jour du fichier XML de déclaration du module.
Editer le fichier ApiGwt.gwt.xml et modifier le en supprimant les lignes surlignées en jaunes ci dessous.


Le projet est maintenant prêt et peut-être utiliser pour créer les classes que l'on souhaite partager.

Etape 3: Création d'une classe simple.
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 -> source folder


J'ai appelé "ui" ce nouveau dossier source. Dans ce dossier il faut créer deux packages:
  • org.graphical.api.client.ui
  • org.graphical.api.client.ui.dialogs
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:










Note: penser à décommenter le doctype.

Afin de fournir un exemple, dans le package org.graphical.api.client.ui.dialogs, je créé la classe MyDialog dont le code est:

package org.graphical.api.client.ui.dialogs;

import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;

public class MyDialog extends DialogBox {

public MyDialog() {
super();
this.setText("Mon titre");
this.setWidget(new HTML("Bla bla bla"));
}
}

Etape 4: déclaration du nouveau module dans le fichier XML de déclaration principal.
Pour cela il suffit de rajouter la ligne suivante dans le fichier ApiGwt.gwt.xm:




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.

Etape 5: création d'un package de tests.
Afin de bien séparer les tests du reste je créé un nouveau dossier source nommé "tests". Dans ce dossier je créé deux packages:
  • org.graphical.api.tests
  • org.graphical.api.tests.client
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:
















La ligne

permet de déclarer quelle est la classe qui implémente "EntryPoint".

Dans le deuxième package org.graphical.api.tests.client je crée la classe "Tests":
package org.graphical.api.tests.client;

import org.graphical.api.client.ui.dialogs.MyDialog;

import com.google.gwt.core.client.EntryPoint;

public class Tests implements EntryPoint {

@Override
public void onModuleLoad() {
MyDialog myDialog = new MyDialog();
myDialog.show();
myDialog.center();

}

}


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:



par la ligne:



Une fois cela fait faire un clic droit sur ApiGwtTests.gwt.xml puis run as -> web application.


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.

Etape 6: export sous forme de jar.
L'arborescence finale est la suivante:

Pour exporter sous forme de jar faire un clic droit sur le projet puis export->java->jar file et sélectionner les packages a exporter comme suit:


Etape 7 : Utilisation du jar créé.
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 .gwt.xml en y ajoutant la ligne suivante:

Conclusion:
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 (http://java.ociweb.com/mark/programming/GWT.html#Reuse) que j'ai trouvé un peu léger même si tout y est dit, d'où l'idée de ce post.

mardi 4 mai 2010

Charabia

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.
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!

Vendredi dernier l'émission de France Inter Nous Autres, m'a refait vivre ses grands moments avec beaucoup d'humour. L'interview diffusé était tout simplement jouissif, je vous le conseille.