The trashiest blog in the World...

Aller au contenu | Aller au menu | Aller à la recherche

Java et internationalisation

Je développe régulièrement en Java ; que ce soit pour des projets personnels (applications « de bureau » basées sur Swing principalement) ou pour le boulot.

Dans le développement d'une application, songer à un système d'internationalisation assez rapidement est je pense généralement bénéfique pour deux raisons :

  • il est alors possible de traduire rapidement et facilement votre application en d'autres langues (ben oui, c'est fait pour !),
  • la relecture des chaînes originales ou traduites par une tierce personne est grandement facilitée ; nul besoin de pousser l'application dans ses derniers retranchements pour qu'elle affiche le message d'erreur qui ne devrait jamais être affiché :-p

Lorsque j'ai débuté en Java, je travaillais sur un logiciel de gestion de cantines scolaires, et l'implémentation d'un système i18n - bien que non requis par le « cahier des charges » de l'époque - m'est apparue naturelle.
J'ai en conséquence potassé un peu Java, et découvert les histoires de ResourceBundle et de fichiers .properties. J'ai rapidement trouvé un plugin pour l'IDE que j'utilisais (et que j'utilise toujours d'ailleurs - Eclipse) qui facilitait la saisie des chaînes.

Voici en gros à quoi ressemble une telle chaîne dans un programme java, en deux parties. D'abord, dans le fichier source .java :

System.out.println(Messages.getString("myapp.says.hello"));

Ensuite, dans le fichier .properties localisé qui va bien (ici, le français) :

myapp.says.hello=Un bonjour de mon application

Premier problème : la chaîne contenue dans le fichier Java est totalement dénuée de sens, et par moments (voire même souvent), il faut se référer au fichier .properties pour savoir quel était le message prévu.

Second problème : depuis quelques années, je n'avais pas ou très très peu utilisé ce système (pour le boulot, on utilise Cocoon qui fournit son propre système d'internationalisation, basé sur des fichiers XML) ; et le plugin que j'avais trouvé à l'époque ne fonctionne plus avec les versions récentes de Eclipse. Pire : je ne suis pas parvenu à trouver une quelconque application qui me permette de gérer « facilement » ces fichiers.

Et là, c'est un gros problème. En effet, les fichiers .properties sont de simples fichiers textes ; mais dans lesquels les caractères spéciaux tels les accents, les guillemets («»), etc doivent être encodés en unicode. Pour vous donner un exemple :

myapp.prefs=Pr\u00E9f\u00E9rences

Relire et éditer pareilles chaînes de caractères est difficile sinon impossible (personnellement, j'abandonne au bout de moins de 5 lignes en lecture). Une faute de frappe dans les caractères unicode empêche le catalogue complet de se charger, et à priori sans lever d'exception (nous n'avons tout du moins pas trouvé comment faire :-( ).

Je me suis très récemment décidé à essayer de travailler un peu sur mon logiciel de gestion de Cantines, et me suis retrouvé face à ce problème lorsque j'ai voulu modifier une chaîne existante. ; du bonheur en barres :-D

En cherchant un peu, j'ai découvert le projet gettext-commons qui permet d'internationaliser des applications Java avec les méthodes gettext ! Dans l'application, on se retrouve donc avec quelque chose dans le genre de :

System.out.println(i18n.tr("Preferences"));

Chaîne qui sera ensuite extraite automatiquement du code source, ajoutée dans un fichier .po lequel fichier vous pourrez traduire en utilisant un des nombreux outils disponibles. Je préfère nettement cette solution à la première :-)
Pour ne rien gâcher au plaisir, gettext-commons supporte la pluralisation, la contextualisation, le remplacement de variables dans les chaînes, ... La documentation est assez claire pour mettre en place ce système facilement et rapidement dans un projet.

Seul bémol pour le moment : il faut générer le fichier jar localisé pour voir le résultat dans votre application, c'est parfois un peu lourd (ou bien j'ai sauté la partie de la doc qui explique comment faire autrement :-p )

Petite note tant que j'y suis ; c'est normalement documenté (mais je n'ai pas retrouvé la page) ; méfiez-vous des apostrophes dans les chaînes où vous souhaitez effectuer un remplacement de variables. En effet, la chaîne suivante (quel que soit le système utilisé) :

L'application {0} est perdue.

S'afficherait de la sorte :

Lapplication {0} est perdue.

Sans apostrophe, et sans que la variable n'ait été remplacée, donc !
Pour ces cas de figure, il suffit d'échapper l'apostrophe avec une autre apostrophe (!) et le tour est joué. Ainsi :

L''application {0} est perdue.

Donnera :

L'application monappli est perdue.

Commentaires

1. Le lundi 19 avril 2010, 15:54 par gilles

Ayant des notions faibles en programmation et aucune en Java, mais suffisantes pour m'étonner de la persistance en C du type char à 8 bits, alors que le passage à 16 bits règlerait bien des problèmes ( UTF-16 ), ceci alors que depuis la création du C, les machines ont largement multiplié les performances.