Sometimes I write things, sometimes I don't.

To content | To menu | To search

Friday 18 November 2011

Chaînes de caractères dynamiques

mobile.png Tout bon programmeur Android a pour habitude de lister toutes les chaînes de caractères (ou presque) dans le fichier res/values/strings.xml. A priori, seules les chaînes de caractères statiques ne peuvent être mises dans ce fichier. Mais, il existe des méthodes pour rendre ces chaînes un petit peu plus dynamique qu'elles n'y paraissent. Voyons tout ça.

1. Les formes plurielles

Les formes plurielles varient plus ou moins d'un langage à un autre. Par exemple, en français, on peut vouloir écrire :

  • Je ne possède pas de stylo.
  • Je possède un stylo.
  • Je possède des stylos.

L'API Android met à disposition plusieurs distinctions de formes plurielles grâce à 6 mot clés.

  1. zero, pour la quantité 0 ;
  2. one, pour la quantité 1 ;
  3. two, pour la quantité 2 ;
  4. few, pour représenter une petite quantité ;
  5. many, pour représenter une moyenne quantité ;
  6. other, pour représenter une quantité supérieure à une autre suivant la langue.

En français, on aura tendance à n'utiliser que zero, one et other.
Ainsi pour former les chaînes précédemment citées on mettra dans notre fichier res/values/strings.xml le code suivant :

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <plurals name="nombreDeStylos">
    <item quantity="zero">Je ne possède pas de stylo.</item>
    <item quantity="one">Je possède un stylo.</item>
    <item quantity="other">Je possède des stylos.</item>
  </plurals>
</resources>

Dans le code Java, on récupérera la bonne forme de cette manière.

final List<Stylo> stylos = getStylos();
final int count = stylos.size();
final String text = this.getResources().getQuantityString(R.plurals.nombreDeStylos, count, count);

2. Formatage des chaînes

Il peut être également utile d'afficher des nombres dans les chaînes de caractères comme par exemple : "Bonjour X, vous avez Y nouveaux messages !". Cela se fait de manière relativement simple grâce à la méthode String.format(String, Object...) de Java. Cette méthode est également invoquée automatiquement lors de l'utilisation de Context.getString(int, Object...). La chaîne de caractères à formater doit contenir quelques marques de formatage comme %1$s pour dire qu'il faut remplacer cette marque par le premier argument et que celui-ci est une chaîne de caractère ou encore %2$d pour dire qu'il faut mettre ici le second argument qui est un entier.
Ainsi dans le fichier res/values/strings.xml on écrira :

<string name="welcome_message">Bonjour %1$s, vous avez %2$d nouveaux messages !</string>

Et on utilisera le code Java suivant :

final String username = "toto";
final int mailCount = 10;
final String text = String.format(this.getResources().getString(R.string.welcome_message), username, mailCount);

On pourra aussi utiliser celui-ci :

final String username = "toto";
final int mailCount = 10;
final String text = this.getResources().getString(R.string.welcome_message, username, mailCount);

3. Conclusion

Comme on peut le voir Android met à disposition plusieurs méthodes pour manipuler les chaînes de caractères et les rendre aussi flexibles que possible tout en simplifiant un maximum le travail des traducteurs par exemple. Il ne reste plus qu'à exploiter ces possibilités pour créer un code simple et efficace.

Thursday 6 January 2011

Et quand l'activité a besoin d'un objet ?

mobile.pngJe ne me souviens pas avoir parlé de programmation Android par ici. ce billet est donc l’occasion de commencer l’exploration du merveilleux OS mobile que nous fournit gracieusement Google. J’ai un smartphone qui carbure avec Android depuis bientôt 2 ans et je ne m’étais intéressé que vaguement à la programmation d’applications dessus. Dans mon parcours universitaire, j’ai eu l’occasion d’aborder ce sujet et mon projet tuteuré consiste principalement à faire une application pour Android. Trêve de blabla, passons à l’action.

Je ne vais pas refaire un cours sur Android, nombre de tutoriaux et d’exemples sont disponibles sur la toile. Dans le cadre de mon projet, j’avais donc un souci pour passer de l’information d’une activité à une autre. En effet, seuls les types primitifs et quelques autres trucs peuvent être passés d’une activité à une autre. Malheureusement, pas moyen de faire voyager un objet “simple” sans modification. Il faut qu’il implémente soit Serializable (connu par tous les bons programmeurs Java) soit Parcelable (propre à Android), “pour les surprendre on peut aussi faire les deux” (private joke).

Dans le cas présent, nous allons voir comment faire en implémentant l’interface Parcelable car cela demande un peu plus de code et de compréhension. Considérons un objet Message, sa classe (de base) s’écrirait très simplement.

class_message.png
Pour pouvoir faire naviguer cet objet entre plusieurs activités, on va donc le faire implémenter l’interface citée précédemment. Et c’est ici qu’il faut penser à quelques ajouts bien précis. L’objet implémentant Parcelable doit contenir un champ static appelé CREATOR de type Parcelable.Creator. De plus, 2 méthodes seront à redéfinir. Notre classe message se transforme alors comme la suivante.

class_message_parcelable.png
À ce stade, tous nos objets de type Message pourront être transférés d’une activité à une autre. Pour cela, on va donc utiliser un Bundle avec la méthode putParcelable(Parcelable).

class_sender.png
À noter qu'en tant qu’identifiant de l’objet dans le bundle, j’ai mis son nom complet (package + classe) ce n’est pas un hasard. Maintenant, on peut voir comment récupérer l’objet dans l’activité qui va le réceptionner.

class_receiver.png
Voilà qui est fait. Remarquez qu’il n’y a pas besoin de “caster” l’objet de type Parcelable récupéré, je vous laisse deviner grâce à quoi. Je ne prétends pas que ma méthode soit la meilleure, ni la plus sécurisée, etc… Tout ce que je sais, c’est que pour l’instant ça marche. L’expérience venant en codant, j’en saurai davantage sur l’efficacité de cette technique plus tard. Toutes améliorations et/ou remarques sont les bienvenues.

Saturday 30 January 2010

Lancer un programme en anglais sans changer la langue

Il peut être intéressant, pour une raison ou une autre, de vouloir utiliser un programme en anglais sur un système configuré dans une autre langue. Dans mon cas, je voudrais pouvoir réaliser simplement quelques captures d'écran de GNOME Split en anglais.

Dans un tel cas, il serait forcément assez lourd de changer la langue de tout le système pour lancer un logiciel. C'est là qu'intervient la variable d'environnement LANG. C'est avec cette variable que nous allons jouer. Pour commencer, on peut entrer la commande suivante dans un terminal.
~$ echo $LANG

Si votre système est en français comme le mien, vous devriez probablement avoir comme résultat la chaîne de caractères suivante : fr_FR.UTF-8.

Pour lancer un logiciel en anglais, on va modifier cette variable seulement dans le "terminal" où l'on va lancer le programme. Pour cela, on crée un script qui va donner à la variable LANG la valeur C puis exécuter la ligne de commande passée en argument du script (ligne de commande identique à celle que l'on utiliserait pour lancer le logiciel normalement).

Pour faire le script, on crée puis édite un fichier nommé (comme on veut en fait) english.sh et on y met le code suivant :

#!/bin/bash
LANG=C "$@"


Ensuite, on enregistre puis on rend le script exécutable.
~$ chmod +x english.sh

Finalement, on lance le script et on passe en paramètre la ligne de commande à exécuter.
~$ ./english.sh transmission

En voilà ce que ça donne (un peu de pub ça fait pas de mal non roh).

Wednesday 9 September 2009

Exploitez vos codes C grâve à Java et sa JNI

Maintenant que je travaille depuis quelques semaines sur java-gnome, j'ai eu l'occasion (à plusieurs reprises) d'utiliser la JNI (pour Java Native Interface). Cet aspect de Java permet notamment d'exploiter du code C et C++ sans avoir à le réécrire totalement en Java ce qui n'est pas toujours possible (java-gnome n'est déjà pas complet alors réécrire GNOME en Java... on n'en parle même pas). Jusqu'à maintenant, je n'ai jamais vraiment cherché à comprendre comment la JNI fonctionnait, je me contentais de l'exploiter en me basant sur les divers codes déjà présents. Si j'écris cet article, on peut donc se douter que je suis allé un peu plus loin dans le sujet.

En effet, en recherchant une solution pour un problème (récupérer la taille de l'espace disque restant), je suis tombé sur de nombreux résultats dans lesquels les utilisateurs conseillaient d'utiliser un code natif via la JNI. C'est donc grâce à ça que j'ai décidé de comprendre comment la machine fonctionne (le côté JNI de java-gnome étant généré automatiquement, on ne le touche pas souvent). Pour comprendre comment utiliser la JNI, nous allons donc utiliser 3 méthodes que je qualifierais d'exemplaires. Pas parce que le code est impeccable, mais plutôt car on pourra voir comment gérer les paramètres et les types de retour.

Continue reading...

Sunday 16 August 2009

java-gnome's cool new stuffs

C'est vrai, c'est génial ! Ce que j'ai toujours aimé dans le projet java-gnome, c'est sa facilité d'accès lorsque l'on connaît un peu le langage Java. Je préfère de loin réaliser une interface graphique avec java-gnome qu'avec Swing. Pourquoi ? Déjà parce que c'est plus beau et surtout parce que c'est plus simple.

Bon trêve de compliments, je ne suis pas là pour expliquer à quel point écrire des applications avec java-gnome c'est bien. Quoi que ça serait presque çamais bon...

Depuis la version 4.0.12 de l'API, j'essaie de contribuer pas mal à son développement même si avec mon travail qui n'a rien à voir avec l'informatique je suis plutôt crevé en rentrant. Cependant, je prends quand même le temps de développer plusieurs branches. J'avais donc envie de faire un petit point sur les nouveautés qui arriveront (j'espère) pour la version 4.0.13 de java-gnome.

Je commence par la première branche que j'ai codé seul et qui est terminée (elle est en attente d'intégration défintive dans l'API). Cette branche est nommée entry-gtk-2.16. Elle a pour but d'ajouter les fonctionnalités arrivées pour les GtkEntry avec GTK 2.16 dans la classe Entry de java-gnome. Ainsi tout comme avec la bibliothèque de développement en C, on pourra mettre des icônes des deux côtés de l'entrée de texte ou encore se servir de l'indicateur de progression qui y est intégré. Voici une démonstration :


Les branches suivantes que je développe étaient auparavant codées par Serkan Kaba qui depuis a lancé un appel afin que quelqu'un reprenne son travail. C'est donc ce que j'ai fait avec 3 de ses branches.

Je me suis intéressé pour commencer à l'intégration de libsexy dans java-gnome. Cette bibliothèque apporte quelques widgets intéressants en plus à GTK. Je peux à présent considérer mon travail sur l'intégration de libsexy presque terminé puisque tout a été implémenté par Serkan et moi. On pourra, donc une fois le merge avec le code l'API fait, utiliser des Labels contenant des liens,


mais aussi, des Entrys supportant les corrections orthographiques (truc dont j'ai besoin),


des textes d'astuces (tooltips) différents selon les lignes des TreeViews et enfin, des widgets Tooltip pouvant contenir des choses plus complexes que des simples lignes de texte.


J'ai également décidé de ne pas implémenter le SexyIconEntry puisque la classe Entry de GTK 2.16 offre encore plus de fonctionnalités.

J'ai aussi travaillé sur une branche visant à implanter le widget offert par la bibilothèque nommée VTE (pour Virtual Terminal Emulator). Les amateurs de GNOME connaissent probablement ce widget puisque c'est lui qui est utilisé par l'émulateur de terminal de GNOME.


Enfin, pour terminer, j'ai terminé le code d'une branche dédiée à ajouter les fonctionnalités liées au LinkButton (bouton contenant un lien). On pourra donc alors profiter de ce widget dans java-gnome mais également profiter de ses nouveautés dans la boîte de dialogue AboutDialog. En effet, jusqu'à présent, on ne pouvait qu'insérer un lien et l'afficher afin de spécifier le site web de l'application à laquelle cette boîte de dialogue était attachée. Maintenant, ce lien devient intéractif, c'est-à-dire qu'un clic dessus permettra d'ouvrir le navigateur web à l'adresse donnée.


C'est tout pour le moment, j'espère que chacune de ses branches sera intégrée dans java-gnome avant la sortie de la version 4.0.13 (qui sera d'ailleurs peut-être estampillée 4.1.1) et qui promet encore de belles choses.

Ah oui j'oubliais, on m'a des fois fait la remarque suivante : "Wa pour développer java-gnome faut connaître le C et la JNI non ?". Et bien en fait non, il n'y a pas besoin de savoir manipuler le C et la JNI. En effet, tout ce qui est code C / JNI est automatiquement généré par un ... générateur ... qui grâce à des fichiers de types .defs et les .h des bibliothèques génère le code C / JNI automatiquement. Il ne reste donc que l'API public (haut niveau si je peux dire ça comme ça) à écrire. Bien entendu, il y a toujours des cas particuliers (comme je suis un grand chanceux, je suis tombé dessus...) où il faut écrire quelques bouts de code en C pour contourner certains "manques" de Java (comme les callbacks).

Tuesday 7 July 2009

Migration de SVN vers Bazaar

Migrer d'un système de contrôle de version à un autre peut parfois être utile. On peut distinguer deux raisons de migration :

  • le besoin (pour des raisons de gestion du projet), et,
  • l'envie (par préférence d'utilisation).

Le cas numéro 2 a été le mien. En effet, en développant de plus en plus pour java-gnome, je me suis pris d'affection pour Bazaar. J'ai donc décidé de migrer le code de gSplit de SVN à Bazaar sans perte de données.

Continue reading...

Sunday 31 May 2009

Démo : la version 1.1.1 de gSplit en vidéo

Ça commence à faire un petit moment que je n'avais pas parlé de gSplit et donc que je n'avais pas fait part de mon développement sous Ubuntu avec Java et GTK. Donc voilà une petite vidéo pour vous montrer l'actuelle version stable (numérotée 1.1.1) du petit gSplit.

La vidéo est téléchargeable.

Dès à présent, vous pouvez trouver une version packagée de gSplit dans mon PPA sur Launchpad (bien entendu, c'est un dépôt non officiel donc il faut faire attention). Pour le moment, seules les personnes utilisant Jaunty Jackalope peuvent en profiter. Pour plus d'informations pour obtenir gSplit, vous pouvez jeter un coup d'oeil sur la page qui lui est dédiée dans la documentation.

Dans un deuxième temps, comme dit à la fin de la vidéo, dans le but de développer la version 2.0.0 (qui est déjà commencée en fait), vous pouvez me suggérer toutes vos idées pour améliorer le programme aussi bien au niveau ergonomique qu'au niveau des fonctionnalités. Je prendrai note et tenterai de faire le maximum pour contenter tout le monde.

Thursday 5 March 2009

java-gnome 4.0.10 est de sortie

Depuis le temps que je l'attendais, et après nous avoir fait patienter avec 3 releases candidates, la version 4.0.10 de java-gnome est enfin disponible. Comme son nom l'indique, le but de cet API est d'offrir la possibilité aux programmeurs utilisant le langage Java de développer des applications en profitant d'une interface GTK parfaite pour GNOME. Si vous hésitez à vous lancer, il doit y avoir un tutoriel rapide qui traine par ici. Pour voir les nouveautés, vous pouvez vous diriger sur cette page qui offre un résumé complet des changements effectués depuis la version 4.0.9. Pour en faire le tour rapidement, on y trouve un support grandissant pour l'utilisation de Cairo, des améliorations au niveau des widgets tels que les vues arborescentes (treeview) ou les vues textes (textview), le support du presse-papier (clipboard) et je passe sur le reste. Je vous rappelle que si vous voulez avoir un exemple d'une application, vous pouvez toujours faire un tour du côté de gSplit en plus de la consultation des exemples proposés dans l'API. Au niveau du téléchargement, vous pouvez désormais jeter un coup d'oeil sur le FTP, ou alors profiter des paquets déjà disponibles sur mon PPA (dépôt non officiel, attention au chien). En cadeau bonux, un screenshot de gSplit ^^

- page 1 of 2