:: Accueil :: Présentation de SWT/JFace :: Comparatif SWT/Swing :: Téléchargements :: Liens :: Contacts ::

:: Présentation de SWT/JFace :: Principes de fonctionnement ::

:: Présentation de SWT ::

SWT (Standard Widget Toolkit) est une bibliothèque graphique Java développée par IBM pour eclipse. Celle-ci est distribuée librement en open source par IBM et peut donc être utilisée par les développeurs pour créer des plugins pour eclipse ou des applications en standalone.

Au-delà de considérations commerciales, on peut se demander pourquoi IBM a développé cette bibliothèque et n'a pas utilisé le célèbre AWT/Swing de Sun. L'article " SWT: The Standard Widget Toolkit - PART 1: Implementation Strategy for Java™ Natives " donne une argumentation technique à ce choix.

Les bibliothèques graphiques multi-plateformes comme Swing sont difficiles à écrire et à maintenir. Les grandes différences entre plateformes rendent leurs composants graphiques complexes. SWT résout ce problème en utilisant des techniques d'implémentation de bas niveau. En effet, la stratégie de SWT est totalement différente. SWT à la particularité de procurer des composants graphiques natifs d'une manière indépendante de l'OS.


:: Stratégie de SWT ::

L'API SWT est implémentée sur différentes plateformes en utilisant une combinaison de Java et de JNI spécifique à chaque plateforme. Il ne faut pas s'y tromper, SWT est développé en totalité en Java : le JNI est uniquement utilisé pour invoquer le système d'exploitation. Il y a un mapping " one to one " entre les méthodes natives Java et les appels à l'OS.

Pour comprendre cette stratégie, l'article précédemment cité explique par un exemple comment est développée en SWT la sélection sur une zone de texte.
Le composant graphique concerné (zone de texte) est un objet Java de type Text.
Voici le code utilisé par une application pour initialiser le texte affiché et pour fixer la selection :

/* Select positions 2 to 5 */
text.setText ("0123456780");
text.setSelection (2, 5);


L'implémentation de la méthode setSelection est différente sur chaque plateforme.

Windows
Motif
public void setSelection (int start, int end) {
OS.SendMessage (handle, OS.EM_SETSEL, start, end);
}
public void setSelection (int start, int end) {
int xDisplay = OS.XtDisplay (handle);
if (xDisplay == 0) return;
OS.XmTextSetSelection (handle, start, end, OS.XtLastTimestampProcessed (xDisplay));
OS.XmTextSetInsertionPosition (handle, end);
}
class OS {
public static final int EM_SETSEL = 0xB1;
public static final native int SendMessage (int hWnd, int Msg, int wParam, int lParam);
...
}

class OS {
public static final native void XmTextSetSelection (int widget, int first, int last, int time);
public static final native int XtLastTimestampProcessed (int display);
public static final native void XmTextSetInsertionPosition (int widget, int position);
public static final native int XtDisplay (int widget);
...
}
JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_win32_OS_SendMessage__IIII
(JNIEnv *env, jclass that, jint hWnd, jint Msg, jint wParam, jint lParam)
{
return (jint) SendMessage((HWND)hWnd, Msg, wParam, lParam);
}

JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_motif_OS_XmTextSetSelection
(JNIEnv *env, jclass that, jint widget, jint first, jint last, jint time)
{
XmTextSetSelection((Widget)widget, first, last, time);
}


On constate bien que les implémentations spécifiques à chaque plateforme sont faites uniquement en Java dans la méthode setText. Le code natif, mis à disposition dans la classe OS, ne fait qu'appeler les fonctions natives de l'OS.

Il y a donc une implémentation des composants SWT pour chaque plateforme mais la signature des méthodes publiques reste la même. L'application qui utilise les composant SWT est donc bien multiplateforme.

La stratégie " one to one " est appliquée strictement pour diverses raisons. Les principales sont :
- la séparation des responsabilités : les développeurs Windows développent les implémentations de composants sous Windows et les développeurs Motif développent les implémentations en Motif ; sans se soucier l'un de l'autre.
- le langage Java est un langage de haut niveau. Il présente en tant que tel un grand nombre d'avantages connus par rapport à d'autres langages comme le C : gestion de la mémoire, classes réutilisables, …
- le code source se situe à un seul endroit. Ainsi la maintenance est plus simple. Il est également plus simple de faire du " performance tuning " sachant qu'une fois que le code natif est appelé, les performances dépendent uniquement du système d'exploitation.

:: Gestion des ressources en SWT ::

Nous l'avons vu précédemment, SWT utilise des ressources du système d'exploitation.
Comme dans toute application, les ressources allouées se doivent d'être libérées, faute de quoi, on risque de faire planter son application ou les autres applications tournant sur le système par manque de ressource.
L'article " SWT: The Standard Widget Toolkit - PART 2: Managing Operating System Resources " explique très clairement comment gérer les ressources allouées par SWT à l'aide de 2 règles à retenir :

- Si on le créé, on le libère
Les ressources sont allouées automatiquement dans les constructeurs des composants SWT. Ainsi, chaque fois que l'on créé une instance d'un composant SWT, il est nécessaire après son utilisation de libérer les ressources allouées en appelant la méthode dispose() dessus. Attention, il faut uniquement libérer les ressources de ce que l'on a créé explicitement. En effet, la création d'un composant SWT peut engendrer l'allocation d'autres ressources telles que des polices ou des couleurs. Ce n'est pas au développeur de les libérer, elles seront libérées automatiquement par la classe qui les a créé.
Ainsi, la présente règle doit également être comprise dans le sens : " on ne libère que ce qu'on a créé ".
Prenons un exemple : si on alloue explicitement une police " Font font = new Font(device, fontData); ", il est nécessaire de la libérer ultérieurement avec " font.dispose(); ". Par contre, si on récupère une police d'un composant " Font font= control.getFont(); ", il ne faut pas la libérer.

- La libération d'un parent libère les enfants
Un composant graphique ne peut pas exister dans le système d'exploitation sans composant parent. Ainsi, si le composant parent est libéré, les composants enfants seront automatiquement libérés. Cette règle simplifie grandement la gestion des ressources.
Ceci dit, certains composants dits " non graphiques " comme Font ou Color ne sont pas des enfants. Il faudra systématiquement les libérer " manuellement " lorsqu'ils auront été alloués explicitement par le développeur. En effet, un composant SWT ne libèrera jamais une ressource qui a été allouée par un développeur. Ceci enfreindrait la première règle.

On peut se demander pourquoi la libération des composants SWT n'est pas prise en charge par le garbage collector Java. L'article explique que ceci est principalement dû au fait qu'il est impossible de connaître l'ordre de libération des objets par le garbage collector. De ce fait, la libération aléatoire de certains composants avant d'autres risquerait de provoquer des bugs graphiques, voire des plantages.

 
(c) 2004 Nicolas SEBBAN