TUTORIELS 
S'affranchir des frontières en Java
Même si l'anglais prédomine sur Internet, "internationaliser" ses programmes Java permet à vos utilisateurs de bénéficier d'une interface adaptée. Dates, formats numériques et autres messages sont alors à coup sûr compréhensibles.  (28 novembre 2001)
 

Vous avez de grandes ambitions pour le programme Java que vous développez actuellement : quelques millions de téléchargements à prévoir dans les prochaines semaines. Tout d'abord félicitations, mais ne vous réjouissez pas trop vite. Avez-vous pensé à "l'internationaliser" ? Vous n'envisagez tout de même pas de distribuer un programme où les messages, les formats numériques, les dates, sont stockés "en dur" dans le programme ?
L'internationalisation consiste à isoler les parties du programme dépendantes de la langue. Voici comment résoudre une partie de ces problèmes à l'aide d'un exemple simple en Java.

Exploiter les codes ISO

Sur la toile, l'anglais règne en maître, certes. Avouez cependant que lorsqu'on vous donne le choix de choisir votre langue dans une application, vous choisissez volontiers la vôtre, d'autant plus si vous ne maîtrisez pas parfaitement le programme en question.
Par chance, pays et langages sont normalisés par des codes ISO : International Organization for Standardization.

Java utilise cette standardisation pour l'objet "Locale". On identifie un tel objet en concaténant l'identifiant d'un "Resource Bundle" (nous verrons plus tard de quoi il s'agit) avec "_" suivi de deux caractères ISO représentant le langage, suivi d'un autre "_" auquel on ajoute cette fois le code du pays ("country code").
Par exemple...

MyResourceBundle_fr_FR

... Correspond à la langue française utilisée en France, alors que, petite nuance :

MyResourceBundle_fr_CA

... Correspond à la même langue mais utilisée au Canada.

Revenons sur la notion de "Resource Bundle". Ces derniers contiennent des objets "locaux", dans lesquels on trouve des "ressources" appropriées à la localisation de l'utilisateur. En isolant ainsi les données dépendantes de la localisation, vous permettrez à votre programme d'évoluer et d'être traduit plus tard pourquoi pas dans d'autres langues, plus facilement.

Les éléments de notre programme

Afin de mieux comprendre comment s'enchaînent les étapes de l'internationalisation nous allons tenter d'appliquer ses principes sur un petit programme. Celui-ci est réellement très simple, il n'affiche au début que "Bonjour", et "Au revoir" :

public class HelloBye
{
     static public void main(String[] args)
     {
          System.out.println("Bonjour");
          System.out.println("Au revoir ");
     }
}

Copiez ce programme dans un fichier reprenant le nom de la classe : "HelloBye", compilez-le (javac HelloBye.java) et exécutez-le (java HelloBye).

Votre programme destiné à être distribué si massivement ne s'exprime pour le moment qu'en français : vous prenez des risques.
Voyons comment le rendre plus modulaire et isoler les parties dépendantes du langage.

Afin de permettre au plus grand nombre, et pas seulement aux programmeurs, ce qui est un des points importants, de traduire votre programme, les informations propres à une localisation sont stockées dans de simples fichiers textes, manipulables par n'importe quel éditeur de texte. On les appelle des "Properties Files". Ils sont constitués d'un label, qui ne doit pas être modifié quelle que soit la langue, et de la traduction correspondante à ce label dans une langue donnée. Par défaut nous souhaitons que notre programme s'exprime en français, cela donne par exemple :

(Nom du fichier : "MessagesBundle.properties")
Accueil = Bonjour
Depart = Au revoir

Nous voulons également convertir notre programme en anglais et en allemand, nous créeons un "fichier de propriétés" par langage, notez la dénomination de ceux qui vont suivre, elle se base sur les codes ISO des pays et langages :

(MessagesBundle_de_DE.properties)
Accueil = Guten Tag
Depart = Auf Wiedersehen

(MessagesBundle_en_US.properties)
Accueil = Hello
Depart = Bye

Ainsi chaque traducteur peut facilement créer un fichier destiné à enrichir les capacités linguistiques de votre langage à condition de respecter les codes ISO.

Notre programme demandera à l'utilisateur de spécifier sa langue mais si jamais vous souhaitez détecter la configuration par défaut de son système, il faut écrire :

Locale loc = Locale.getDefault();

Vous pouvez sinon la définir manuellement :

locfr = new Locale("fr","FR");

Par la suite notre programme récupèrera, grâce aux paramètres entrés par l'utilisateur, les informations suivantes :

String langue = new String(args[0]);
String pays= new String(args[1]);
currentLocale = new Locale(langue, pays);

Le code de notre programme

Nous n'avons pas encore détaillé tous les mécanismes utilisés par notre programme en vue de son internationalisation, mais afin d'obtenir une vue d'ensemble des procédés, voici tout de même son code source, suivi des commentaires nécessaires :

(Nom du fichier : "HelloByeInt")
import java.util.*;

public class HelloByeInt
{
     static public void main(String[] args)
     {
          String langue;
          String pays;

          // Si le nombre de paramètres passés en ligne de commande est != 2.
          if (args.length != 2)
          {
               langue = new String("fr");
               pays = new String("FR");
          }
         else
         {
              langue = new String(args[0]);
              pays = new String(args[1]);
         }

         Locale currentLocale;
         ResourceBundle messages;
         currentLocale = new Locale(langue, pays);

         messages = ResourceBundle.getBundle("MessagesBundle", currentLocale);
         System.out.println(messages.getString("Accueil"));
         System.out.println(messages.getString("Depart"));
     }
}

Grâce à ce listing vous voyez sans doute mieux les procédés s'enchaîner. Vous pouvez tester ce programme, compilez-le comme le précédent listing et testez-le de la sorte :

java HelloByeInt
(vous obtenez par défaut : "Bonjour" / "Au revoir")

java HelloByeInt de DE
(vous obtenez "Guten Tag" / "Auf Wiedersehen")

et enfin
java HelloByeInt en US
(vous obtenez "Hello" / "Bye")

Il nous restait à voir comment créer les "Resource Bundle", c'est chose faite avec :

messages = ResourceBundle.getBundle("MessagesBundle", currentLocale);

Les arguments passés à la méthode "getBundle" permettent d'identifier quel "Properties files" il faut utiliser. En effet, notre programme ne fonctionne qu'à la condition de créer les trois fichiers :
- "MessagesBundle_de_DE.properties" : pour la traduction allemande
- "MessagesBundle_en_US.properties" : pour la traduction anglaise
- "MessagesBundle.properties" : pour la traduction française et celle par défaut.

Par la suite la méthode getString permet de récupérer les champs précis du "Properties file" qui nous intéressent.

Voici les sources des fichiers impliqués dans ce tutoriel :
- HelloByeInt.java
- MessagesBundle.properties
- MessagesBundle_de_DE.properties
- MessagesBundle_en_US.properties

Enfin, d'autres ressources pour aller plus loin : (gestion des caractères unicode, formatage de date ou de monnaie...)

- Sun
- JGuru / IBM

 
[ Arnaud GadalJDNet
 
Accueil | Haut de page