Les principes de base du GUI

Romain Guy (Gfx)

Nous découvrirons quels sont les principes de base à respecter et comment utiliser de manière optimale l'API Swing pour créer des interfaces originales. ♪

- Titre : Les principes de base du GUI

- Auteur : Romain Guy (Gfx)

- Parution : 26 juillet 2006

- Licence : Cette création est mise à disposition sous un contrat Creative Commons (Paternité - Partage des Conditions Initiales à l'Identique).

Sommaire

- Introduction

- I. L'abécédaire du GUI

- II. Java Swinguer !

- III. Screenshots

- IV. Les sources

Introduction

Beaucoup de programmeurs ont tendance à délaisser l'attention portée à la création de l'interface graphique (ou GUI pour « Graphical User Interface ») de leur logiciel. Malheureusement, quelle que soit la puissance de votre application, vous trouverez toujours un utilisateur pour dire : « Je préférerais que ce bouton soit vert ». Ceci est très frustrant quand vous avez passé plusieurs nuits blanches à faire fonctionner ledit bouton. Mais aucune échappatoire n'est possible : les utilisateurs sont en général plus sensibles à l'aspect graphique d'un logiciel plutôt qu'à sa puissance intrinsèque. C'est pourquoi il est de votre devoir de peaufiner vos interfaces utilisateur dans leurs moindres détails avant de diffuser vos applications. Il existe quelques règles à respecter si vous souhaitez créer un environnement de travail agréable. Nous commencerons par étudier celles-ci avant de nous intéresser à la création de beaux GUI en Java.

I - L'abécédaire du GUI

Nombre d'entre vous seront peut-être décontenancés par la logique des propos qui suivent, mais ce n'est pas un mal de les rappeler. Voici donc les règles primordiales à respecter lors de la réalisation d'une interface.
Tout d'abord, veillez à éliminer tout le superflu. Mais attention, ne sombrez pas dans le minimalisme ! Un bandeau en dégradé de couleur contenant un titre, par exemple, n'est pas nécessairement superflu. Ce genre d'élément graphique peut apporter couleurs et lisibilité à votre logiciel. Si vous décidez de créer ou de modifier des composants graphiques, ne tombez pas dans l'excès inverse, c'est-à-dire la surcharge graphique. Le logiciel de messagerie ICQ est un parfait exemple d'interface surchargée graphiquement. Le but est d'offrir une image agréable à l'œil, mais parfaitement claire.
Une méthode très efficace pour créer une bonne interface est d'utiliser la réactivité de celle-ci. Par exemple, vous pouvez créer des boutons qui changent de couleur lors du passage de la souris. Ce genre de petite astuce conforte l'utilisateur dans son idée que le logiciel est là pour le servir.
Essayer de réaliser, si possible, un GUI dynamique. Une interface dynamique est une interface qui s'adapte aux besoins de l'utilisateur. Prenons l'exemple d'un environnement de développement supportant plusieurs langages : lorsque l'utilisateur édite un fichier HTML, des menus d'édition dédiés au HTML devront apparaître tandis que ceux destinés aux autres langages devront disparaître. Et ceci prévaut pour tous les composants de l'interfacebv : boutons, barres d'outils… Ne vous contentez pas de « griser » les composants : cachez-les ! Une telle dynamique permet d'offrir les seules fonctions utiles et le gain pour vous est double : le logiciel paraît plus simple d'emploi et également plus riche.
Structurez le contenu des fenêtres ! Regroupez les composants par utilité puis par nature : dans une boîte d'options, places les options générales ensemble puis regroupez les champs de texte en haut, les cases à cocher en bas… Il est possible d'améliorer la structure d'une interface en utilisant des panneaux séparateurs « titrés » ou encore en créant des séparateurs de menu affichant des titres.
Enfin, laissez la possibilité à l'utilisateur de modifier le plus possible l'aspect, voire le contenu, de l'interface graphique.

II - Java Swinguer !

Maintenant que vous connaissez les principes de base, nous allons en appliquer quelques-uns avec l'API Swing et découvrir comment personnaliser les composants.
Commençons par nous attaquer à la clarté de l'interface. Étudions donc une interface graphique Swing classique. La première chose à remarquer est que les polices utilisées sont en gras. Ceci nuit à l'interface dans la mesure où elles apportent une touche « comique » à l'environnement. Pour revenir à quelque chose d'aussi agréable, mais de plus professionnel, il suffit de changer ces polices. Le Look And Feel Metal (par défaut) de Swing propose un système très simple pour arriver à nos fins : les thèmes. Un thème Metal est une classe héritant de javax.swing.plaf.metal.DefaultMetalTheme et qui surcharge ses méthodes. Chaque méthode de cette classe est utilisée par Metal pour obtenir les informations de couleur ou autres sur l'interface. Nous allons donc simplement modifier les valeurs de retour des méthodes retournant des polices de caractère. Voici une partie du code de notre nouveau thème :

public class JextMetalTheme extends DefaultMetalTheme
{
private FontUIResource font = new FontUIResource(new Font("Dialog", Font.PLAIN, 11));

public JextMetalTheme() {
super();
}

public FontUIResource getMenuTextFont() {
return font;
}
//...
}

Dans cet extrait, la police du texte des menus sera une police de type Dialog, en taille 11 et sans style. Enfin, pour utiliser ce thème, un simple appel à la méthode setTheme() de la classe MetalLookAndFeel suffit.
La seconde chose que nous allons modifier dans les composants Swing est les bordures des menus. Les menus par défaut sont en relief. Nous allons tout simplement les modifier pour les remplacer par de simples lignes noires. La création d'une bordure est extrêmement simple : il suffit d'appeler la méthode « setBorder()» des composants. Dans le package javax.swing.border, vous trouverez plusieurs bordures intéressantes. Nous allons pour notre part utiliser les bordures LineBorder et EmptyBorder. La première classe sera utilisée comme ceci : LineBorder.createBlackLineBorder() pour créer une bordure noire, de un pixel de large. La seconde classe servira à créer de l'espace supplémentaire autour du composant. Ainsi, la classe org.jext.JextMenu dérivant de Jmenu attribue une bordure LineBorder à son menu déroulant. La classe JextMenuItem pour sa part utilise un EmptyBorder de 2 pixels de large.
Jusqu'à présent nous nous sommes contentés d'utiliser des fonctions de Swing pour modifier l'interface. Il est donc temps de modifier nous même l'aspect des composants. Le programme d'exemple propose deux composants modifiés : le JextMenuSeparator, un séparateur de menu affichant une ligne noire, et le JextLabeledMenuSeparator qui affiche un séparateur de menu possédant un titre. Les deux sont créés de manière similaire. Penchons-nous donc sur le second. Pour modifier un composant, commencez par créer une classe dérivant celui-ci : dans notre cas, nous héritons de JPopupMenu.Separator. Ensuite, nous devons modifier le « UI » utilisé par le composant. Plusieurs étapes sont nécessaires. Premièrement, il faut déclarer le nouvel UI du composant. Cet UI sera la classe qui gérera l'affichage du composant à l'écran. Voici comment procéder :

private static final String uiClassID = "JextLabeledMenuSeparatorUI";
static{
UIManager.getDefaults().put("JextLabeledMenuSeparatorUI",
"org.jext.gui.JextLabeledMenuSeparatorUI");
}

Pour changer l'UI, il tout simplement associer un identificateur d'UI (ici la variable uiClassID) à la classe chargée de l'affichage au sein du gestionnaire de UI de Swing. La déclaration de la variable uiClassID servira par la suite. Lorsqu'un composant Swing est créé, la méthode getUIClassID() est appelée pour associer le composant à son UI. Nous devons donc surcharger cette méthode pour qu'elle retourne notre propre UI :

public String getUIClassID(){  return uiClassID;}

Enfin, nous devons terminer nos modifications en surchargeant l'appel à la méthode updateUI() qui sert à associer l'UI au composant :

public void updateUI(){
this.setUI((JextLabeledMenuSeparatorUI);
UIManager.getUI(this));
}

Cette méthode doit impérativement être appelée dans le constructeur de notre composant. Seule reste la création de l'UI lui-même. Pour créer un UI il suffit de créer une classe héritant de ComponentUI et implantant la méthode surchargée :

public static ComponentUI createUI(JComponent c){
return new JextLabeledMenuSeparatorUI(c);
}

Notez le paramètre de type JComponent. Votre UI doit le prendre en compte. Pour terminer, surchargez la méthode paint() de ComponentUI et placez-y le code d'affichage du composant.
Le programme d'exemple contient des boutons réactifs. Toutes les modifications de l'interface sont dans les sources du package org.jext.gui, étudiez-les avec soin !

III - Screenshots

Notre exemple avec les composants Swing…

…et le même après nos modifications

Forté For Java dispose d'une excellente interface

Les modifications de Swing sont tirées de ce logiciel

IV - Les sources

Toutes les sources de ce tutoriel sont incluses dans le zip joint ci-dessous :
- Les sources