38. Le développement d'interfaces graphiques avec SWING 40. JFace Imprimer Sommaire Consulter avec table des matières
Développons en Java   v 2.10  
Copyright (C) 1999-2016 .  

 

39. Le développement d'interfaces graphiques avec SWT

 

chapitre 3 9

 

Niveau : niveau 3 Intermédiaire 

 

La première API pour développer des interfaces graphiques portables d'un système à un autre en Java est AWT. Cette API repose sur les composants graphiques du système sous-jacent ce qui lui assure de bonnes performances. Malheureusement, ces composants sont limités dans leur fonctionnalité car ils représentent le plus petit dénominateur commun des différents systèmes concernés.

Pour pallier ce problème, Sun a proposé une nouvelle API, Swing. Cette Api est presque exclusivement écrite en Java, ce qui assure sa portabilité. Swing possède aussi d'autres points forts, telles que des fonctionnalités avancées, la possibilité d'étendre les composants, une adaptation du rendu de composants, etc ... Swing est une API mature, éprouvée et parfaitement connue. Malheureusement, ses deux gros défauts sont sa consommation en ressource machine et la lenteur d'exécution des applications qui l'utilisent.

SWT propose une approche intermédiaire : utiliser autant que possible les composants du système et implémenter les autres composants en Java. SWT est écrit en Java et utilise la technologie JNI pour appeler les composants natifs. SWT utilise autant que possible les composants natifs du système lorsqu'ils existent, sinon ils sont réécrits en pur Java. Les données de chaque composant sont aussi stockées autant que possible dans le composant natif, limitant ainsi les données stockées dans les objets Java correspondant.

Ce chapitre contient plusieurs sections :

 

39.1. La présentation de SWT

Une partie de SWT est livrée sous la forme d'une bibliothèque dépendante du système d'exploitation et d'un fichier .jar lui aussi dépendant du système. Toutes les fonctionnalités de SWT ne sont implémentées que sur les systèmes où elles sont supportées (exemple, l'utilisation des ActiveX n'est possible que sur le portage de SWT sur les systèmes Windows).

Les trois avantages de SWT sont donc la rapidité d'exécution, des ressources machines moins importantes lors de l'exécution et un rendu parfait des composants graphiques selon le système utilisé puisqu'il utilise des composants natifs. Cette dernière remarque est particulièrement vraie pour des environnements graphiques dont l'apparence est modifiable.

Malgré cette dépendance vis à vis du système graphique de l'environnement d'exécution, l'API de SWT reste la même quelque soit la plate-forme utilisée.

En plus de dépendre du système utilisé lors de l'exécution, SWT possède un autre petit inconvénient. N'utilisant pas de purs objets java, il n'est pas possible de compter sur le ramasse miette pour libérer la mémoire des composants créés manuellement. Pour libérer cette mémoire, il est nécessaire d'utiliser la méthode dispose() pour les composants instanciés lorsque ceux-ci ne sont plus utiles.

Pour faciliter ces traitements, l'appel de la méthode dispose() d'un composant entraîne automatiquement l'appel de la méthode dispose() des composants qui lui sont rattachés. Il faut toutefois rester vigilant lors de l'utilisation de certains objets qui ne sont pas des contrôles tels que les objets de type Font ou Color, qu'il convient de libérer explicitement sous peine de fuites de mémoire.

Les règles à observer pour la libération des ressources sont :

Attention, l'utilisation d'un objet dont la méthode dispose() a été appelée induira un résultat imprévisible.

Ainsi SWT pose à nouveau la problématique concernant la dualité entre la portabilité (Write Once Run Anywhere) et les performances.

SWT se fonde sur trois concepts classiques dans le développement d'une interface graphique :

La structure d'une application SWT est la suivante :

La version de SWT utilisée dans ce chapitre est la 2.1.

SWT est regroupé dans plusieurs packages :

Package

Rôle

org.eclipse.swt

Package de base qui contient la définition de constantes et d'exceptions

org.eclipse.swt.accessibility

 

org.eclipse.swt.custom

Contient des composants particuliers

org.eclipse.swt.dnd

Contient les éléments pour le support du « cliqué / glissé »

org.eclipse.swt.events

Contient les éléments pour la gestion des événements

org.eclipse.swt.graphics

Contient les éléments pour l'utilisation des éléments graphiques (couleur, polices, curseur, contexte graphique, ...)

org.eclipse.swt.layout

Contient les éléments pour la gestion de la présentation

org.eclipse.swt.ole.win32

Contient les éléments pour le support d'OLE 32 sous Windows

org.eclipse.swt.printing

Contient les éléments pour le support des impressions

org.eclipse.swt.program

 

org.eclipse.swt.widgets

Contient les différents composants

 

39.2. Un exemple très simple

L'exemple de cette section affiche simplement bonjour dans une fenêtre.

Exemple :
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;

public class TestSWT1 {
	
  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    
    Label label = new Label(shell, SWT.CENTER);
    label.setText("Bonjour!");
    label.pack();
    
    shell.pack();
    shell.open();
        
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }
        
    display.dispose();
    label.dispose();
  }
}

Pour exécuter cet exemple sous Windows, il faut que le fichier swt.jar correspondant à la plate-forme Windows soit inclus dans le classpath et que l'application puisse accéder à la bibliothèque swt-win32-2135.dll.

 

39.3. La classe SWT

Cette classe définit un certain nombre de constantes concernant les styles. Les styles sont des comportements ou des caractéristiques définissant l'apparence du composant. Ces styles sont directement fournis dans le constructeur d'une classe encapsulant un composant.

 

39.4. L'objet Display

Toute application SWT doit obligatoirement instancier un objet de type Display. Cet objet assure le dialogue entre l'application et le système graphique du système d'exploitation utilisé.

Exemple :
Display display = new Display();

La méthode la plus importante de la classe Display est la méthode readAndDispatch() qui lit les événements dans la pile du système graphique natif pour les diffuser à l'application. Elle renvoie true s'il y a encore des traitements à effectuer sinon elle renvoie false.

La méthode sleep() permet de mettre en attente le thread d'écoute d'événements jusqu'à l'arrivée d'un nouvel événement.

Il est absolument nécessaire lors de la fin de l'application de libérer les ressources allouées par l'objet de type Display en appelant sa méthode dispose().

 

39.5. L'objet Shell

L'objet Shell représente une fenêtre gérée par le système graphique du système d'exploitation utilisé.

Un objet de type Shell peut être associé à un objet de type Display pour obtenir une fenêtre principale ou être associé à un autre objet de type Shell pour obtenir une fenêtre secondaire.

La classe Shell peut utiliser plusieurs styles : BORDER,H_SCROLL, V_SCROLL, CLOSE, MIN, MAX, RESIZE, TITLE, SHELL_TRIM, DIALOG_TRIM

BORDER : une fenêtre avec une bordure sans barre de titre

Shell shell = new Shell(display, SWT.BORDER);
shell.setSize(200, 100) ;
shell.setText("test");

TITLE : une fenêtre avec une barre de titre

Shell shell = new Shell(display, SWT.TITLE);
shell.setSize(200, 100) ; 
shell.setText("test");

CLOSE : une fenêtre avec un bouton de fermeture

Shell shell = new Shell(display, SWT.CLOSE);
shell.setSize(200, 100);
shell.setText("test");

MIN : une fenêtre avec un bouton pour iconiser

Shell shell = new Shell(display, SWT.CLOSE | SWT.MIN); 
shell.setSize(200, 100);
shell.setText("test");

MAX : une fenêtre avec un bouton pour agrandir au maximum

Shell shell = new Shell(display, SWT.CLOSE | SWT.MAX);
shell.setSize(200, 100);
shell.setText("test");

RESIZE : une fenêtre dont la taille peut être modifiée

Shell shell = new Shell(display, SWT.CLOSE | SWT.RESIZE);
shell.setSize(200, 100);
shell.setText("test");
SHELL_TRIM : groupe en une seule constante les styles CLOSE, TITLE, MIN, MAX et RESIZE

DIALOG_TRIM : groupe en une seule constante les styles CLOSE, TITLE et BORDER

APPLICATION_MODAL :
 
SYSTEM_MODAL :
 

La méthode setSize() permet de préciser la taille de la fenêtre.

La méthode setText() permet de préciser le titre de la fenêtre.

Exemple : centrer la fenêtre sur l'écran
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.*;

public class TestSWT1 {

  public static void centrerSurEcran(Display display, Shell shell) {
    Rectangle rect = display.getClientArea();
    Point size = shell.getSize();
    int x = (rect.width - size.x) / 2;
    int y = (rect.height - size.y) / 2;
    shell.setLocation(new Point(x, y));
  }
  
  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setSize(340, 100);
    centrerSurEcran(display, shell);

    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

 

39.6. Les composants

Les composants peuvent être regroupés en deux grandes familles :

Une application SWT est une hiérarchie de composants dont la racine est un objet de type Shell.

Certaines caractéristiques comme l'apparence ou le comportement d'un contrôle doivent être fournies au moment de leur création par le système graphique. Ainsi, chaque composant SWT possède une propriété nommée style fournie en paramètre du constructeur.

Plusieurs styles peuvent être combinés avec l'opérateur | . Cependant certains styles sont incompatibles entre-eux pour certains composants.

 

39.6.1. La classe Control

La classe Control définit trois styles : BORDER, LEFT_TO_RIGHT et RIGHT_TO_LEFT

Le seul constructeur de la classe Control nécessite aussi de préciser le composant père sous la forme d'un objet de type Composite. L'association avec le composant père est obligatoire pour tous les composants lors de leur création.

La classe Control possède plusieurs méthodes pour enregistrer des listeners pour certains événements. Ces événements sont : FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick, MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove, Move, Paint, Resize.

Elle possède aussi plusieurs méthodes dont les principales sont :

Nom Rôle
boolean forceFocus() Force le focus au composant pour lui permettre de recevoir les événements clavier
Display getDisplay() Renvoie l'objet Display associé au composant
Shell getShell() Renvoie l'objet Shell associé au composant
void pack() Recalcule la taille préférée du composant
void SetEnabled() Permet de rendre actif le composant
void SetFocus() Donne le focus au composant pour lui permettre de recevoir les événements clavier
void setSize() Permet de modifier la taille du composant
void setVisible() Permet de rendre visible ou non le composant

 

39.6.2. Les contrôles de base

 

39.6.2.1. La classe Button

La classe Button représente un bouton cliquable.

La classe Button définit plusieurs styles : BORDER, CHECK, PUSH, RADIO, TOGGLE, FLAT, LEFT, RIGHT, CENTER, ARROW (avec UP, DOWN)

NONE : un bouton par défaut

button = new Button(shell, SWT.NONE);
button.setText("Valider");
button.setSize(100,25);

BORDER : met une bordure autour du bouton

Button button = new Button(shell, SWT.BORDER);

CHECK : une case à cocher

Button button = new Button(shell, SWT.CHECK);

RADIO : un bouton radio

Button button = new Button(shell, SWT.RADIO);

PUSH : un bouton standard (valeur par défaut)

Button button = new Button(shell, SWT.PUSH);

TOGGLE : un bouton pouvant conservé un état enfoncé

Button button = new Button(shell, SWT.TOGGLE);

ARROW : bouton en forme de flèche (par défaut vers le haut)

Button button = new Button(shell, SWT.ARROW);
Button button = new Button(shell, SWT.ARROW | SWT.DOWN);
  

RIGHT : aligne le contenu du bouton sur la droite

Button button = new Button(shell, SWT.RIGHT);

LEFT : aligne le contenu du bouton sur la gauche

Button button = new Button(shell, SWT.LEFT);

CENTER : centre le contenu du bouton

Button button = new Button(shell, SWT.CENTER);

FLAT : le bouton apparaît en 2D

Button button = new Button(shell, SWT.FLAT); 
Button button = new Button(shell, SWT.FLAT | SWT.RADIO);
  

 

39.6.2.2. La classe Label

Ce contrôle permet d'afficher un libellé ou une image

La classe Label possède plusieurs styles : BORDER, CENTER, LEFT, RIGHT, WRAP, SEPARATOR (avec HORIZONTAL, SHADOW_IN, SHADOW_OUT, SHADOW_NONE, VERTICAL)

NONE : un libellé par défaut

Label label = new Label(shell, SWT.NONE);
label.setText("Bonjour!");
label.setSize(100,25);

BORDER : ajouter une bordure autour du libellé

Label label = new Label(shell, SWT.BORDER);

CENTER : permet de centrer le libellé

Label label = new Label(shell, SWT.CENTER);

SEPARATOR et VERTICAL : une barre verticale

Label label = new Label(shell, SWT.SEPARATOR | SWT. VERTICAL);

SEPARATOR et HORIZONTAL : une barre horizontale

Label label = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);

SHADOW_IN :

Label label = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL | 
SWT.SHADOW_IN);

SHADOW_OUT :

Label label = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL | 
SWT.SHADOW_OUT);

Cette classe possède plusieurs méthodes dont les principales sont :

Nom Rôle
void setAlignment(int) Permet de préciser l'alignement des données du contrôle
void setImage(Image) Permet de préciser une image affichée par le contrôle
void setText(string) Permet de préciser le texte du contrôle

 

39.6.2.3. La classe Text

Ce contrôle est une zone de saisie de texte.

La classe Text possède plusieurs styles : BORDER, SINGLE,  READ_ONLY, LEFT, CENTER, RIGHT, WRAP, MULTI (avec H_SCROLL, V_SCROLL)

NONE : une zone de saisie sans bordure

Text text = new Text(shell, SWT.NONE); 
text.setText("mon texte");
text.setSize(100,25);

BORDER : une zone de saisie avec bordure

Text text = new Text(shell, SWT.BORDER);

MULTI, SWT.H_SCROLL, SWT.V_SCROLL : une zone de saisie avec bordure

Text text = new Text(shell, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
READ_ONLY : une zone de saisie en lecture seule

Cette classe possède plusieurs méthodes dont les principales sont :

Nom Rôle
void setEchoChar(char) Caractère affiché lors de la frappe d'une touche
void setTextLimit(int) Permet de préciser le nombre maximum de caractères saisissables
void setText(string) Permet de préciser le contenu de la zone de texte
void setEditable(boolean) Permet de rendre le contrôle éditable ou non

 

39.6.3. Les contrôles de type liste

SWT permet de créer des composants de type liste et liste déroulante.

 

39.6.3.1. La classe Combo

Ce contrôle est une liste déroulante dans laquelle l'utilisateur peut sélectionner une valeur dans une liste d'éléments prédéfinis ou saisir un élément.

La classe Combo définit trois styles : BORDER, DROP_DOWN, READ_ONLY, SIMPLE

BORDER : une liste déroulante

Combo combo = new Combo(shell, SWT.BORDER);
combo.add("element 1");
combo.add("element 2");
combo.add("element 3");
combo.add("element 4");
combo.setSize(100,41);

READ_ONLY : une liste déroulante ne permettant que la sélection (saisie d'un élément impossible)

Combo combo = new Combo(shell, SWT.BORDER | SWT.READ_ONLY);

SIMPLE : zone de saisie et une liste

Combo combo = new Combo(shell, SWT.BORDER | SWT.SIMPLE); 
combo.setSize(100,81);

 

39.6.3.2. La classe List

Ce contrôle est une liste qui permet de sélectionner un ou plusieurs éléments.

La classe List possède plusieurs styles : BORDER, H_SCROLL, V_SCROLL, SINGLE, MULTI

BORDER : une liste

List liste = new List(shell, SWT.BORDER);
liste.add("element 1");
liste.add("element 2");
liste.pack();

V_SCROLL : une liste avec une barre de défilement

List liste = new List(shell, SWT.V_SCROLL); 
liste.add("element 1"); 
liste.add("element 2"); 
liste.add("element 3"); 
liste.add("element 4"); 
liste.setSize(100,41);

MULTI : une liste avec sélection de plusieurs éléments

List liste = new List(shell, SWT.V_SCROLL | SWT.MULTI);

La méthode add() permet d'ajouter un élément à la liste sous la forme d'une chaînes de caractères.

La méthode setItems() permet de fournir les éléments de la liste sous la forme d'un tableau de chaînes de caractères.

Exemple :
List liste = new List(shell, SWT.V_SCROLL | SWT.MULTI);
liste.setItems(new String[] {"element 1", "element 2", "element 3", "element 4"});
liste.setSize(100,41);

 

39.6.4. Les contrôles pour les menus

SWT permet la création de menus principaux et de menus déroulants. La création de ces menus met en oeuvre deux classes : Menu, MenuItem

 

39.6.4.1. La classe Menu

Ce contrôle est un élément du menu qui va contenir des options

La classe Menu possède plusieurs styles : BAR, DROP_DOWN, NO_RADIO_GROUP, POP_UP

BAR : le menu principal d'une fenêtre

Menu menu = new Menu(shell, SWT.BAR);
MenuItem menuitem1 = new MenuItem(menu, SWT.CASCADE);
menuitem1.setText("Fichier");
shell.setMenuBar(menu);

POP_UP : un menu contextuel

Menu menu = new Menu(shell, SWT.POP_UP);
MenuItem menuitem1 = new MenuItem(menu, SWT.CASCADE);
menuitem1.setText("Fichier");
MenuItem menuitem2 = new MenuItem(menu, SWT.CASCADE);
menuitem2.setText("Aide");
shell.setMenu(menu);
DROP_DOWN : un sous menu
 
NO_RADIO_GROUP :
 

 

39.6.4.2. La classe MenuItem

Ce contrôle est une option d'un menu.

La classe MenuItem possède plusieurs styles : CHECK, CASCADE, PUSH, RADIO, SEPARATOR

CASCADE : une option de menu qui possède un sous menu

PUSH : une option de menu

Menu menu = new Menu(shell, SWT.BAR);
MenuItem optionFichier = new MenuItem(menu, SWT.CASCADE);
optionFichier.setText("Fichier");
Menu menuFichier = new Menu(shell, SWT.DROP_DOWN);
MenuItem optionOuvrir = new MenuItem(menuFichier, SWT.PUSH);
optionOuvrir.setText("Ouvrir");
MenuItem optionFermer = new MenuItem(menuFichier, SWT.PUSH);
optionFermer.setText("Fermer");
optionFichier.setMenu(menuFichier);
MenuItem optionAide = new MenuItem(menu, SWT.CASCADE);
optionAide.setText("Aide");
shell.setMenuBar(menu);

CHECK : une option de menu avec un état coché ou non

Menu menu = new Menu(shell, SWT.BAR);
MenuItem optionFichier = new MenuItem(menu, SWT.CASCADE);
optionFichier.setText("Fichier");
Menu menuFichier = new Menu(shell, SWT.DROP_DOWN);
MenuItem optionOuvrir = new MenuItem(menuFichier, SWT.CASCADE);
optionOuvrir.setText("Ouvrir");
MenuItem optionFermer = new MenuItem(menuFichier, SWT.CASCADE);
optionFermer.setText("Fermer");
MenuItem optionCheck = new MenuItem(menuFichier, SWT.CHECK);
optionCheck.setText("Check");
optionFichier.setMenu(menuFichier); 
MenuItem optionAide = new MenuItem(menu, SWT.CASCADE);
optionAide.setText("Aide");
shell.setMenuBar(menu);

Radio : une option de menu sélectionnable parmi un ensemble

Menu menu = new Menu(shell, SWT.BAR);
MenuItem optionFichier = new MenuItem(menu, SWT.CASCADE);
optionFichier.setText("Fichier");
Menu menuFichier = new Menu(shell, SWT.DROP_DOWN);
MenuItem optionOuvrir = new MenuItem(menuFichier, SWT.CASCADE);
optionOuvrir.setText("Ouvrir");
MenuItem optionFermer = new MenuItem(menuFichier, SWT.CASCADE);
optionFermer.setText("Fermer");
MenuItem optionCheck = new MenuItem(menuFichier, SWT.CHECK);
optionCheck.setText("Check");
optionFichier.setMenu(menuFichier); 
MenuItem optionAide = new MenuItem(menu, SWT.CASCADE);
optionAide.setText("Aide");
shell.setMenuBar(menu);

SEPARATOR : pour séparer les options d'un menu

Menu menu = new Menu(shell, SWT.BAR);
MenuItem optionFichier = new MenuItem(menu, SWT.CASCADE);
optionFichier.setText("Fichier");
Menu menuFichier = new Menu(shell, SWT.DROP_DOWN);
MenuItem optionOuvrir = new MenuItem(menuFichier, SWT.PUSH);
optionOuvrir.setText("Ouvrir");
MenuItem optionSeparator = new MenuItem(menuFichier, SWT.SEPARATOR);
MenuItem optionFermer = new MenuItem(menuFichier, SWT.PUSH);
optionFermer.setText("Fermer");
optionFichier.setMenu(menuFichier);
MenuItem optionAide = new MenuItem(menu, SWT.CASCADE);
optionAide.setText("Aide");
shell.setMenuBar(menu);

La méthode setText() permet de préciser le libellé de l'option de menu.

La méthode setAccelerator() permet de préciser un raccourci clavier.

Menu menuFichier = new Menu(shell, SWT.DROP_DOWN);
MenuItem optionOuvrir = new MenuItem(menuFichier, SWT.PUSH);
optionOuvrir.setText("&Ouvrir\tCtrl+O"); 
optionOuvrir.setAccelerator(SWT.CTRL+'O');

 

39.6.5. Les contrôles de sélection ou d'affichage d'une valeur

SWT propose un contrôle pour l'affichage d'une barre de progression et deux contrôles pour la sélection d'une valeur numérique dans une plage de valeur.

 

39.6.5.1. La classe ProgressBar

Ce contrôle est une barre de progression.

La classe ProgressBar possède plusieurs styles : BORDER, INDETERMINATE, SMOOTH, HORIZONTAL, VERTICAL

HORIZONTAL :

ProgressBar progressbar = new ProgressBar(shell,
  SWT.HORIZONTAL);
progressbar.setMinimum(1);
progressbar.setMaximum(100);
progressbar.setSelection(40);
progressbar.setSize(200,20);

SMOOTH :

ProgressBar progressbar = new ProgressBar(shell, 
  SWT.HORIZONTAL | SWT.SMOOTH);

INDETERMINATE : la barre de progression s'incrémente automatiquement et revient au début indéfiniment

ProgressBar progressbar = new ProgressBar(shell, 
  SWT.INDETERMINATE);

Les méthodes setMinimum() et setMaximum() permettent respectivement de préciser les valeurs minimale et maximale du contrôle.

La méthode setSelection() permet de positionner la valeurs courante de l'indicateur.

 

39.6.5.2. La classe Scale

Ce contrôle permet de faire une sélection dans une plage de valeurs numériques.

La classe Scale possède trois styles : BORDER, HORIZONTAL, VERTICAL

HORZONTAL :

Scale scale = new Scale(shell,SWT.HORIZONTAL); 
scale.setSize(100,40);

VERTICAL :

Scale scale = new Scale(shell,SWT.VERTICAL);
scale.setSize(40,100);

BORDER :

Scale scale = new Scale(shell,SWT.BORDER);
scale.setSize(100,40);

Les méthodes setMinimum() et setMaximum() permettent respectivement de préciser les valeurs minimale et maximale du contrôle.

La méthode setSelection() permet de positionner le curseur dans la plage de valeurs à la valeur fournie en paramètre.

La méthode setPageIncrement() permet de préciser la valeur fournie en paramètre d'incrémentation d'une page

Exemple :

Scale scale = new Scale(shell,SWT.HORIZONTAL);

scale.setSize(100,40);
scale.setMinimum(1);
scale.setMaximum(100); 
scale.setSelection(30);
scale.setPageIncrement(10);

 

39.6.5.3. La classe Slider

Ce contrôle permet de sélectionner une valeur dans une plage de valeurs numériques.

La classe Slider possède trois styles : BORDER, HORIZONTAL, VERTICAL

BORDER :

Slider slider = new Slider(shell, SWT.BORDER);
slider.setSize(200,20);

VERTICAL :

Slider slider = new Slider(shell, SWT.VERTICAL);
slider.setSize(20,200);

Les méthodes setMinimum() et setMaximum() permettent respectivement de préciser les valeurs minimale et maximale du contrôle.

La méthode setSelection() permet de positionner le curseur dans la plage de valeurs à la valeur fournie en paramètre.

La méthode setPageIncrement() permet de préciser la valeur d'incrémentation d'une page du contrôle.

La méthode setThumb() permet de préciser la taille du curseur.

Exemple :

Slider slider = new Slider(shell,SWT.HORIZONTAL);

slider.setMinimum(1);
slider.setMaximum(110);
slider.setSelection(30);
slider.setThumb(10);
slider.setSize(100,20);

 

39.6.6. Les contrôles de type « onglets »

SWT propose la création de composants de type onglets mettant en oeuvre deux classes : TabFolder et TabItem

 

39.6.6.1. La classe TabFolder

Ce contrôle est un ensemble d'onglets.

NONE :

TabFolder tabfolder = new TabFolder(shell, SWT.NONE);
tabfolder.setSize(200,200);
TabItem onglet1 = new TabItem(tabfolder, SWT.NONE);
onglet1.setText("Onglet 1"); 
TabItem onglet2 = new TabItem(tabfolder, SWT.NONE);
onglet2.setText("Onglet 2");

BORDER : un ensemble d'onglets avec une bordure

TabFolder tabfolder = new TabFolder(shell, SWT.BORDER);

 

39.6.6.2. La classe TabItem

Ce contrôle est un onglet d'un ensemble d'onglets

La méthode setControl() ne permet d'insérer qu'un seul contrôle dans un onglet mais ce contrôle peut être de type Composite et regrouper différents éléments.

Exemple :
TabFolder tabfolder = new TabFolder(shell, SWT.NONE);
tabfolder.setSize(200,100);
TabItem onglet1 = new TabItem(tabfolder, SWT.NONE);
onglet1.setText("Onglet 1");
TabItem onglet2 = new TabItem(tabfolder, SWT.NONE);
onglet2.setText("Onglet 2");

Composite pageOnglet1 = new Composite(tabfolder, SWT.NONE);
Text text1 = new Text(pageOnglet1, SWT.BORDER);
text1.setText("mon texte");
text1.setBounds(10,10,100,25);
Button button1 = new Button(pageOnglet1, SWT.BORDER);
button1.setText("Valider");
button1.setBounds(10,40,100,25);
onglet1.setControl(pageOnglet1);

 

39.6.7. Les contrôles de type « tableau »

SWT permet la création d'un contrôle de type tableau pour afficher et sélectionner des données en mettant en oeuvre trois classes : Table, TableColumn et TableItem.

 

39.6.7.1. La classe Table

Ce contrôle permet d'afficher et de sélectionner des éléments sous la forme d'un tableau.

La classe Table possède plusieurs styles : BORDER, H_SCROLL, V_SCROLL, SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION

BORDER :

Table table = new Table(shell, SWT.BORDER);
table.setSize(204,106);
TableColumn colonne1 = new TableColumn(table, SWT.LEFT);
colonne1.setText("Colonne 1");
colonne1.setWidth(100);
TableColumn colonne2 = new TableColumn(table, SWT.LEFT);
colonne2.setText("Colonne 2");
colonne2.setWidth(100);
table.setHeaderVisible(true);
table.setLinesVisible(true); 
TableItem ligne1 = new TableItem(table,SWT.NONE);
ligne1.setText(new String[] {"valeur 1 1","valeur 1 2"});
TableItem ligne2 = new TableItem(table,SWT.NONE);
ligne2.setText(new String[] {"valeur 1 1","valeur 1 2"});
TableItem ligne3 = new TableItem(table,SWT.NONE);
ligne3.setText(new String[] {"valeur 1 1","valeur 1 2"});
TableItem ligne4 = new TableItem(table,SWT.NONE);
ligne4.setText(new String[] {"valeur 1 1","valeur 1 2"});

MULTI : permet la sélection de plusieurs éléments dans la table

Table table = new Table(shell, SWT.MULTI);

CHECK : une table avec une case à cocher pour chaque ligne

Table table = new Table(shell, SWT.CHECK);

FULL_SELECTION : la ou les lignes sélectionnées sont entièrement mises en valeur

Table table = new Table(shell, SWT.MULTI | SWT.FULL_SELECTION);

HIDE_SELECTION : seule la première colonne sélectionnée est mise en valeur

 

La méthode setHeaderVisible() permet de préciser si l'en-tête de la table doit être affiché ou non : par défaut il est non affiché (false).

La méthode setLinesVisible() permet de préciser si les lignes de la table doivent être affichées ou non : par défaut elles ne sont pas affichées (false).

 

39.6.7.2. La classe TableColumn

Ce contrôle est une colonne d'un contrôle Table

La classe TableColumn possède trois styles : LEFT, RIGHT, CENTER

LEFT : alignement de la colonne sur la gauche (valeur par défaut)
 

RIGHT : alignement de la colonne sur la droite

TableColumn colonne2 = new TableColumn(table, SWT.RIGHT);

CENTER : alignement centré de la colonne

TableColumn colonne2 = new TableColumn(table, SWT.CENTER);

Bizarrement, seul le style LEFT semble pouvoir s'appliquer à la première colonne de la table.

La méthode setWidth() permet de préciser la largeur de la colonne

La méthode setText() permet de préciser le libellé d'en-tête de la colonne

La méthode setResizable() permet de préciser si la colonne peut être redimensionnée ou non.

 

39.6.7.3. La classe TableItem

Ce contrôle est une ligne d'un contrôle Table

La classe TableItem ne possède aucun style.

Il existe plusieurs surcharges de la méthode setText() pour fournir à chaque ligne les données de ses colonnes.

Une surcharge de cette méthode permet de fournir les données sous la forme d'un tableau de chaînes de caractères.

Exemple :
ligne1.setText(new String[] {"valeur 1 1","valeur 1 2"});

Une autre surcharge de cette méthode permet de préciser le numéro de la colonne et le texte. La première colonne possède le numéro 0.

Exemple : modifier la valeur de la première cellule de la ligne
ligne4.setText(0 ,"valeur 2 2");

La méthode setCheck() permet de cocher ou non la case associée à la ligne si la table possède le style CHECK.

 

39.6.8. Les contrôles de type « arbre »

SWT permet la création d'un composant de type arbre en mettant en oeuvre les classes Tree et TreeItem.

 

39.6.8.1. La classe Tree

Ce contrôle affiche et permet de sélectionner des données sous la forme d'une arborescence

La classe Tree possède plusieurs styles : BORDER, H_SCROLL, V_SCROLL, SINGLE, MULTI, CHECK

SINGLE : un arbre avec sélection unique

Tree tree = new Tree(shell, SWT.SINGLE);
TreeItem tree_1 = new TreeItem(tree, SWT.NONE);
tree_1.setText("element 1");
TreeItem tree_2 = new TreeItem(tree, SWT.NONE);
tree_2.setText("element 2");
TreeItem tree_2_1 = new TreeItem(tree_2, SWT.NONE);
tree_2_1.setText("element 2 1");
TreeItem tree_2_2 = new TreeItem(tree_2, SWT.NONE);
tree_2_2.setText("element 2 2");
TreeItem tree_3 = new TreeItem(tree, SWT.NONE);
tree_3.setText("element 3");
tree.setSize(100, 100);

BORDER : arbre avec une bordure

Tree tree = new Tree(shell, SWT.SINGLE | SWT.BORDER);

H_SCROLL et V_SCROLL : arbre avec si nécessaire une barre de défilement respectivement horizontal et vertical

Tree tree = new Tree(shell, SWT.SINGLE | SWT.BORDER | 
  SWT.H_SCROLL | SWT.V_SCROLL);

MULTI : un arbre avec sélection multiple possible

Tree tree = new Tree(shell, SWT.MULTI | SWT.BORDER);

CHECK : un arbre avec une case à cocher devant chaque élément

Tree tree = new Tree(shell, SWT.CHECK | SWT.BORDER);

 

39.6.8.2. La classe TreeItem

Ce contrôle est un élément d'une arborescence

Cette classe ne possède pas de style particulier.

Pour ajouter un élément racine à l'arbre, il suffit de passer l'arbre en tant qu'élément conteneur dans le constructeur.

Pour ajouter un élément fils à un élément, il suffit de passer l'élément père en tant qu'élément conteneur dans le constructeur.

Il existe un constructeur qui attend un troisième paramètre permettant de préciser la position de l'élément.

Exemple :
Tree tree = new Tree(shell, SWT.SINGLE);
TreeItem tree_1 = new TreeItem(tree, SWT.NONE);
tree_1.setText("element 1");
TreeItem tree_2 = new TreeItem(tree, SWT.NONE);
tree_2.setText("element 2");
TreeItem tree_2_1 = new TreeItem(tree_2, SWT.NONE);
tree_2_1.setText("element 2 1");
TreeItem tree_2_2 = new TreeItem(tree_2, SWT.NONE);
tree_2_2.setText("element 2 2");
TreeItem tree_3 = new TreeItem(tree, SWT.NONE);
tree_3.setText("element 3");
tree.setSize(100, 100);

 

39.6.9. La classe ScrollBar

Ce contrôle est une barre de défilement

La classe ScrollBar possède deux styles : HORIZONTAL, VERTICAL

 

39.6.10. Les contrôles pour le graphisme

SWT permet de dessiner des formes graphiques en mettant en oeuvre la classe GC et la classe Canvas.

 

39.6.10.1. La classe Canvas

Ce contrôle est utilisé pour dessiner des formes graphiques

La classe Canvas définit plusieurs styles : BORDER, H_SCROLL, V_SCROLL, NO_BACKGROUND, NO_FOCUS, NO_MERGE_PAINTS, NO_REDRAW_RESIZE, NO_RADIO_GROUP

BORDER : une zone de dessin avec bordure

Canvas canvas = new Canvas(shell, SWT.BORDER); 
canvas.setSize(200,200);

 

39.6.10.2. La classe GC

Cette classe encapsule un contexte graphique dans lequel il va être possible de dessiner des formes.

Pour réaliser ces opérations, la classe GC propose de nombreuses méthodes.

Attention : il est important d'appeler la méthode open() de la fenêtre avant de réaliser des opérations de dessin sur le contexte.

Ne pas oublier le libérer les ressources allouées à la classe GC en utilisant la méthode dispose() si l'objet de GC est explicitement instancié dans le code.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;

public class TestSWT21 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setSize(420,420);

    Canvas canvas = new Canvas(shell, SWT.NONE);
    canvas.setSize(200,200);
    canvas.setLocation(10,10);
    shell.pack();
    shell.open();

    GC gc = new GC(canvas);
    gc.drawText("Bonjour",20,20);
    gc.drawLine(10,10,10,100);
    gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
    gc.drawOval(60,60,60,60);
    gc.dispose();

    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }
    display.dispose();
  }
}

Dans cette exemple, le dessin est réalisé une seule fois au démarrage, il n'est donc pas redessiné si nécessaire (fenêtre partiellement ou complètement masquée, redimensionnement, ...). Pour résoudre ce problème, il faut mettre les opérations de dessin en réponse à un événement de type PaintListener.

 

39.6.10.3. La classe Color

Cette classe encapsule une couleur définie dans le système graphique.

Elle possède deux constructeurs qui attendent en paramètre l'objet de type Display et soit un objet de type RGB, soit trois entiers représentant les valeurs des couleurs rouge, vert et bleu.

La classe RGB encapsule simplement les trois entiers représentant les valeurs des couleurs rouge, vert et bleu.

Exemple :
Color couleur = new Color(display,155,0,0);
Color couleur = new Color(display, new RGB(155,0,0));

Remarque : il ne faut pas oublier d'utiliser la méthode dispose() pour libérer les ressources du système allouées à cet objet une fois que celui-ci n'est plus utilisé.

Exemple :
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;

public class TestSWT22 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);

    shell.setSize(200, 200);
    Color couleur = new Color(display,155,0,0);
    shell.setBackground(couleur);
    shell.open();
 
   while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }

    couleur.dispose();
    display.dispose();
  }
}

 

39.6.10.4. La classe Font

Cette classe encapsule une police de caractères définie dans le système graphique.

La classe Font peut utiliser plusieurs styles : NORMAL, BOLD et ITALIC

Il existe plusieurs constructeurs dont le plus simple à utiliser nécessite en paramètre l'objet display, le nom de la police (celle-ci doit être présente sur le système), la taille et le style.

Remarque : il ne faut pas oublier d'utiliser la méthode dispose() pour libérer les ressources du système allouées à cet objet une fois que celui-ci n'est plus utilisé.

Exemple :
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.*;

public class TestSWT23 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);

    Font font = new Font(display, "Arial", 16, SWT.ITALIC);
    Label label = new Label(shell, SWT.NONE);
    label.setFont(font);
    label.setText("Bonjour");
    label.setLocation(10, 10);
    label.pack();
    shell.setSize(100, 100);
    shell.open();

    while (!shell.isDisposed()) { 
      if (!display.readAndDispatch())
        display.sleep();
    }

    font.dispose();
    display.dispose();
  }
}

 

39.6.10.5. La classe Image

Cette classe encapsule une image au format BMP, ICO, GIF, JPEG ou PNG.

La classe Image possède plusieurs constructeurs dont le plus simple à utiliser est celui nécessitant en paramètres l'objet Display et une chaîne de caractères contenant le chemin vers le fichier de l'image

Remarque : il ne faut pas oublier d'utiliser la méthode dispose() pour libérer les ressources du système allouées à cet objet une fois que celui-ci n'est plus utilisé.

Exemple :
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.*;

public class TestSWT24 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);

    Image image = new Image(display, "btn1.bmp");
    Button bouton = new Button(shell, SWT.FLAT);
    bouton.setImage(image);
    bouton.setBounds(10, 10, 50, 50);
    shell.setSize(100, 100);
    shell.open();

    while (!shell.isDisposed()) { 
      if (!display.readAndDispatch())
        display.sleep();
    }

    image.dispose();
    display.dispose();
  }
}

Si l'application doit être packagée dans un fichier jar, incluant les images utiles, il faut utiliser la méthode getResourceAsStream() du classloader pour charger l'image.

Exemple :
import org.eclipse.swt.widgets.*; 
import org.eclipse.swt.graphics.*; 
import org.eclipse.swt.*; 
import java.io.*; 

public class TestSWT25 { 

  public static void main(String[] args) { 
    final Display display = new Display(); 
    final Shell shell = new Shell(display); 

    InputStream is = TestSWT25.class.getResourceAsStream("btn1.bmp"); 
    Image image = new Image(display, is); 
    Button bouton = new Button(shell, SWT.FLAT); 
    bouton.setImage(image); 
    bouton.setBounds(10, 10, 50, 50); 
    shell.setSize(100, 100); 
    shell.open(); 

    while (!shell.isDisposed()) { 
      if (!display.readAndDispatch()) 
        display.sleep(); 
    } 

    image.dispose(); 
    display.dispose(); 
  } 
}

 

39.7. Les conteneurs

Ce type de composant permet de contenir d'autres contrôles.

 

39.7.1. Les conteneurs de base

SWT propose deux contrôles de ce type : Composite et Group.

 

39.7.1.1. La classe Composite

Ce contrôle est un conteneur pour d'autres contrôles.

Ce contrôle possède les styles particuliers suivants : BORDER, H_SCROLL et V_SCROLL

BORDER : permet la présence d'une bordure autour du composant

Composite composite = new Composite(shell, SWT.BORDER);
 

H_SCROLL : permet la présence d'une barre de défilement horizontal

Composite composite = new Composite(shell, SWT.H_SCROLL);
 

V_SCROLL : permet la présence d'une barre de défilement vertical

Composite composite = new Composite(shell, SWT.V_SCROLL);
 

Les contrôles sont ajoutés au contrôle Composite de la même façon que dans un objet de type Shell en précisant simplement que le conteneur est l'objet de type Composite.

La position indiquée pour les contrôles inclus dans le Composite est relative à l'objet Composite.

Exemple complet :
import org.eclipse.swt.*; 
import org.eclipse.swt.graphics.*; 
import org.eclipse.swt.widgets.*; 

public class TestSWT2 { 

  public static void main(String[] args) { 
    Display display = new Display(); 
    Shell shell = new Shell(display); 
    shell.setText("Test"); 

    Composite composite = new Composite(shell, SWT.BORDER); 
    Color couleur = new Color(display,131,133,131); 
    composite.setBackground(couleur); 
    Label label = new Label(composite, SWT.NONE); 
    label.setBackground(couleur); 
    label.setText("Saisir la valeur"); 
    label.setBounds(10, 10, 100, 25); 
    Text text = new Text(composite, SWT.BORDER); 
    text.setText("mon texte"); 
    text.setBounds(10, 30, 100, 25); 
    Button button = new Button(composite, SWT.BORDER); 
    button.setText("Valider"); 
    button.setBounds(10, 60, 100, 25); 
    composite.setSize(140,140); 

    shell.pack(); 
    shell.open(); 
    while (!shell.isDisposed()) 
      if (!display.readAndDispatch()) 
        display.sleep(); 

    couleur.dispose(); 
    display.dispose(); 
  } 
}

 

39.7.1.2. La classe Group

Ce contrôle permet de regrouper d'autres contrôles en les entourant d'une bordure et éventuellement d'un libellé.

La classe Group possède plusieurs styles : BORDER, SHADOW_ETCHED_IN, SHADOW_ETCHED_OUT, SHADOW_IN, SHADOW_OUT, SHADOW_NONE

NONE : un cadre simple

Group group = new Group(shell, SWT.NONE);
group.setLayout (new FillLayout ());
button button1 = new Button(group, SWT.NONE);
button1.setText("Bouton 1");
Button button2 = new Button(group, SWT.NONE);
button2.setText("Bouton 2");

BORDER : un cadre simple avec une bordure

Group group = new Group(shell, SWT.BORDER);

La méthode setText() permet de préciser un titre affiché en haut à gauche du cadre.

Group group = new Group(shell, SWT.NONE);
group.setLayout (new FillLayout ());
group.setText ("Actions");
Button button1 = new Button(group, SWT.NONE);
button1.setText("Bouton 1");
Button button2 = new Button(group, SWT.NONE);
button2.setText("Bouton 2");

 

39.7.2. Les contrôles de type « barre d'outils »

SWT permet de créer des barres d'outils fixes ou flottantes.

 

39.7.2.1. La classe ToolBar

Ce contrôle est une barre d'outils

La classe ToolBar possède plusieurs styles : BORDER, FLAT, WRAP, RIGHT, SHADOW_OUT HORIZONTAL, VERTICAL

HORIZONTAL : une barre d'outils horizontale (style par défaut)

shell.setSize(150, 100);
ToolBar toolbar = new ToolBar(shell, SWT.HORIZONTAL);
toolbar.setSize(shell.getSize().x, 35);
toolbar.setLocation(0, 0);

Image imageBtn1 = new Image(display, "btn1.bmp");
ToolItem btn1 = new ToolItem(toolbar, SWT.PUSH);
btn1.setImage(imageBtn1);

Image imageBtn2 = new Image(display, "btn2.bmp");
ToolItem btn2 = new ToolItem(toolbar, SWT.PUSH);
btn2.setImage(imageBtn2);

shell.open();
while (!shell.isDisposed())
  if (!display.readAndDispatch())
    display.sleep();

imageBtn1.dispose();
imageBtn2.dispose();
display.dispose();

FLAT : une barre d'outils sans effet 3D

ToolBar toolbar = new ToolBar(shell, SWT.FLAT);

VERTICAL : une barre d'outils verticale

ToolBar toolbar = new ToolBar(shell, SWT.VERTICAL);
toolbar.setSize(35, shell.getSize().y);

BORDER : une barre d'outils avec une bordure

ToolBar toolbar = new ToolBar(shell, SWT.BORDER);

 

39.7.2.2. La classe ToolItem

Ce contrôle est un élément d'une barre d'outils

La classe ToolItem possède plusieurs styles : PUSH, CHECK, RADIO, SEPARATOR, DROP_DOWN

PUSH : un bouton simple

shell.setSize(240, 100);
ToolBar toolbar = new ToolBar(shell, SWT.FLAT);
toolbar.setSize(shell.getSize().x, 40);
toolbar.setLocation(0, 0);

Image imageBtn1 = new Image(display, "btn1.bmp");
ToolItem btn1 = new ToolItem(toolbar, SWT.PUSH);
btn1.setImage(imageBtn1);

Image imageBtn2 = new Image(display, "btn2.bmp");
ToolItem btn2 = new ToolItem(toolbar, SWT.PUSH);
btn2.setImage(imageBtn2);
btn2.setText("Stop");

ToolItem btn3= new ToolItem(toolbar, SWT.PUSH);
btn3.setText("Action");
shell.open();

while (!shell.isDisposed())
  if (!display.readAndDispatch())
    display.sleep();

imageBtn1.dispose();
imageBtn2.dispose();
display.dispose();

CHECK : un bouton qui peut conserver son état enfoncé

ToolItem btn4= new ToolItem(toolbar, SWT.CHECK); 
btn4.setText("Check");

SEPARATOR : un séparateur

ToolItem btn5= new ToolItem(toolbar, SWT.SEPARATOR);

DROP_DOWN : un bouton avec une petite flèche vers le bas

RADIO : un bouton dont un seul d'un même ensemble peut être sélectionné (un ensemble est défini par des boutons de type radio qui sont adjacents)

ToolItem btn7= new ToolItem(toolbar, SWT.RADIO); 
btn7.setText("radio1");
ToolItem btn8= new ToolItem(toolbar, SWT.RADIO);
btn8.setText("radio2");

Exemple :
shell.setSize(340, 100);
final ToolBar toolbar = new ToolBar(shell, SWT.HORIZONTAL);
toolbar.setSize(shell.getSize().x, 45);
toolbar.setLocation(0, 0);

Image imageBtn1 = new Image(display, "btn1.bmp");
ToolItem btn1 = new ToolItem(toolbar, SWT.PUSH);
btn1.setImage(imageBtn1);

Image imageBtn2 = new Image(display, "btn2.bmp");
ToolItem btn2 = new ToolItem(toolbar, SWT.PUSH);
btn2.setImage(imageBtn2);
btn2.setText("Stop");

ToolItem btn3 = new ToolItem(toolbar, SWT.PUSH);
btn3.setText("Action");

ToolItem btn4 = new ToolItem(toolbar, SWT.CHECK);
btn4.setText("Check");

ToolItem btn5 = new ToolItem(toolbar, SWT.SEPARATOR);

final ToolItem btn6 = new ToolItem(toolbar, SWT.DROP_DOWN);
btn6.setText("Actions");

final Menu menu = new Menu(shell, SWT.POP_UP);
MenuItem menu1 = new MenuItem(menu, SWT.PUSH);
menu1.setText("option 1");
MenuItem menu2 = new MenuItem(menu, SWT.PUSH);
menu2.setText("option 2");
MenuItem menu3 = new MenuItem(menu, SWT.PUSH);
menu3.setText("option 3");

btn6.addListener(SWT.Selection, new Listener() {
  public void handleEvent(Event event) {
    if (event.detail == SWT.ARROW) {
      Rectangle rect = btn6.getBounds();
      Point pt = new Point(rect.x, rect.y + rect.height);
      pt = toolbar.toDisplay(pt);
      menu.setLocation(pt.x, pt.y);
      menu.setVisible(true);
    }
  }
});

ToolItem btn7 = new ToolItem(toolbar, SWT.RADIO);
btn7.setText("radio1");

ToolItem btn8 = new ToolItem(toolbar, SWT.RADIO);
btn8.setText("radio2");

shell.open();
while (!shell.isDisposed())
  if (!display.readAndDispatch())
    display.sleep();

imageBtn1.dispose();
imageBtn2.dispose();
display.dispose();

 

39.7.2.3. Les classes CoolBar et Cooltem

La classe CoolBar est une barre d'outils repositionnable. Ce contrôle doit être utilisé avec un ou plusieurs contrôles CoolItem qui représentent les éléments constitutifs de la CoolBar.

Le plus simple est d'associer une barre d'outils de type ToolBar à un de ses éléments en utilisant la méthode setControl() de la classe CoolItem.

Exemple : utilisation de la barre d'outils définie dans la section précédente
shell.setLayout(new GridLayout());

shell.setSize(340, 100);
CoolBar coolbar = new CoolBar(shell, SWT.BORDER);
final ToolBar toolbar = new ToolBar(coolbar, SWT.FLAT);

Image imageBtn1 = new Image(display, "btn1.bmp");
ToolItem btn1 = new ToolItem(toolbar, SWT.PUSH);
btn1.setImage(imageBtn1); 

Image imageBtn2 = new Image(display, "btn2.bmp");
ToolItem btn2 = new ToolItem(toolbar, SWT.PUSH);
btn2.setImage(imageBtn2);
btn2.setText("Stop");

ToolItem btn3 = new ToolItem(toolbar,SWT.PUSH);
btn3.setText("Action");

ToolItem btn4 = new ToolItem(toolbar,SWT.CHECK);
btn4.setText("Check");

ToolItem btn5 = new ToolItem(toolbar, SWT.SEPARATOR);

final ToolItem btn6 = new ToolItem(toolbar, SWT.DROP_DOWN);
btn6.setText("Actions");

final Menu menu = new Menu(shell, SWT.POP_UP);
MenuItem menu1 = new MenuItem(menu, SWT.PUSH);
menu1.setText("option 1");
MenuItem menu2 = new MenuItem(menu, SWT.PUSH);
menu2.setText("option2");
MenuItem menu3 = new MenuItem(menu, SWT.PUSH);
menu3.setText("option3");

btn6.addListener(SWT.Selection, new Listener() {
  public void handleEvent(Event event) {
    if (event.detail == SWT.ARROW) {
      Rectangle rect = btn6.getBounds();
      Point pt = new Point(rect.x, rect.y + rect.height);
      pt = toolbar.toDisplay(pt);
      menu.setLocation(pt.x, pt.y);
      menu.setVisible(true);
    }
  }
});

ToolItem btn7 = new ToolItem(toolbar, SWT.RADIO);
btn7.setText("radio1");

ToolItem btn8 = new ToolItem(toolbar, SWT.RADIO);
btn8.setText("radio2");

CoolItem coolItem = new CoolItem(coolbar, SWT.NONE);
coolItem.setControl(toolbar);
Point size = toolbar.computeSize(SWT.DEFAULT, SWT.DEFAULT);
coolItem.setPreferredSize(coolItem.computeSize(size.x, size.y));

shell.open();

while (!shell.isDisposed())
  if (!display.readAndDispatch())
    display.sleep();

imageBtn1.dispose();
imageBtn2.dispose();

La classe CoolItem possède une méthode setLocked() qui attend un booléen en paramètre précisant si le contrôle peut être déplacé ou non. Cette méthode doit être appelée lors d'un clic sur un bouton de la barre pour empêcher le déplacement de celle-ci.

 

39.8. La gestion des erreurs

Lors de l'utilisation de l'API SWT, des exceptions de trois types peuvent être levées :

 

39.9. Le positionnement des contrôles

 

39.9.1. Le positionnement absolu

Dans ce mode, il faut préciser pour chaque composant, sa position et sa taille. L'inconvénient de ce mode de positionnement est qu'il réagit très mal à un changement de la taille du conteneur des composants.

 

39.9.2. Le positionnement relatif avec les LayoutManager

SWT propose un certain nombre de gestionnaires de positionnement de contrôles (layout manager). Ceux-ci sont regroupés dans le package org.eclipse.swt.layout.

Le grand avantage de ce mode de positionnement est de laisser au LayoutManager utilisé le soin de positionner et de dimensionner chaque composant en fonction de ses règles et des paramètres qui lui sont fournis.

SWT définit quatre gestionnaires de positionnement :

Pour personnaliser finement l'arrangement des composants, des informations complémentaires peuvent être associées à chacun d'eux en utilisant un objet dédié du type RowData, GridData ou FormData respectivement pour les gestionnaires de positionnement RowLayout, GridLayout et FormLayout.

 

39.9.2.1. FillLayout

Le FillLayout est le gestionnaire de positionnement le plus simple : il organise les composants dans une colonne ou une rangée. L'espace entre les composants est calculé automatiquement par la classe FillLayout.

La classe FillLayout peut utiliser deux styles : SWT.HORIZONTAL (par défaut) et SWT.VERTICAL pour préciser le mode d'alignement

Exemple :
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.*;

public class TestSWT27 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);

    shell.setLayout(new RowLayout());
    Button bouton1 = new Button(shell, SWT.FLAT);
    bouton1.setText("bouton 1");
    Button bouton2 = new Button(shell, SWT.FLAT);
    bouton2.setText("bouton 2");
    Button bouton3 = new Button(shell, SWT.FLAT);
    bouton3.setText("bouton 3");

    shell.pack();
    shell.open();

    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }

    display.dispose();
  }
}

Voici différents aperçus en cas de modification de la taille de la fenêtre.

  

Il n'est pas possible de mettre un espace entre le bord du conteneur et les composants avec ce gestionnaire. Il n'est pas non plus possible pour ce gestionnaire de mettre des composants sur plusieurs colonnes ou rangées.

 

39.9.2.2. RowLayout

Ce gestionnaire propose d'arranger les composants en rangées ou en colonnes. Il possède des paramètres permettant de préciser une marge, un espace, une rupture et une compression.

Propriété Valeur par défaut Rôle
wrap true

demande de faire une rupture dans la rangée s'il n'y a plus de place

false : true :

pack true demande à chaque composant de prendre sa taille préférée
justify false

justification des composants

type SWT.HORIZONTAL

type de mise en forme SWT.HORIZONTAL ou SWT.VERTICAL

SWT.VERTICAL :

marginLeft 3 taille en pixels de la marge gauche
marginTop 3 taille en pixels de la marge haute
marginRight 3 taille en pixels de la marge droite

marginBottom

3

taille en pixels de la marge basse

spacing 3 taille en pixels entre deux cellules

Exemple :
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.*;

public class TestSWT27 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);

    RowLayout rowlayout = new RowLayout();
    shell.setLayout(rowlayout);
    Button bouton1 = new Button(shell, SWT.FLAT);
    bouton1.setText("bouton 1");

    Button bouton2 = new Button(shell, SWT.FLAT);
    bouton2.setText("bouton 2");

    Button bouton3 = new Button(shell, SWT.FLAT);
    bouton3.setText("bouton 3");

    shell.pack();
    shell.open();

    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }
    display.dispose();
  }
}

Voici différents aperçus en cas de modification de la taille de la fenêtre.

 

39.9.2.3. GridLayout

Ce gestionnaire permet d'arranger les composants dans une grille et possède plusieurs propriétés :

Propriété Valeur par défaut Rôle
horizontalSpacing 5 préciser l'espace horizontal entre chaque cellule
makeColumnsEqualWidth false donner à toutes les colonnes de la grille la même largeur
marginHeight 5 préciser la hauteur de la marge
marginWidth 5 préciser la largeur de la marge
numColumns 1 préciser le nombre de colonnes de la grille
verticalSpacing 5 préciser l'espace vertical entre cellules

Exemple :
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.*;

public class TestSWT28 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);

    GridLayout gridLayout = new GridLayout();
    gridLayout.numColumns = 2;
    shell.setLayout(gridLayout);

    Label label1 = new Label(shell, SWT.NONE);
    label1.setText("Donnee 1 :");
    Text text1 = new Text(shell, SWT.BORDER);
    text1.setSize(200, 10);

    Label label2 = new Label(shell, SWT.NONE);
    label2.setText("Donnee 2 :");
    Text text2 = new Text(shell, SWT.BORDER);
    text2.setSize(200, 10);

    Label label3 = new Label(shell, SWT.NONE);
    label3.setText("Donnee 3 :");
    Text text3 = new Text(shell, SWT.BORDER);
    text3.setSize(200, 10);

    Button button1 = new Button(shell, SWT.NONE);
    button1.setText("Valider");

    Button button2 = new Button(shell, SWT.NONE);
    button2.setText("Annuler");

    shell.pack();
    shell.open();

    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }

    display.dispose();
  }
}

Les paramètres liés à un composant d'une cellule particulière de la grille peuvent être précisés grâce à un objet de type GridData. Ces paramètres précisent le comportement du composant en cas de redimensionnement.

Il existe deux façons de créer un objet de type GridData :

La méthode setLayoutData() permet d'associer un objet GridData à un composant.

Attention : il ne faut pas appliquer le même objet GridData à plusieurs composants (la méthode setLayoutData() doit recevoir des objets GridData différents.).

Exemple :
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.*;

public class TestSWT28 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);

    GridLayout gridLayout = new GridLayout();
    gridLayout.numColumns = 2;
    shell.setLayout(gridLayout);

    Label label1 = new Label(shell, SWT.NONE);
    label1.setText("Donnee 1 :");
    Text text1 = new Text(shell, SWT.BORDER);
    text1.setSize(200, 10);

    Label label2 = new Label(shell, SWT.NONE);
    label2.setText("Donnee 2:");
    Text text2 = new Text(shell, SWT.BORDER);
    text2.setSize(200, 10);

    Label label3 = new Label(shell, SWT.NONE);
    label3.setText("Donnee 3 :");
    Text text3 = new Text(shell, SWT.BORDER);
    text3.setSize(200, 10);

    Button button1 = new Button(shell, SWT.NONE);

    button1.setText("Valider");

    Button button2 = new Button(shell, SWT.NONE);
    button2.setText("Annuler");

    GridData data = new GridData();
    data.widthHint = 120;
    label1.setLayoutData(data);

    data = new GridData();
    data.widthHint = 220;
    text1.setLayoutData(data);

    shell.pack();
    shell.open();

    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }

    display.dispose();
  }
}

 

39.9.2.4. FormLayout

Ce gestionnaire possède deux propriétés :

Propriété Valeur par défaut Rôle
marginHeight 0 préciser la hauteur de la marge
marginWidth 0 préciser la largeur de la marge

Ce gestionnaire impose d'associer à chaque composant un objet de type FormData qui va préciser les informations de positionnement et de comportement du composant.

 

39.10. La gestion des événements

La gestion des événements avec SWT est très similaire à celle proposée par l'API Swing car elle repose sur les Listeners. Ces Listeners doivent être ajoutés au contrôle en fonction des événements qu'ils doivent traiter.

Dès lors, lorsque l'événement est émis suite à une action de l'utilisateur, la méthode correspondante du Listener enregistré est exécutée.

Dans la pratique, les Listeners sont des interfaces qu'il faut faire implémenter par une classe selon les besoins. Cette implémentation définira donc des méthodes qui contiennent les traitements à exécuter pour un événement précis. Un ou plusieurs paramètres fournis à ces méthodes permettent d'obtenir des informations plus précises sur l'événement.

Il suffit ensuite d'enregistrer le Listener auprès du contrôle en utilisant la méthode addXXXListener() du contrôle où XXX représente le type du Listener.

Exemple : pour le traitement d'un clic d'un bouton
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;

public class TestSWT3 {

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setText("Test");

    Button button = new Button(shell, SWT.NONE);
    button.setText("Valider");
    button.setBounds(1, 1, 100, 25);

    button.addSelectionListener(new SelectionListener() {
      public void widgetSelected(SelectionEvent arg0) {
                        System.out.println("Appui sur le bouton");
      }
      public void widgetDefaultSelected(SelectionEvent arg0) {
      }
    });

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

Comme avec Swing, SWT propose un ensemble de classes de type Adapter qui sont des classes implémentant les interfaces Listener avec des méthodes vides. Pour les utiliser, il suffit de définir une classe fille qui hérite de la classe de type Adapter adéquate et de redéfinir la ou les méthodes utiles.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;

public class TestSWT4 {

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setText("Test");

    Button button = new Button(shell, SWT.NONE);
    button.setText("Valider");
    button.setBounds(1, 1, 100, 25);

    button.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent arg0) {
        System.out.println("Appui sur le bouton");
      }
    });

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

SWT définit plusieurs Listeners :

 

39.10.1. L'interface KeyListener

Cette interface définit deux méthodes keyPressed() et keyReleased() relatives à des événements émis par le clavier, respectivement lors de l'enfoncement d'une touche et la remontée d'une touche du clavier.

Ces deux méthodes possèdent un objet de type KeyEvent qui contient des informations sur l'événement grâce à trois attributs :

character contient le caractère de la touche concernée
keyCode

contient le code de la touche concernée

SWT défini des valeurs pour des touches particulières, par exemple SWT.ALT, SWT.ARROW_DOWN, SWT_ARROW_LEFT, SWT.CTRL, SWT.CR, SWT.F1, SWT.F2, ...

stateMask contient l'état du clavier au moment de l'émission de l'événement, ce qui permet de savoir si l'une des touches Shift, Alt ou Ctrl était enfoncée au moment de l'événement. Il suffit pour cela de comparer la valeur avec SWT.SHIFT, SWT.ALT ou SWT.CTRL.

SWT définit une classe KeyAdapter qui implémente l'interface KeyListener avec des méthodes vides.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;

public class TestSWT5 {

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setText("Test");

    shell.addKeyListener(new KeyAdapter() {
      public void keyReleased(KeyEvent e) {
        String res = "";
        switch (e.character) {
          case SWT.CR :
            res = "Touche Entree";
            break;
          case SWT.DEL :
            res = "Touche Supp";
            break;
          case SWT.ESC :
            res = "Touche Echap";
            break;
          default :
            res = res + e.character;
        }

        System.out.println(res);

      }
    });

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

Exemple : utilisation de la propriété stateMask
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;

public class TestSWT6 {

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setText("Test");

    shell.addKeyListener(new KeyAdapter() {
      public void keyReleased(KeyEvent e) {
        String res = "";
        if (e.keyCode == SWT.SHIFT) {
            res = "touche shift";
        } else {
          if ((e.stateMask & SWT.SHIFT) != 0) {
            res = "" + e.character + " + touche shift";
          }
        }
        System.out.println(res);
      }
    });

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

 

39.10.2. L'interface MouseListener

Cette interface définit trois méthodes mouseDown(), mouseUp() et mouseDoubleClick() relatives à des événements émis par un clic sur la souris, respectivement l'enfoncement d'un bouton et le relâchement d'un bouton ou le double clic sur un bouton de la souris.

Ces trois méthodes possèdent un objet de type MouseEvent qui contient des informations sur l'événement grâce à quatre attributs :

button contient le numéro du bouton utilisé (de 1 à 3). Attention, la valeur est dépendante du système utilisé, par exemple sous Windows avec une souris à molette possédant deux boutons, l'appui sur le bouton de droite renvoie 3
stateMask contient l'état du clavier au moment de l'émission de l'événement, ce qui permet de savoir par exemple si la touche Alt ou Shift ou Ctrl est enfoncée au moment de l'événement en effectuant un test sur la valeur avec SWT.ALT ou SWT.CTRL ou SWT.SHIFT
x contient la coordonnée x du pointeur de la souris par rapport au contrôle lors de l'émission de l'événement
y contient la coordonnée y du pointeur de la souris par rapport au contrôle lors de l'émission de l'événement

SWT définit une classe MouseAdapter qui implémente l'interface MouseListener avec des méthodes vides.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;

public class TestSWT7 {

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setText("Test");


    shell.addMouseListener(new MouseAdapter() {
      public void mouseDown(MouseEvent e) {
        String res = "";
          res = "bouton " + e.button + ", x = " + e.x + ", y = " + e.y;
          if ((e.stateMask & SWT.SHIFT) != 0) {
            res = res + " + touche shift";
          }
        System.out.println(res);
      }
    });

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

 

39.10.3. L'interface MouseMoveListener

Cette interface définit une seule méthode mouseMove() relative aux événements émis lors du déplacement de la souris au-dessus d'un contrôle.

Cette méthode possède un objet de type MouseEvent qui contient des informations sur l'événement grâce à quatre attributs.

La mise en oeuvre est similaire de l'interface MouseListener.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;

public class TestSWT8 {

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setText("Test");

    shell.addMouseMoveListener(new MouseMoveListener() {
      public void mouseMove(MouseEvent e) {
        String res = "";
        if ((e.x < 20) & (e.y < 20)) {

          res = "x = " + e.x + ", y = " + e.y;
          if ((e.stateMask & SWT.SHIFT) != 0) {
            res = res + " + touche shift";
          }
          System.out.println(res);
        }
      }
    });

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

 

39.10.4. L'interface MouseTrackListener

Cette interface définit trois méthodes mouseEnter(), mouseExit() et mouseHover() relatives à des événements émis respectivement par l'entrée de la souris sur la zone d'un composant, la sortie et le passage au-dessus de la zone d'un composant.

Ces trois méthodes possèdent un objet de type MouseEvent.

SWT définit une classe MouseTrackAdapter qui implémente l'interface MouseListener avec des méthodes vides.

Exemple : changement de la couleur de fond de la fenêtre
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;

public class TestSWT9 {

  public static void main(String[] args) {
    Display display = new Display();
    final Shell shell = new Shell(display);

    final Color couleur1 = new Color(display,155,130,0);
    final Color couleur2 = new Color(display,130,130,130);
    shell.setText("Test");

    shell.addMouseTrackListener(new MouseTrackAdapter() {
      public void mouseEnter(MouseEvent e) {
            shell.setBackground(couleur1);
      }
      public void mouseExit(MouseEvent e) {
            shell.setBackground(couleur2);           
      }
    });

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

 

39.10.5. L'interface ModifyListener

Cette interface définit une seule méthode modifyText() relative à un événement émis lors de la modification du contenu d'un contrôle de saisie de texte.

Cette méthode possède un objet de type ModifyEvent.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;

public class TestSWT10 {

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setText("Test");

    Text text = new Text(shell, SWT.BORDER);
    text.setText("mon texte");
    text.setSize(100, 25);

   text.addModifyListener(new ModifyListener() {
     public void modifyText(ModifyEvent e) {
       System.out.println("nouvelle valeur = " + ((Text)e.widget).getText());
      }
    });

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

 

39.10.6. L'interface VerifyText()

Cette interface définit une seule méthode verifyText() relative à un événement émis lors de la vérification des données avant modification du contenu d'un contrôle de saisie de texte.

Cette méthode possède un objet de type VerifyEvent qui contient des informations sur l'événement grâce à quatre attributs :

doit un drapeau qui indique si la modification doit être effectuée ou non
end la position de fin de la modification
start la position de début de la modification
text la valeur de la modification

Exemple : n'autoriser la saisie que de chiffres
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;

public class TestSWT11 {

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setText("Test");

    Text text = new Text(shell, SWT.BORDER);
    text.setText("");
    text.setSize(100, 25);

    text.addVerifyListener(new VerifyListener() {
      public void verifyText(VerifyEvent e) {
        int valeur = 0;
        e.doit = true;
        if (e.text != "") {
          try {
            valeur = Integer.parseInt(e.text);
          } catch (NumberFormatException e1) {
            e.doit = false;
          }
        }

        System.out.println(
          "start = " + e.start + ", end = " + e.end + ", text = " + e.text);

      }
    });

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

 

39.10.7. L'interface FocusListener

Cette interface définit deux méthodes focusGained() et focusLost() relatives à un événement émis respectivement lors de la prise et la perte du focus par un contrôle.

Ces méthodes possèdent un objet de type FocusEvent.

SWT définit une classe FocusAdapter qui implémente l'interface FocusListener avec des méthodes vides.

Exemple :
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.*;

public class TestSWT12 {

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);

    Text text = new Text(shell, SWT.BORDER);
    text.setText("mon texte");
    text.setBounds(10, 10, 100, 25);

    text.addFocusListener(new FocusListener() {
      public void focusGained(FocusEvent e) {
        System.out.println(e.widget + " obtient le focus");
      }
      public void focusLost(FocusEvent e) {
        System.out.println(e.widget + " perd le focus");
      }
    });

    Button button = new Button(shell, SWT.NONE);
    button.setText("Valider");
    button.setBounds(10, 40, 100, 25);

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

 

39.10.8. L'interface TraverseListener

Cette interface définit une méthode keyTraversed() relative à un événement émis lors de la traversée d'un contrôle au moyen de la touche tab ou des flèches haut et bas.

Cette méthode possède un objet de type TraverseEvent qui contient des informations sur l'événement grâce à deux attributs :

Attribut Rôle
doit un drapeau qui indique si le composant peut être traversé ou non
detail le type de l'opération qui génère la traversée

Exemple : empêcher le parcours des contrôles dans l'ordre inverse par la touche tab
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.*;

public class TestSWT13 {

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);

    TraverseListener tl = new TraverseListener() {
      public void keyTraversed(TraverseEvent e) {
        String res = "";
        res = e.widget + " est traverse grace à ";
        switch (e.detail) {
          case SWT.TRAVERSE_TAB_NEXT :
            res = res + " l'appui sur la touche tab";
            e.doit = true;
            break;
          case SWT.TRAVERSE_TAB_PREVIOUS :
            res = res + " l'appui sur la touche shift + tab";
            e.doit = false;
            break;
          default :
            res = res + " un autre moyen";
        }
        System.out.println(res);
      }
    };

    Text text = new Text(shell, SWT.BORDER);
    text.setText("mon texte");
    text.setBounds(10, 10, 100, 25);
    text.addTraverseListener(tl);

    Button button = new Button(shell, SWT.NONE);
    button.setText("Valider");
    button.setBounds(10, 40, 100, 25);
    button.addTraverseListener(tl);

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}

 

39.10.9. L'interface PaintListener

Cette interface définit une méthode paintControl() relative à un événement émis lors de la nécessité de redessiner le composant.

Cette méthode possède un objet de type PaintEvent qui contient des informations sur l'événement grâce à plusieurs attributs :

Attribut Rôle
gc un objet de type GC qui encapsule le contexte graphique
height la hauteur de la zone à redessiner
width la longueur de la zone à redessiner
x l'abscisse de l'origine de la zone à redessiner
y l'ordonnée de l'origine de la zone à redessiner

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;

public class TestSWT21 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setSize(420, 420);

    Canvas canvas = new Canvas(shell, SWT.NONE);
    canvas.setSize(200, 200);
    canvas.setLocation(10, 10);
    canvas.addPaintListener(new PaintListener() {
      public void paintControl(PaintEvent e) {
        GC gc = e.gc;
        gc.drawText("Bonjour", 20, 20);
        gc.drawLine(10, 10, 10, 100);
        gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
        gc.drawOval(60, 60, 60, 60);
      }
    });

    shell.pack();
    shell.open();

    GC gc = new GC(canvas);

    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }

    display.dispose();
  }
}

Remarque : il est important d'associer le listener avant d'ouvrir la fenêtre. Il n'est pas utile d'utiliser la méthode dispose() de l'objet de type GC car le code n'est pas responsable de son instanciation.

 

39.11. Les boîtes de dialogue

Comme dans toutes les interfaces graphiques, SWT permet l'utilisation de boîtes de dialogue soit prédéfinies soit personnalisées.

 

39.11.1. Les boîtes de dialogue prédéfinies

SWT propose plusieurs boîtes de dialogue prédéfinies.

 

39.11.1.1. La classe MessageBox

La classe MessageBox permet d'afficher un message à l'utilisateur et éventuellement de sélectionner une action standard via un bouton.

Les styles utilisables avec MessageBox sont :

La méthode setMessage() permet de préciser le message qui va être affiché à l'utilisateur.

La méthode open permet d'ouvrir la boîte de dialogue et de connaître le bouton qui a été utilisé pour fermer la boîte de dialogue en comparant la valeur de retour avec la valeur de style du bouton correspondant.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;

public class TestSWT18 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new GridLayout());
    shell.setSize(300, 300);

    Button btnOuvrir = new Button(shell, SWT.PUSH);
    btnOuvrir.setText("Afficher");
    btnOuvrir.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event e) {
        int reponse = 0;
        MessageBox mb = new MessageBox(shell, 
          SWT.ICON_INFORMATION | SWT.ABORT | SWT.RETRY | SWT.IGNORE);
        mb.setMessage("Message d'information pour l'utilisateur");
        reponse = mb.open();
        if (reponse == SWT.ABORT) {
          System.out.println("Bouton abandonner selectionne");
        }
        if (reponse == SWT.RETRY) {
          System.out.println("Bouton reessayer selectionne");
        }
        if (reponse == SWT.IGNORE) {
          System.out.println("Bouton ignorer selectionne");
        }
      }
    });

    shell.pack();
    shell.open();
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }
    display.dispose();
  }
}

 

39.11.1.2. La classe ColorDialog

Cette boîte de dialogue permet la sélection d'une couleur dans la palette des couleurs.

La méthode setRGB() permet de préciser la couleur qui est sélectionnée par défaut.

La méthode open() permet d'ouvrir la boîte de dialogue et de renvoyer la valeur de la couleur sélectionnée sous la forme d'un objet de type RGB. Si aucune couleur n'est sélectionnée (appui sur le bouton annuler dans la boîte de dialogue) alors l'objet renvoyé est null.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.graphics.*;

public class TestSWT15 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new GridLayout());
    shell.setSize(300, 300);

    Button btnOuvrir = new Button(shell, SWT.PUSH);
    btnOuvrir.setText("Couleur");
    btnOuvrir.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event e) {
        Color couleurDeFond = shell.getBackground();

        ColorDialog colorDialog = new ColorDialog(shell);
        colorDialog.setRGB(couleurDeFond.getRGB());
        RGB couleur = colorDialog.open();

        if (couleur != null) {
          if (couleurDeFond != null)
            couleurDeFond.dispose();
          couleurDeFond = new Color(display, couleur);
          shell.setBackground(couleurDeFond);
        }

      }
    });

    shell.getBackground().dispose();
    shell.open();
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }
    display.dispose();
  }
}

 

39.11.1.3. La classe FontDialog

Cette classe encapsule une boîte de dialogue permettant la sélection d'une police de caractère.

La méthode open() permet d'ouvrir la boîte de dialogue et renvoie un objet de type FontData qui encapsule les données de la police sélectionnée ou renvoie null si aucune n'a été sélectionnée.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;

public class TestSWT19 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new GridLayout());
    shell.setSize(300, 300);

    Label lblNomPolice = new Label(shell, SWT.NONE);
    lblNomPolice.setText("Nom de la police = ");
    final Text txtNomPolice = new Text(shell, SWT.BORDER | SWT.READ_ONLY);
    txtNomPolice.setText("");
    txtNomPolice.setSize(280, 40);

    Button btnOuvrir = new Button(shell, SWT.PUSH);
    btnOuvrir.setText("Police");
    btnOuvrir.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event e) {
        FontDialog dialog = new FontDialog(shell, SWT.OPEN);
        FontData fontData = dialog.open();
        if (fontData != null) {
          txtNomPolice.setText(fontData.getName());
          System.out.println("selection de la police " + fontData.getName());
          if (txtNomPolice.getFont() != null) {
            txtNomPolice.getFont().dispose();
          }
          Font font = new Font(display, fontData);
          txtNomPolice.setFont(font);

        }
      }
    });

    shell.pack();
    shell.open();
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }
    display.dispose();
  }
}

 

39.11.1.4. La classe FileDialog

Cette boîte de dialogue permet de sélectionner un fichier.

La méthode open() ouvre la boîte de dialogue et renvoie le nom du fichier sélectionné. Si aucun fichier n'est sélectionné, alors elle renvoie null.

La méthode setFilterExtensions() permet de préciser sous la forme d'un tableau de chaînes la liste des extensions de fichiers acceptées par la sélection.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;

public class TestSWT16 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new GridLayout());
    shell.setSize(300, 300);

    Label lblNomFichier = new Label(shell, SWT.NONE);
    lblNomFichier.setText("Nom du fichier = ");
    final Text txtNomFichier = new Text(shell, SWT.BORDER | SWT.READ_ONLY);
    txtNomFichier.setText("");
    txtNomFichier.setSize(280,40);
            
    Button btnOuvrir = new Button(shell, SWT.PUSH);
    btnOuvrir.setText("Ouvrir");
    btnOuvrir.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event e) {
        String nomFichier;
        FileDialog dialog = new FileDialog(shell, SWT.OPEN);
        dialog.setFilterExtensions(new String[] { "*.java", "*.*" });
        nomFichier = dialog.open();
        if ((nomFichier != null) && (nomFichier.length() != 0)){       
          txtNomFichier.setText(nomFichier);
            System.out.println("selection du fichier "+nomFichier);
        }
      }
    });

    shell.pack();
    shell.open();
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }

    display.dispose();
  }
}

 

39.11.1.5. La classe DirectoryDialog

Cette classe encapsule une boîte de dialogue qui permet la sélection d'un répertoire.

La méthode open() ouvre la boîte de dialogue et renvoie le nom du répertoire sélectionné. Si aucun répertoire n'est sélectionné, alors elle renvoie null.

La méthode setFilterPath() permet de préciser sous la forme d'une chaîne de caractères le répertoire sélectionné par défaut.

La méthode setMessage() permet de préciser un message qui sera affiché dans la boîte de dialogue.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;

public class TestSWT17 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new GridLayout());
    shell.setSize(300, 300);

    Label lblNomFichier = new Label(shell, SWT.NONE);
    lblNomFichier.setText("Nom du fichier = ");
            final Text txtNomRepertoire = new Text(shell, SWT.BORDER | SWT.READ_ONLY);
            txtNomRepertoire.setText("");
            txtNomRepertoire.setSize(280,40);
            

    Button btnOuvrir = new Button(shell, SWT.PUSH);
    btnOuvrir.setText("Ouvrir");
    btnOuvrir.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event e) {
        String nomRepertoire;
        DirectoryDialog dialog = new DirectoryDialog(shell, SWT.OPEN);
        dialog.setFilterPath("d:/");
        dialog.setMessage("Test");
        nomRepertoire = dialog.open();
        if ((nomRepertoire != null) && (nomRepertoire.length() != 0)){       
          txtNomRepertoire.setText(nomRepertoire);
          System.out.println("selection du repertoire "+nomRepertoire);
        }
      }
    });

    shell.pack();
    shell.open();
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }
    display.dispose();
  }
}

 

39.11.1.6. La classe PrintDialog

La classe PrintDialog encapsule une boîte de dialogue permettant la sélection d'une imprimante configurée sur le système. Pour utiliser cette classe, il faut importer la package org.eclipse.swt.printing.

La méthode open() permet d'ouvrir la boîte de dialogue et renvoie un objet de type PrinterData qui encapsule les données de l'imprimante sélectionnée ou renvoie null si aucune n'a été sélectionnée.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.printing.*;
import org.eclipse.swt.graphics.*;

public class TestSWT20 {

  public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new GridLayout());
    shell.setSize(300, 300);

    Button btnOuvrir = new Button(shell, SWT.PUSH);
    btnOuvrir.setText("Imprimer");
    btnOuvrir.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event e) {
        PrintDialog dialog = new PrintDialog(shell, SWT.OPEN);
        PrinterData printerData = dialog.open();
        if (printerData != null) {
          Printer printer = new Printer(printerData);
          if (printer.startJob("Test")) {
            printer.startPage();
            GC gc = new GC(printer);
            gc.drawString("Bonjour", 100, 100);
            printer.endPage();
            printer.endJob();
            gc.dispose();
            printer.dispose();
          }
        }
      }
    });

    shell.pack();
    shell.open();
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }
    display.dispose();
  }
}

Remarque : cet exemple est très basic dans la mesure où il est préférable de lancer les tâches d'impression dans un thread pour ne pas bloquer l'interface utilisateur pendant ces traitements.

 

39.11.2. Les boîtes de dialogue personnalisées

Pour définir une fenêtre qui sera une boîte de dialogue, il suffit de définir un nouvel objet de type Shell qui sera lui-même rattaché à sa fenêtre mère.

Exemple :
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;

public class TestSWT14 {

  public static void main(String[] args) {
    Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new GridLayout());
    shell.setSize(300,300);

    Button btnOuvrir = new Button(shell, SWT.PUSH);
    btnOuvrir.setText("Ouvrir");
    btnOuvrir.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event e) {
        final Shell fenetreFille = new Shell(shell, SWT.TITLE | SWT.CLOSE);
        fenetreFille.setText("Boite de dialogue");
                        fenetreFille.setLayout(new GridLayout());

        fenetreFille.addListener(SWT.Close, new Listener() {
          public void handleEvent(Event e) {
            System.out.println("Fermeture de la boite de dialogue");
          }
        });

        Button btnFermer = new Button(fenetreFille, SWT.PUSH);
        btnFermer.setText("Fermer");
        btnFermer.addListener(SWT.Selection, new Listener() {
          public void handleEvent(Event e) {
            fenetreFille.close();
          }
        });
        fenetreFille.setSize(200, 200);
        fenetreFille.open();
      }
    });

    shell.open();
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }
    display.dispose();
  }
}

 


  38. Le développement d'interfaces graphiques avec SWING 40. JFace Imprimer Sommaire Consulter avec table des matières Développons en Java   v 2.10  
Copyright (C) 1999-2016 .