mardi 6 octobre 2015

Développer pour la Réalité virtuelle

Scripts PHP pour e-commerce

mardi 2 juin 2015

JavaFX : quelques outils d'aide / support au développement

Dans l'éco-système Java, il y a les outils de développement mais aussi des outils complémentaires très utiles pour les développeurs.

JIRA est un système de suivi de bugs, un système de gestion des incidents et un système de gestion de projets développé par Atlassian Software Systems.

Par exemple vous trouverez les bugs et incidents liés aux versions actuelles du JDK JavaFX.

Encore plus intéressant, vous pouvez déclarer un incident - incident pris en charge par un membre de l'équipe JDK.

L'incident recevra un niveau de priorité.

Une fois l'incident déclaré, vous pouvez suivre le traitement de cet incident et connaître la version future du JDK qui fixera le problème (si toutefois votre problème peut être résolu).

Soyez précis lors de la déclaration d'un incident : le membre de l'équipe JDK doit pouvoir reproduire le problème facilement.

Etant donné que le JDK JavaFX est toujours en version EA, de nombreux bugs sont encore en cours.

Cet outil est donc utile et vous servira de "dashboard" global sur le taux de traitement des problèmes liés au JDK.

OpenJDK est une espace collaboratif à la fois pour l'implémentation Open Source de Java et pour l'implémentation de projets autour de la plateforme Java.

Le JDK JavaFX est issu de projets gérés sur cet espace.

Très intéressant : vous avez la ROADMAP des versions actuelles et futures du JDK - information non négligeable à prendre en considération dans votre planning de développement.

La difficulté d'un projet JavaFX est de pouvoir assoir ce projet sur une version stable du JDK JavaFX.

D'autre part la version choisie doit correspondre aux besoins de votre projet.

Nous sommes aussi dans une transition entre le JDK 8 et le prochain JDK 9 : les API sont (et vont être) modifiées et améliorées.

Quelle version faut-il prendre en compte pour notre projet ?

Autant de questions qu'il faut se poser rapidement.

Windows 10 pour bientôt !

JavaFx : Runtime / Jar

Pour tester votre application, vous exécutez (par exemple sous Eclipse) votre application (en mode Runtime).

Les tests sont positifs, donc tout va bien.

Vous packagez (génération du fichier Jar) votre application avec succès.

Quelque fois dans l'euphorie ou la précipitation un test est oublié :  le test après Packaging de l'application.

Nous partons souvent du principe que puisque les tests sont corrects en mode Runtime forcément ils seront corrects en mode Packaging !

Si cela est le cas, nous faisons une grosse erreur : l'application doit être testée dans les deux modes.

Cette erreur peut amener son lot de problèmes.


Prenons un exemple concret pour illustrer.

Dans toute application, il y a très souvent des accès à des ressources (par exemple : lire un fichier XML ou lire un fichier IMAGE).

Selon le contexte (et les fonctions utilisées) certaines ressources sont accessibles d'une certaine façon en mode Runtime et d'une autre en mode Packaging.

Exemple :

En mode Runtime

public static final String FOP_CONFIGURATION_FILE = "mycfg.xml";

String config = MyClasse.class
.getResource(FOP_CONFIGURATION_FILE).toString()
.substring(6); (*)

fopFactory.setUserConfig(new File(config));

(*) un <substring(6)> est nécessaire car nous obtenons : file:/D:/..../mycfg.xml (chemin absolu dans le file system) : il faut donc supprimer le préfixe "file:/"

Dans cet exemple nous accédons à un fichier de configuration nécessaire pour initialiser le moteur "XSL:FO" (transformer des données XML - par exemple générer un fichier PDF à partir de ces données).

Le fichier FOP_CONFIGURATION_FILE se trouve dans le même package Java que la classe MyClasse.

En mode Runtime, le même package = le même répertoire.

En mode Packaging (lors de l'exécution du Jar)

fopFactory.setUserConfig(this.getClass()
.getResource(FOP_CONFIGURATION_FILE).toURI().toString());

Dans ce cas il faut transformer le chemin de notre fichier en URI pour initialiser notre moteur XSL.


Nous avons donc deux approches très proches mais différentes pour accèder à une même ressource.

Quelle est donc la bonne pratique pour être sûr que le code de notre exemple s'exécute correctement dans les deux modes d'exécution ?

if (MyClasse.class.getResource(FOP_CONFIGURATION_FILE)
.toString().contains("jar:")) {
        // accès en mode Packaging
fopFactory.setUserConfig(this.getClass()
.getResource(FOP_CONFIGURATION_FILE).toURI().toString());

} else {
// accès en mode Runtime
String config = MyClasse.class
.getResource(FOP_CONFIGURATION_FILE).toString()
.substring(6);

fopFactory.setUserConfig(new File(config));
}

Si la valeur retournée par la fonction <getResource> contient "jar:" alors nous sommes en mode Packaging sinon nous sommes en mode Runtime.

Vous avez notez qu'une ressource qui se trouve dans le Jar n'est pas un fichier au sens strict : c'est une "composante" d'un fichier Jar.


Cet exemple a servi à illustrer l'importance de tester tous les comportements (notamment les accès aux ressources) de votre application qu'elle soit en mode DEV ou en mode PRODUCTION.

Il faudra peut être isoler les cas qui vont nécessiter un traitement particulier en mode Runtime ou en mode Packaging.

jeudi 7 mai 2015

Nouvelle version de io.js

JavaFX / IHM : programmative ou déclarative ?

En JavaFX, nous avons la possibilité de définir une IHM de deux façons à la fois différentes et complémentaires :

  • En exploitant des fichiers FXML (façon déclarative)
  • En "assemblant" dynamiquement tous les composants UI nécessaires (façon programmative)

Les fichiers FXML fournissent les informations sur les composants UI qui vont être utiliser.

Ces fichiers vont être considérés par JavaFX comme des objets sérialisés parfaitement utilisables par votre application.

JavaFX Scene Builder est une application WYSIWIG qui permet de générer ces fichiers FXML.

Vous pouvez bien sûr générer manuellement ces fichiers.

La façon programmative va s'appuyer strictement sur les API Java pour construire une IHM.

Certains développeurs adopteront (par confort, par habitude ou par "philosophie") une des deux approches.

Quelle est donc la meilleure approche : programmative ou déclarative ?

En fait il n'y a pas de meilleure approche.

Au début de cet article, nous avons considéré ces deux approches comme complémentaires.

Et c'est le cas !

JavaFX permet de construire une IHM en utilisant ces deux approches.

Nous pouvons par exemple construire une partie de notre IHM avec l'approche déclarative et construire l'autre partie avec l'approche programmative.

Une réflexion au préalable est souhaitable pour estimer la part du déclaratif / programmatif.

"L'estimation" sera peut être conditionnée par certaines contraintes (par exemple : volonté de ne pas externaliser une IHM).

Nous avons un palette d'outils : à nous de les utiliser au mieux !

Nouvelle version de PHP

Du nouveau pour PHP :

Après un PHP 6 avorté, voici PHP 7.
Affaire à suivre...

Transformation données XML et Encodage

Lorsque vous manipulez la chaine de traitement XML pour transformer vos données en un document exploitable, il faut tenir compte de l'encodage de vos données.

L'encodage pour faire simple est la "façon" de représenter vos données.

Il est donc nécessaire que chaque maillon de la chaine de traitement puisse analyser et comprendre les données transmises.

Pour éviter des données non comprises (et très souvent représentées dans ce cas par des caractères spéciaux), il faut s'assurer d'utiliser le même encodage sur toute la chaine de traitement.

Cela peut sembler évident mais cette "négligence" peut être la source de nombreux problèmes.

Voici quelques conseils.

Nous partirons du principe par exemple que l'encodage sélectionné soit l'UTF-8.

Commençons par les données.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>

Vous devez insérer cette balise en première ligne de votre fichier XML - vous pourrez ainsi utiliser les caractères accentués.

Assurez - vous que l'encodage du fichier soit aussi en UTF-8 - cela peut sembler évident mais dans la pratique nous constatons quelque fois une différence d'encodage entre le fichier et ses données.

Vos documents XSL / XSL:FO doivent aussi comporter :

<?xml version="1.0" encoding="UTF-8"?>

en première ligne.

La précédente remarque sur l'encodage du fichier s'applique aussi dans ce cas.

Une fois que vous êtes sûrs que vos données et fichiers soient bien en UTF-8, cela ne suffit pas.

Il faut s'assurer que lors du traitement de la chaine XML, vos données soient bien lues et écrites en UTF-8.

Exemple :

// données XML
Source sourceDATA = new StreamSource(tempFile);

// feuille de style XSL
FileInputStream stream = new FileInputStream(
templatesList.get(newValue).replace(
"\\", "\\\\"));

Reader reader = new InputStreamReader(stream,"UTF-8");

Source xsl = new StreamSource(reader);

// document HTML en sortie
File temp = File.createTempFile("mon_fichier_de_sortie", ".html");
OutputStream fos = new FileOutputStream(temp);
OutputStreamWriter bw = new OutputStreamWriter(fos, "UTF-8");

Result result = new StreamResult(bw);

// transformation
TransformerFactory factory = TransformerFactory.newInstance();

Transformer transformer = factory.newTransformer(xsl);

transformer.setParameter("encoding", "UTF-8");

transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

transformer.transform(sourceDATA, result);

Dans cette exemple, nous transformons (XSL / XSLT) des données XML en un document HTML.

Vous noterez les précautions à prendre pour s'assurer du bon encodage jusqu'au bout du traitement.

Ce principe s'applique pour toutes les technologies XML.

XSL:FO : gestion multi pages

XSL:FO permet de décrire les mises en forme de documents XML quel que soit le support (écran, papier, ...).

Par exemple, il est possible de générer ainsi un document PDF à partir de données XML.

Une des difficultés est de gérer correctement un document multi - pages.

Imaginez que vous deviez mettre en forme des lignes d'une facture et que vous souhaitiez faire un saut de page toutes les 15 lignes.

Voici un extrait d'un document XSL:FO type :

<fo:table table-layout="fixed" border-spacing="3px 3px">
...
<fo:table-body background-color="white" border-color="black"

border-width="1px" border-style="solid">
<xsl:for-each select="Ligne">

<fo:table-row space-before.optimum="0pt">
<!-- gestion des sauts de page -->
<xsl:if test="position() mod 15 = 0">
<xsl:attribute name="break-after">page</xsl:attribute>
</xsl:if>

<fo:table-cell padding="3px">
<fo:block text-align-last="center">
<xsl:value-of select="ref" />
</fo:block>
</fo:table-cell>
<fo:table-cell padding="3px">
<fo:block text-align-last="center">
<xsl:value-of select="designation" />
</fo:block>
</fo:table-cell>
<fo:table-cell padding="3px">
<fo:block text-align-last="center">
<xsl:value-of select="qte" />
</fo:block>
</fo:table-cell>
<fo:table-cell padding="3px">
<fo:block text-align-last="right">
<xsl:value-of select="format-number(pu_ht, '### ###.00')" />
</fo:block>
</fo:table-cell>
<fo:table-cell padding="3px">
<fo:block text-align-last="right">
<xsl:if test="remise > 0">
<xsl:value-of select="format-number(remise, '### ###.00')" />
</xsl:if>
<xsl:if test="contains(remise, '%')">
<xsl:value-of select="remise" />
</xsl:if>
</fo:block>
</fo:table-cell>
<fo:table-cell padding="3px">
<fo:block text-align-last="right">
<xsl:value-of select="format-number(total_ht, '### ###.00')" />
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
...
            </fo:table>

Un extrait des données XML associées :

<Lignes>
...
<Ligne>
<ref>XXXX_105</ref>
<designation>Carte mère</designation>
<qte>1</qte>
<pu_ht>160</pu_ht>
<remise>34.55</remise>
<total_ht>125.45</total_ht>
</Ligne>
<Ligne>
<ref>FORT1</ref>
<designation>Forfait maintenance</designation>
<qte>1</qte>
<pu_ht>60</pu_ht>
<remise>15%</remise>
<total_ht>51</total_ht>
</Ligne>
<Ligne>
<ref>FORT2</ref>
<designation>Forfait maintenance 2</designation>
<qte>1</qte>
<pu_ht>70</pu_ht>
<remise></remise>
<total_ht>60</total_ht>
</Ligne>
<Ligne>
<ref>FORT3</ref>
<designation>Forfait maintenance 3</designation>
<qte>1</qte>
<pu_ht>80</pu_ht>
<remise></remise>
<total_ht>60</total_ht>
</Ligne>
<Ligne>
<ref>FORT4</ref>
<designation>Forfait maintenance 2</designation>
<qte>1</qte>
<pu_ht>70</pu_ht>
<remise></remise>
<total_ht>60</total_ht>
</Ligne>
<Ligne>
<ref>FORT5</ref>
<designation>Forfait maintenance 3</designation>
<qte>1</qte>
<pu_ht>80</pu_ht>
<remise></remise>
<total_ht>60</total_ht>
</Ligne>
...
</Lignes>

Simple non ?

Oui, mais vous devez prendre une précaution importante sinon votre gestion multi - pages ne fonctionnera pas.

Votre <FO:TABLE> ne doit pas être dans un <FO:BLOCK-CONTAINER> qui est positionné en valeur absolue (propriété : position='absolute') -  d'après les spécifications XSL.

Si cela est le cas, votre gestion multi - pages sera ignorée.

Pour remédier à ce problème, la meilleure chose à faire est de supprimer le <FO:BLOCK-CONTAINER>.

Vous pouvez aussi modifier les propriétés de <FO:REGION-BODY> en y reportant les valeurs des propriétés précédemment initialisées dans le <FO:BLOCK-CONTAINER> (ex : "margin-top" de <FO:REGION-BODY> = valeur propriété "top" de <FO:BLOCK-CONTAINER).

mardi 14 avril 2015

Swift : le vent en poupe ?

Affichage / Impression / PDF avec XML : bonnes pratiques

Dans un logiciel, vous avez au moins un traitement qui affiche, imprime ou génére un fichier PDF.

Comment associer judicieusement les technologies XML avec les traitements pré-cités ?

Considérons d'abord un affichage de données.

Dans la façon traditionnelle, vous lisez et affichez vos données en écrivant du code - en utilisant un langage de développement en particulier.

C'est bien mais nous pouvons rendre le traitement plus souple et plus dynamique.

Votre langage de développement intégre un moteur HTML : utilisez - le !

"Découplez" les données, de l'affichage.

Vos données peuvent être ainsi regroupées dans un fichier XML (avec un fichier XSD associé) et votre affichage dans un fichier XSL (template).

Votre traitement va donc consister à associer les données lues (XML) au template (XSL) et à générer (XSLT) une page HTML prête à être affichée  !

Le principal avantage : votre traitement ne subit aucunes modifications - vous modifiez uniquement vos données et/ou votre template.

Considérons le traitement d'impression.

Il est possible de définir un fichier CSS pour l'impression d'un document, tout comme nous pouvons définir un fichier CSS pour l'affichage d'un document.

Mais cette pratique est très vite limitée - exemple : la gestion multi - page d'un document.

Hors rares sont les documents qui ne sont pas multi - pages.

Un fichier CSS, comme tout fichier Web, est lié à un navigateur Web. "L'interprétation" de certaines fonctionnalités HTML varie d'un navigateur à un autre.

Nous déconseillons donc cette approche.

L'astuce consiste d'abord à générer un fichier PDF et ensuite d'imprimer ce fichier.

Nous verrons dans la partie suivante comment générer ce fichier PDF.

Votre traitement va consister :

  • à afficher une boite de dialogue permettant de choisir l'imprimante et de renseigner quelques informations pour l'impression
  • de lancer la tâche d'impression de votre document généré

Le traitement pour générer un fichier PDF.

De nombreuses API existent pour générer un fichier PDF.

L'utilisation de la technologie XSL:FO va permettre une plus grande souplesse.

Cette technologie comme son nom l'indique est une technologie très proche de la technologie XSL mais elle est plus adaptée à la génération de documents (dont le PDF).

Même si elles se rapprochent, ces technologies restent néanmoins différentes et nécessitent un apprentissage distinct mais complémentaire.

Votre traitement va consister uniquement à "coupler" vos données avec votre template (XSL-FO) et à générer le document souhaité.


Que dire de ce bref tour d'horizon des technologies XML ?

Développons des solutions les plus "souples" possible en "découplant" au maximum les données des traitements.

Les technologies XML sont puissantes et offrent une potentiel souvent sous-estimé.

Nous y gagnerons dans la maintenabilité de notre logiciel.

mercredi 1 avril 2015

API dhtmlxGantt : nouvelle version !

Webix - Tutoriel #2 : la gestion des appels AJAX

La gestion des appels AJAX en Javascript peut être assez "fastidieuse" : trop de code (souvent redondant) et une visibilité du code peu optimale !

Webix a réglé ce problème.

Exemple source :

ma_page.php

<script>
webix.ajax("chercher_data.php",
function(text, data, xhr){ alert(text); });
</script>

cherche_data.php

<?php
$json = Array();

$json[] = Array("data1"=> "test", "data2"=> "test2");

echo json_encode($json);
?>

Quelques explications.

La page <chercher_data.php> a pour mission d'extraire les données et de les mettre en forme façon JSON.

Dans notre exemple, les données "data1" et "data2" peuvent servir par exemple à "alimenter" un composant UI de Webix de type <list>.

Intéressons - nous à la fonction CALLBACK de notre appel AJAX - function(text, data, xhr).

TEXT -> réponse complète de notre appel AJAX

DATA -> réponse au format JSON / XML quand cela est applicable

XHR -> objet XmlHttpRequest

Il existe d'autres variantes pour l'utilisation de webix.ajax - veuillez consulter la documentation pour plus d'informations.

Vous noterez donc qu'un appel AJAX est simple sous Webix.

Le code est lisible  ! ce qui non négligeable dans le cas où vous devez effectuer de nombreux appels AJAX.

mercredi 25 mars 2015

Webix - Tutoriel #1 : gestion d'un menu

Le principe de Webix (API Javascript UI) est assez simple.

Vous définissez d'abord une "zone" (par exemple un DIV).

Dans la feuille de style CSS :

#mon_div {
margin: 0 auto;
width: 335px;
height: 90px;
}

Dans cet exemple nous avons un DIV auto centré d'une largeur de 335 pixels et d'une hauteur de 90 pixels.

Ce DIV va nous servir de "containeur" pour notre menu.

Dans la page HTML :

<body>
...

<div id="mon_div"></div>
...

</body>


Ensuite nous allons initialiser un composant UI "Menu".

Veuillez insérer le code ci-dessous dans la page HTML après le DIV.

<script type="text/javascript" charset="utf-8">
webix.ui({
container:"mon_div",
view:"menu",
    data:[
{ id:"1",value:"Menu 1", 
config:{
width:160
},
submenu:[
{id: "option1", value: "Option 1" },
{id: "option2", value: "Option 2" }]},
{ id:"2",value:"Menu 2", 
config:{
width:190
},
submenu:[ 
    {id: "option3", value: "Option 3" },
    {id: "option4", value: "Option 4" }]}
],
on:{
onMenuItemClick:function(id){
if (this.getMenuItem(id).id == "option1")
// traitement option 1

if (this.getMenuItem(id).id == "option2")
// traitement option 2

if (this.getMenuItem(id).id == "option 3")
// traitement option 3

if (this.getMenuItem(id).id == "option4")
// traitement option 4
}
},
    type:{
        subsign:true
    }
});
</script>
Exemple de rendu
Notre composant UI va donc s'insérer dans notre DIV ("mon_div").

Vous pouvez par exemple définir la largeur des options d'un menu (ex : "width:160").

Vous noterez la gestion des options sélectionnées.

Il est possible d'aller plus loin en ajoutant par exemple des sous - menus ou à modifiant le style du menu.

Pour plus d'informations, veuillez consulter la documentation de Webix.

vendredi 20 mars 2015

Node.js : nouvelle version !

mardi 17 mars 2015

Lancer des applications Linux sous Windows

Underscore.js 1.8.0 : nouveautés