0% ont trouvé ce document utile (0 vote)
37 vues473 pages

Introduction à l'IHM en Java

Transféré par

zakiyoussef811
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
37 vues473 pages

Introduction à l'IHM en Java

Transféré par

zakiyoussef811
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Interfaces Homme - Machine

Chapitre 1: Généralités sur les librairies graphiques


AWT et Swing

SMI - S6
Année universitaire 2017-2018

Prof. M.D. RAHMANI


mrahmani@[Link]
IHM c’est quoi ?

 Définition:
“L’Interaction Homme-Machine (IHM) est la discipline
qui étudie : la conception ; la mise en œuvre ; et l’évaluation de
systèmes interactifs utiles et utilisables destinés à des humains”.

 L’interface est (presque) la seule chose que l’utilisateur connaît


de l’application.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018’est 2


Objectifs
 Comprendre les concepts et les aspects techniques de la programmation
des interfaces graphiques (programmation événementielle, composants
graphiques, conteneurs, gestionnaires de placement, etc...)

 Maîtriser la programmation des composants les plus courants (fenêtres,


boutons, listes, menus, champs de saisie, etc...)
 Etre capable de concevoir et d’implanter convenablement une interface
graphique.

 Dessiner et afficher les images.

 Introduire la programmation concurrente avec les processus légers.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 3


Plan
 Chapitre 1- Les librairies graphiques AWT et swing
(Hiérarchie des classes, types de composants, création d’un cadre)
premiers exemples de composants graphiques.
Les composants atomiques : Les étiquettes, les boutons, les cases à
cocher, boutons radio..

 Chapitre 2- Conteneurs et gestionnaires de placement


Les conteneurs: les fenêtres, les boîtes de dialogue, les panneaux...
Les principaux gestionnaires de placement.

 Chapitre 3- Gestion des événements


Les types d’événements (la source, l’écouteur), les écouteurs de souris,
de clavier, les adaptateurs,…
Les principaux gestionnaires d’événement.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 4
Plan - suite
 Chapitre 4- Les Applettes Java
(la classe Japplet, écriture et lancement d’une applette, balises HTML
et attributs pour applettes , cycle de vie d’une applette, la
transformation d’une application graphique en une applette)
 Chapitre 5- Visualisation et édition de textes
(menus, sous-menus, accélérateurs, raccourcis,…)

 Chapitre 6- Dessin et affichage d’images


(la classe Graphics, les événements de bas niveau, dessin par la souris)
 Chapitre 7- Introduction à la concurrence avec les threads (processus légers)

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 5


Plan suite
Les travaux pratiques:
TP- Réalisation d’un micro-éditeur
Les travaux pratiques concernent la construction d’applications graphiques.
Nous commencerons par construire :
 une interface graphique simple sous forme d’une fenêtre,

 et nous finirons par une application graphique avec différents types de


composants, une barre de menu, une barre d’état, en utilisant des
gestionnaires de placement et des gestionnaires d’événements

 et en séparant les éléments modèle, vue et contrôleur.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 6


Bibliographie
1- Programmer en Java,
Claude Delannoy, Ed. Eyrolles (2017) 10ème édition.
2- Exercices en Java,
Claude Delannoy, Ed. Eyrolles (2017) 4ème édition.

3- Swing la synthèse, Développement des interfaces graphiques en Java


de Valérie Berthié et Jean-Baptiste Briaud, Ed. Dunod (pour débuter).

4- Les Cahiers du programmeur Swing


de Emmanuel Puybaret, Ed. Eyrolles.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 7


Webographie (Le langage Java)
Le site officiel: [Link]
Le site Web des développeurs Java
[Link]
Lettres d'informations relatives à la technologie Java
[Link]
Tutoriel Java : [Link]
[Link]
Centre de programmation Java pour débutants:
[Link]
Pour vérifier que Java est installé et qu'il fonctionne correctement sur votre ordinateur:
[Link]
Testez la version installée de Java: [Link]

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 8


Webographie (IHM)
" Programmation événementielle & interfaces graphiques Java Swing"
Eric Lecolinet , Télécom Paristech – Dept. INFRES
[Link]

" Université d’Aix-Marseille, IUT d'Aix-en-Provence, IHM & Java 2016


[Link]

"Université Grenoble Alpes"


[Link]

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 9


Chapitre 1- Les librairies graphiques AWT et Swing

◦ Hiérarchie des classes,


◦ Types de composants,
◦ Création d’un cadre,
◦ Premiers exemples de composants
graphiques,
◦ Introduction aux gestionnaires de placement.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 10


Les interfaces Homme-Machine
Nous allons aborder les Interfaces Homme Machine
(IHM) ou Interfaces Graphiques Utilisateur (GUI) pour
Graphical User Interfaces et par extension, la programmation
événementielle en Java.
 Système algorithmique (fermé) :
 lecture des données, calcul et production des résultats.
 il y'a un état final.
 Système interactif (ouvert) :
 événements provenant de l'extérieur.
 boucle infinie, non déterminisme.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 11


La programmation événementielle
Le programme ne réagit pas uniquement à des saisies
au clavier mais à des événements provenant d'actions
sur des composants graphiques : un bouton, une liste,
un menu…
 Ces actions peuvent modifier totalement le cheminement
du programme.
L'ordre d'exécution des instructions ne peut être prévu à l'écriture du
code.
 Le langage Java propose différentes bibliothèques (boîtes à
outils) pour programmer des IHM, nous utiliserons
essentiellement les packages [Link] et [Link].

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 12


Les librairies des interfaces graphiques en Java
 Les différents packages pour créer les objets graphiques en Java et de
gérer l'interaction avec l’utilisateur sont:

 Package [Link] (Abstract Windowing Toolkit)


 Package [Link]
 Package [Link] (IBM) (Standard Widget Toolkit)
 Package javafx (Oracle)
[Link]
[Link]
[Link].*

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 13


Les packages AWT et Swing
La 1ère bibliothèque pour réaliser des interfaces-utilisateur graphiques en
Java a été AWT (Abstract Windowing Toolkit).
Avec Java 2, Swing écrit en pur java, est ajoutée.
Ensemble AWT et Swing constituent la bibliothèque officiellement nommée
JFC (pour Java Foundation Classes).
 Les classes de AWT constituent le paquage [Link] et un ensemble de
paquages dont les noms commencent par [Link]:
[Link], [Link], [Link], etc...
 Les classes de Swing constituent le paquage [Link] et un ensemble
de paquages dont les noms commencent par [Link]:
[Link], [Link], etc.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 14


Le package: AWT
La 1ère API AWT (Abstract Windows Toolkit) est apparue dans la version
1.0 du JDK en 1995.
Le but de cette bibliothèque est de définir un ensemble de composants
graphiques communs à une variété de systèmes d'exploitation.
Ces composants appartiennent à une couche abstraite qui les lie à leurs
équivalents natifs sur chaque plate-forme.
Cette librairie utilise le système graphique de la plate-forme d'exécution
(Windows, MacOS, X-Window) pour afficher les objets graphiques.
Le package contient des classes décrivant les composants graphiques, les
polices, les couleurs et les images.
 Cette librairie est limitée car elle ne peut contenir que les composants
communs (composants lourds) à toutes les plates-formes.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 15


Le package: Swing (1)
La librairie Swing est apparue officiellement en 1997 avec Java 2 dans le cadre
du projet JFC (Java Foundation Classes).
Le code natif est remplacé par des composants écrits avec du code Java pur.
Ces composants sont devenus des éléments de la machine virtuelle de Java
(JVM); ce sont des composants légers.
Dans Swing, seule la fenêtre principale est construite par le système
d'exploitation, le reste par la JVM.
Ceci permet une grande variété de composants puissants et personnalisables,
n'appartenant pas nécessairement au toolkit natif.
Possibilités de dessin d'arbres ou de tableaux.
 La réalisation en Java pur empêche Swing d'atteindre les performances des
solutions natives.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 16
Le package: Swing (2)
Les concepteurs de Swing ont décidé de garder les même noms de la
librairie AWT en ajoutant un J au début des noms des classes:

JComponent,
JFrame,
JDialog,
JButton,
JPanel, etc...

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 17


Le package: SWT
IBM a décidé de créer son propre toolkit, le Standard Widget Toolkit (SWT),
autour de l'environnement de développement Eclipse.

SWT adopte une approche intermédiaire entre AWT et Swing:

1- Il fait appel comme AWT au système d'exploitation hôte pour gérer et


afficher les composants graphiques communs.
2- Comme Swing, il émule les composants n'appartenant pas à un toolkit
natif.
Les paquetages principaux pour développer des applications graphiques sont:
[Link] et [Link].

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 18


Le package: JavaFX (1)
 2008: SUN a sorti la première version stable de JavaFx, l’objectif est de donner un
concurrent des environnements Silverlight de Microsoft et Flex d’Adobe.

 Depuis Silverlight est 'mort' et Flex a été donné à la fondation Apache en 2011.

 Dans sa première version, JavaFx ne permettait pas de développer en Java. Il fallait


passer par le langage JavaFx Script.
Ce fut abandonné à partir de JavaFx 2. à l’occasion de la sortie de Java 8 en mars
2014.

 JavaFx permet la création d’applications desktop (ou lourdes) ainsi que la


création d’applications riches (Rich Internet Application) qui s’exécutent dans le
navigateur en utilisant le plugin Java.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 19


Le package: JavaFX (2)
JavaFx a introduit FXML, le nouveau langage basé sur XML utilisé
pour séparer le design des interfaces graphiques du code Java qui les
manipule et les contrôle.
Les fichiers FXML (Formulaire XML) sont des fichiers XML qui
vont permettre de décrire l'interface de manière plus visuelle que le code
brut. On parle de langage de définition d'interface graphique par balisage
(User Interface Markup Language).

Quelques nouveautés :
Gestion de la 3D : le support des textures, la gestion de l'éclairage,
la possibilité de rendre des sous-parties d'une scène ou encore de déplacer
la caméra.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 20


Hiérarchie des classes (1)
 Composants (Component):
La classe [Link] est la super-classe de toutes les classes qui
représentent des composants graphiques, aussi bien AWT que Swing.
 Conteneurs (Container):
La classe [Link] est une sous-classe de
[Link].
Un conteneur est un composant qui peut contenir d'autres.
 Fenêtres (Window):
La classe [Link] est une sous classe de [Link].
La caractéristique d'une fenêtre est la possibilité d'être visible sans nécessiter
d'être incluse dans un autre composant.
Les fonctionnalités de cette classe sont presque toujours exploitées à travers les
sous classes Frame et Dialog.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 21


Hiérarchie des classes (2)

Component

Container

Window JComponent Panel

Frame Dialog JWindow Applet

JFrame JDialog JApplet

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 22


Hiérarchie des classes (3)
 Cadres et boîtes de dialogue (Frame, Dialog):
Les classes [Link] (cadre) et [Link]
(boîte de dialogue) sont des sous classes de Window.

 Un cadre (Frame) est une fenêtre munie d'un bord, un bandeau de


titre et éventuellement une barre de menu.

Le cadre remplit au moins 3 fonctions:


1- la modification de la taille et la forme de l'interface,
2- le port de la barre de menu de l'application,
3- la fermeture du cadre produit la terminaison de l'application.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 23


Hiérarchie des classes (4)
 Les boites de dialogues (Dialog) sont elles aussi des fenêtres munies
d'un bord et d'une barre de titre.
 Elles sont destinées pour afficher des messages, poser une question ou
demander des informations.
 Elles permettent à l'utilisateur de faire les actions demandées: cocher
une case, remplir un champ de texte, faire des choix dans les listes, etc.

 Les boîtes de dialogues peuvent être modales et non modales:


 Une boîte modale bloque toutes les autres fenêtres de l'application,
sauf celles dont la boîte en question est propriétaire.
 Une boite non modale n'a pas d'effet bloquant sur les autres fenêtres

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 24


Exemple 1: une interface graphique avec JWindow
[Link]

import [Link];
public class Fenetre0 {
public static void main(String[] args) {
JWindow fenetre = new JWindow();
[Link](300,200); // taille de la fenêtre en pixels
[Link](true); // rendre visible la fenêtre
}
}

Le résultat n'est pas probant! une fenêtre sans barre de titre, sans bordure et sans
boutons, non déplaçable et non redimensionnable.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 25


Exemple 2: une interface graphique avec JDialog
[Link]

import [Link];
public class Fenetre1 {
public static void main(String[] args) {
JDialog fenetre = new JDialog();
[Link](300, 200);
[Link](true);
}
}

Une fenêtre (boîte de dialogue) avec barre de titre, bordure et un bouton pour fermer.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 26


Exemple 3: une interface graphique avec JFrame

import [Link];
public class Fenetre2 {
public static void main(String[] args) {
JFrame fenetre = new JFrame();
[Link](300, 200);
[Link](true);
}
}

Une fenêtre avec une barre de titre, une bordure, des boutons pour réduire, maximiser
la taille et fermer la fenêtre.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 27
Une interface graphique avec JFrame (avec titre)
Exemple avec la classe Jframe, l’ajout d’un titre: [Link]
import [Link];
public class Fenetre3 {
public static void main(String[] args) {
JFrame fenetre = new JFrame();
[Link]("Ma première fenêtre");// titre
[Link](300, 200);
[Link](true);
}
}
Image avec windows 10

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 28


Hiérarchie d'une interface graphique
 Dans une interface graphique on imbrique généralement trois niveaux
d’objets graphiques:
o Le conteneur principal: permet d’encapsuler toutes les entités des
deux autres niveaux (par exemple une fenêtre JFrame)
o Un composant-conteneur intermédiaire: un conteneur qui se charge
de regrouper en son sein des composants atomiques (par exemple un
panneau JPanel)
o Un composant atomique: appelé aussi widget. Il s’agit d’un
élément de base: bouton, zone de saisie, liste de choix déroulante…

Ces composants sont ajoutés dans le conteneur courant en invoquant


la méthode add.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 29


Conteneurs et composants (1)
 Une interface graphique en Java est un assemblage de conteneurs (Container) et de
composants (Component).

 Un conteneur est un espace dans lequel on peut positionner plusieurs composants.


 Sous-classe de la classe [Link]

 La classe Container est elle-même une sous-classe de la classe Component

 Par exemple les fenêtres, les applettes, les panneaux, etc.

 Un composant est une partie "visible" de l'interface utilisateur Java.


 C’est une sous-classe de la classe abstraite [Link].

 Exemple : les boutons, les zones de textes ou de dessin, etc.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 30


Conteneurs et composants (2)

Les deux conteneurs les plus courants sont le JFrame et le JPanel.


 Un JFrame (cadre) représente une fenêtre de haut niveau (top level) avec un titre, une
bordure et des angles de redimensionnement.
 La plupart des applications utilisent au moins un JFrame comme point de départ
de leur interface graphique.
 Du point de vue du système d'exploitation, cette fenêtre représente l'application.

 Un JPanel (panneau) n'a pas une apparence propre et ne peut pas être utilisé comme
fenêtre autonome.
 Les Panels sont créés et ajoutés aux autres conteneurs de la même façon que les
composants tels que les boutons.
 Les Panels peuvent ensuite redéfinir une présentation qui leur soit propre pour
contenir eux-mêmes d'autres composants.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 31


Conteneurs et composants (3)
Construction d'une fenêtre:
JMenuBar

JFrame

JPanel (2 panneaux imbriqués)

Composants

Gestionnaire de placement
(un par conteneur)
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 32
Création d'un cadre avec JFrame (1)
La classe JFrame:
Pour créer un cadre (une fenêtre graphique), on dispose dans le
paquetage [Link], d'une classe standard nommée JFrame,
possédant un constructeur sans arguments.

Exemple:
- Création d'un objet de type JFrame référencée par la variable fenetre,

JFrame fenetre = new JFrame();

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 33


Création d'un cadre avec JFrame (2)
 Pour rendre visible cette fenêtre, on appelle la méthode setVisible:
[Link](true);

 Par défaut, une fenêtre est crée avec une taille nulle, il est nécessaire de
définir les dimensions,
[Link](300, 150);
// donne à la fenêtre une largeur de 300 pixels et une hauteur de 150 pixels.

 Pour afficher un texte dans la barre de titre, on utilise la méthode


setTitle,
[Link]("Ma première fenêtre");

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 34


Création d'un cadre avec JFrame (3)
1- Création d'une fenêtre graphique [Link]
import [Link];
public class Fenetre{
public static void main(String[] args) {
// Instancier un objet de type JFrame
JFrame maFenetre = new JFrame();
// Donner un titre de la fenêtre
[Link]("Ma fenêtre avec swing");
// Donner une taille (400*300)
[Link](400,300);
// Afficher la fenêtre,
[Link](true);
}
}
Remarque: on peut déplacer, modifier la taille de cette fenêtre, ou la réduire à une icone, mais
sa fermeture ne termine pas l'application !

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 35


Création d'un cadre avec JFrame (4)
2- Création d'une fenêtre personnalisée:
Pour ajouter des fonctionnalités ou des champs supplémentaires, il vaut
mieux définir une classe propre dérivée de JFrame et créer un objet de ce
nouveau type: [Link] et [Link]
import [Link];
public class MaFenetre extends JFrame {
public MaFenetre() { // le constructeur
setTitle("Ma fenêtre avec swing");
setSize(400,300);
}
}
public class TestFenetre {
public static void main(String[] args) {
MaFenetre maFenetre = new MaFenetre();
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 36


Actions sur les caractéristiques d'une fenêtre (1)
Par défaut, la fenêtre est positionnée au coin supérieur gauche, qui coïncide
avec l'origine des coordonnées.
L'axe des abscisses est orienté vers la droite, celui des ordonnées vers le bas.
On peut fixer la position de la fenêtre à l'écran, en utilisant la méthode
setBounds:
[Link](250,150,300,200);
// Le coin supérieur gauche de la fenêtre est placé au pixel (250,150)
// et ses dimensions seront de 300*200 pixels

On peut centrer la fenêtre au lancement par:


[Link](null);

Pour terminer réellement l'application:


// Un clic sur croix rouge entraîne la fermeture de l'application
[Link](JFrame.EXIT_ON_CLOSE);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 37


Actions sur les caractéristiques d'une fenêtre (2)
Positionner la fenêtre à l'écran:
La méthode setLocation(int x, int y)
avec x, y les coordonnées du coin supérieur gauche de l'écran.
Empêcher le redimensionnement de la fenêtre
Pour cela, il suffit d'invoquer la méthode setResizable(boolean b) :
false empêche le redimensionnement tandis que true l'autorise.
Garder la fenêtre au premier plan
La méthode setAlwaysOnTop(boolean b)
true laissera la fenêtre au premier plan, false annulera cela.
Retirer les contours et les boutons de contrôle
Pour ce faire, il faut utiliser la méthode setUndecorated(boolean b).

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 38


Actions sur les caractéristiques d'une fenêtre (3)
Exemple : [Link]
import [Link];
public class Fenetre4{
public static void main(String[] args) {
JFrame maFenetre = new JFrame(); // Instancier une Fenêtre
[Link]("Fenêtre centrée et non modifiable"); // Le titre de la fenêtre
[Link](400,150); // La taille (400*150)
[Link](false); // Taille non modifiable par l'utilisateur
// Un clic sur la croix rouge entraîne la fermeture de l'application
[Link](JFrame.EXIT_ON_CLOSE);
[Link](null); // Centrer la fenêtre à l'écran
[Link](true); // Afficher la fenêtre
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 39


Actions sur les caractéristiques d'une fenêtre (4)
Exemple : [Link] (Fenêtre avec icone personnelle)

import [Link].*;
public class Icone1 {
public static void main(String argv[]) {
JFrame f = new JFrame("ma fenetre");
[Link](300,100);
[Link](JFrame.DISPOSE_ON_CLOSE);
ImageIcon image = new ImageIcon("C:\\TPIHM2018\\[Link]");
[Link]([Link]());
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 40


Actions sur les caractéristiques d'une fenêtre (5)
On peut préciser à un JFrame ou à un JDialog comment doivent
réagir au clic sur la croix rouge d'une fenêtre, grâce à la méthode
setDefaultCloseOperation() qui reçoit 4 valeurs pour son argument :

o setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // 0
Ignorer le clic
o setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); // 1
L'option par défaut, cache la fenêtre, mais l'application reste en cours
d'exécution.
o setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // 2
Détruit la fenêtre, mais laisse l'application en exécution.
o setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 3
L'application se termine quand on ferme la fenêtre.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 41


Actions sur les caractéristiques d'une fenêtre (6)
Voici un exemple purement théorique (on n'a pas une interface graphique
avec 2 têtes : JFrame !) pour montrer la différence entre les 2 options de la
réaction d'une fenêtre.
Exemple : [Link] (Fenêtre avec icone personnelle)
import [Link].*;
public class DeuxFenetres {
public static void main (String[] args) {
JFrame principal = new JFrame("Un Clic ferme toute l'application");
JFrame secondaire = new JFrame("Un Clic ferme que celle la");

[Link](true);
[Link](JFrame.EXIT_ON_CLOSE); // 3
[Link]( 400, 300 );

[Link](true);
[Link](JFrame.DISPOSE_ON_CLOSE); // 2
[Link](300, 200);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 42


Le conteneur JFrame
Un JFrame est un objet complexe dont un élément, le
"panneau de contenu" (Content-Pane) est le conteneur auquel les
composants sont ajoutés.

On accède au panneau de contenu d'un objet JFrame par la méthode


getContentPane().

En pratique les cadres des applications sont destinés à être fortement


personnalisés, en recevant des composants divers et nombreux.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 43


Les composants d'un cadre: JFrame
Dans l'ordre :

 la fenêtre ;
 le RootPane (en vert), le conteneur principal qui contient
les autres composants ;
 le LayeredPane (en bleu), qui forme juste un panneau
composé du conteneur global Content-Pane et de la barre
de menu (MenuBar) ;
 la MenuBar (en orange), la barre de menu, quand il y en a
une ;
 le Content-Pane (en violet) : le conteneur des
composants;
 le GlassPane (en transparence), couche utilisée pour
intercepter les actions de l'utilisateur avant qu'elles ne
parviennent aux composants.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 44


Ajout de composants dans un cadre (1)
L'ajout d'un composant dans la fenêtre:
Un composant ne peut être directement inséré dans une fenêtre (JFrame), mais à son
panneau de contenu (Content-Pane).
La méthode getContentPane() de la classe JFrame fournit la référence à son
contenu, de type Container (super classe).
D'autre part, la méthode add de la classe Container permet d'ajouter un composant
quelconque à un objet de ce type.
Exemple:
Pour ajouter le bouton etiquette au conteneur du premier niveau cadre il suffit
d'écrire:
JLabel etiquette = new JLabel("Une étiquette"); // composant
Jframe cadre = new JFrame("Titre du cadre"); // conteneur JFrame
[Link]().add(etiquette); // ajout du composant
Ou d'une façon condensée, depuis la version 5 de Java (sans le getContentPane):
[Link](etiquette); // ajout du composant

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 45


Ajout de composants dans un cadre (2)
Exemple 1: étiquette et couleur
Un cadre avec JFrame: [Link]
import [Link];
import [Link].*;
public class Cadre1 {
public static void main(String[] args) {
JFrame cadre = new JFrame("Titre du cadre");
JLabel etiquette = new JLabel("Une étiquette", [Link]);
[Link](etiquette);
//affectation de la couleur jaune
[Link]().setBackground([Link]
[Link](300, 100);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 46


Ajout de composants dans un cadre (3)
Exemple 2: Une classe dérivée de JFrame
[Link]
import [Link];
import [Link].*;
public class Cadre2 extends JFrame {
public Cadre2() { // le constructeur
super("Le Titre de mon cadre 2");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // pour terminer l'application
JLabel etiquette = new JLabel("Bonjour à tous", [Link]);
add(etiquette);
getContentPane().setBackground([Link]);
setSize(350, 100);
}

public static void main(String[] args) {


new Cadre2();
setVisible(true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 47


Ajout de composants dans un cadre (4)
Le conteneur JPanel:
Le Content-Pane est un conteneur de composants; pour l'utiliser, il suffit
d'invoquer la méthode getContentPane()de la classe JFrame.
Cependant, nous pouvons utiliser un composant autre que le Content-Pane : un
JPanel dans lequel nous insérerons nos composants.

Un JPanel est un composant de type conteneur, intermédiaire, dont la vocation est


d'accueillir d'autres conteneurs ou des composants de base (boutons, cases à cocher…).

La marche à suivre :
1. Importer la classe [Link] dans notre classe héritée de JFrame.
2. Instancier un JPanel puis on va lui spécifier une couleur de fond pour mieux le
distinguer.
3. Avertir notre JFrame que ce sera notre JPanel qui constituera son Content-Pane.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 48


Ajout de composants dans un cadre (5)
Exemple : [Link]
import [Link];
import [Link];
import [Link];
public class Fenetre5 extends JFrame {
public Fenetre5(){
[Link]("Mon panneau orange");
[Link](300, 100);
[Link](null); // La fenêtre au centre au lancement
JPanel paneau = new JPanel(); // Instanciation d'un objet JPanel
[Link]([Link]); // Définition de sa couleur de fond
//On prévient notre JFrame que notre JPanel sera son Content-Pane
[Link](paneau);
[Link](JFrame.EXIT_ON_CLOSE); // ou 3
}
}
public class Panneau1 {
public static void main(String[] args) {
Fenetre5 fenetre = new Fenetre5();
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 49


Ajout de composants dans un cadre (6)
 On ajoute un composant dans un conteneur, avec la méthode add() :
 JPanel p = new JPanel();
 JButton b = new JButton();
 [Link](b); // ajout d'un bouton dans un panneau

 De manière similaire, un composant est retiré de son conteneur par la


méthode remove() :
 [Link](b); // supprime le bouton du panneau

 Un composant a:
 une taille préférée que l’on obtient avec getPreferredSize()
 une taille minimale que l’on obtient avec getMinimunSize()
 une taille maximale que l’on obtient avec getMaximunSize()

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 50


Ajout de composants dans un cadre (7)
Affichage du bouton (la notion de gestionnaire de placement):

La disposition des composants dans une fenêtre est géré par un


gestionnaire de placement (en anglais: Layout Manager).
Un gestionnaire de type FlowLayout dispose les différents
composants "en flot", d'abord sur une même ligne, puis ligne par ligne.

Pour choisir un gestionnaire, il suffit d'appliquer la méthode


setLayout à l'objet contenu dans la fenêtre.

Exemple: pour obtenir un gestionnaire de type FlowLayout souhaité,


getContentPane().setLayout(new FlowLayout());

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 51


Ajout de composants dans un cadre (8)
Exemple : [Link]
import [Link].*; // pour JFrame
import [Link].*; // pour FlowLayout

class Fen1Bouton extends JFrame {


JButton monBouton; // on peut le déclarer private
public Fen1Bouton() { // constructeur
setTitle ("Premier Bouton");
setSize(300,150);
monBouton = new JButton("Test Swing");
//getContentPane().setLayout(new FlowLayout());
setLayout(new FlowLayout()); // centré par défaut
//getContentPane().add(monBouton);
add(monBouton);
}
}
public class Bouton1 {
public static void main(String args[]){
Fen1Bouton f = new Fen1Bouton();
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 52
Ajout de composants dans un cadre (avec AWT) (9)
[Link]

import [Link].*;

public class Bouton2 {


public static void main(String[] args) {
Frame f =new Frame("Premier bouton");
Button b= new Button("Test AWT");
[Link](new FlowLayout()); // centré par défaut
[Link](b); // Ajout du composant
[Link](300, 150);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 53


Gestion de plusieurs composants
Pour ajouter d'autres boutons dans la fenêtre, nous utilisons le
gestionnaire de type FlowLayout, ils seront affichés séquentiellement
dans l'ordre de leur ajout.

Remarque:
- Le gestionnaire par défaut d'un JFrame est BorderLayout, tous
les composants s'affichent au centre.
Seul le dernier sera visible.
- Le gestionnaire par défaut d'un JPanel est FlowLayout.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 54


Exemple: un panneau avec 3 boutons
Exemple: [Link]
La définition d'une classe JPanel qui est un conteneur portant trois boutons,
import [Link].*;
class TroisBoutons extends JPanel { // FlowLayout par défaut
public TroisBoutons() {
JButton bouton = new JButton("Oui");
add(bouton);
bouton = new JButton("Non");
add(bouton);
// [Link](false);// pour désactiver un composant
bouton = new JButton("Sans avis");
add(bouton);
}

public static void main(String[] args) {


JFrame cadre = new JFrame("Trois boutons");
[Link](JFrame.EXIT_ON_CLOSE);
// [Link]().add(new TroisBoutons());
[Link](new TroisBoutons());
//[Link](); // le composant JPanel occupe tout l’espace
[Link](300,150);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 55


Les composants de base (1)
 JButton
 JCheckbox (case à cocher)
 JToggleButton (le bouton à 2 états)
 JRadioButton (choix exclusif)
 JComboBox (Liste déroutlante)
 JLabel
 JList
 JScrollbar (barre de défilement)
 JTextField (zone de saisie d’une ligne)
 JTextArea (zone de saisie multi-lignes)

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 56


Les composants de base (2)
 JLabel, hérite de JComponent
 Un JLabel affiche une seule ligne de texte (étiquette) non modifiable ou/et
une image.
 En général, les étiquettes ne traitent pas d'événements.
 Définition du texte:
 par le constructeur: JLabel et = new JLabel("Etiquette");
 par la méthode setText: [Link]("Une autre étiquette");
 Définition d'une image:
 la méthode setIcon: [Link](new ImageIcon("[Link]");
 position du texte par rapport à l'image:
o [Link]([Link]);
o [Link]([Link]);
 Support de HTML: [Link]("<html>texte en<i>italique</i></html>");

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 57


Les composants de base (2)
 JLabel, hérite de Jcomponent
Un cadre avec JFrame: [Link]
import [Link];
import [Link].*;
public class Etiquette1 {
public static void main(String[] args) {
JFrame cadre = new JFrame("Cadre avec étiquette");
JLabel etiquette = new JLabel("Une étiquette", [Link]);
[Link](etiquette);
[Link]().setBackground([Link]);
[Link](300, 100);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 58


Les composants de base (3)
 AbstractButton
 La classe abstraite AbstractButton définit une classe qui regroupe les
caractéristiques de tous les boutons:
 Les boutons:
 JButton
 JToggleButton (un bouton à 2 états, à bascule)
 JChekBox (case à cocher)
 JRadioButton (bouton radio)
 Les éléments de menus:
 JMenuItem
 JCheckBoxMenuItem
 JRadioButtonMenuItem
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 59
Les composants de base (3 bis)
 La classe AbstractButton
Elle fournit de nombreuses méthodes pour paramétrer les boutons, sur-
définies dans les classes filles pour adapter leur comportement.

 setText : permet d'insérer du texte dans le composant,


 setIcon : permet de spécifier l'icone par défaut du composant,
 setMnemonic : permet de définir une touche de raccourci pour le
clavier (Alt + caractère),

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 60


Les composants de base (4)
 JButton (hérite de AbstractButton)
 C'est un composant d'interface de base de type "appuyer pour activer".
 Il peut être construit avec une étiquette de texte (un Jlabel) précisant son
rôle.
 Un objet de la classe JButton est une source d'événement.
 Création d'un bouton:
 Avec étiquette: JButton jbt = new JButton("Exemple");
 Avec image: JButton jbt = new JButton("Exemple",icon);
 Association d'un raccourci clavier: [Link]('r'); //Alt+r
 Enlever/Ajouter une bordure: [Link](false);
 Enlever le cadre indiquant le focus: [Link](false);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 61


Les composants de base (5)
 JButton: bouton et étiquette
import [Link].*;
class BoutonEtEtiquette extends JPanel {
public BoutonEtEtiquette() {
JLabel etiquette = new JLabel("Etiquette");
add(etiquette);
JButton bouton = new JButton("Oui");
add(bouton);
}

public static void main(String[] args) {


JFrame cadre = new JFrame("Bouton & Etiquette");
[Link](JFrame.EXIT_ON_CLOSE);
// [Link]().add(new BoutonEtEtiquette());
[Link](new BoutonEtEtiquette());
[Link](350,100);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 62


Les composants de base (6)
 JButton: bouton et icon

import [Link].*;
class BoutonAvecIcon extends JPanel {
public BoutonAvecIcon() {
JLabel etiquette = new JLabel("Etiquette");
add(etiquette);
String url = "[Link]"; // l'image est dans le répertoire projet
ImageIcon img = new ImageIcon(url);
JButton bouton = new JButton("Oui", img);
add(bouton);
}

public static void main(String[] args) {


JFrame cadre = new JFrame("Bouton avec Icon & Etiquette");
[Link](3);
[Link]().add(new BoutonAvecIcon());
// ou simplement [Link](new BoutonAvecIcon());
[Link]();
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 63


Les composants de base (6)
 JToggleButton (hérite de AbstractButton)
 C'est un bouton qui a deux états qui indique une activation ou non d'une
option.
 Il peut être construit avec une étiquette de texte (un label) précisant son rôle.
 Un objet de la classe JToggleButton est une source d'événements.
 Création d'un JTogglebouton:
JPanel p;
JToggleButton jtbt = new JToggleButton("Exemple", true);
[Link](jtbt);
 Activation de l'état: [Link](true);
 Consulter l'état: [Link](); // réponse true ou false
 Remarque: On peut comparer le JButton à un bouton poussoir et un
JToggleButton à un interrupteur.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 64


Les composants de base (7)
 JToggleButton (le bouton à 2 états)

import [Link].*;
class BoutonEtEtiquette2 extends JPanel {
public BoutonEtEtiquette2() {
JLabel etiquette = new JLabel("Etiquette2");
add(etiquette);
JToggleButton bouton = new JToggleButton("Oui");
add(bouton);
}

public static void main(String[] args) {


JFrame cadre = new JFrame("Bouton à 2 états");
[Link](JFrame.EXIT_ON_CLOSE);
[Link](new BoutonEtEtiquette2());
[Link](300,100);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 65


Les composants de base (8)
 JCheckBox (case à cocher), hérite de JToggleButton
 Chaque case à cocher est indépendante des autres.
 Création:
JPanel jp;
JCheckBox cb1 = new JCheckBox("Choix 1");
[Link](cb1);
JCheckBox cb2 = new JCheckBox("Choix 2");
[Link](cb2);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 66


Les composants de base (9)
 JCheckBox (case à cocher), hérite de JToggleButton
import [Link].*;
class BoutonEtEtiquette3 extends JPanel {
public BoutonEtEtiquette3() {
JLabel etiquette = new JLabel("Etiquette3");
add(etiquette);
JCheckBox casePasCochee = new JCheckBox("Case à cocher");
add(casePasCochee);
JCheckBox caseCochee = new JCheckBox("Case cochée",true);
add(caseCochee);
}

public static void main(String[] args) {


JFrame cadre = new JFrame("Bouton & Etiquette 3");
[Link](JFrame.EXIT_ON_CLOSE);
[Link](new BoutonEtEtiquette3());
[Link](400,100);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 67


Les composants de base (10)
 JRadioButton (bouton radio), hérite de JToggleButton
 Les JRadioButton sont présentés par groupe. Un seul du groupe à la fois
peut être sélectionné.
 Il faut créer un objet de la classe ButtonGroup et lui ajouter des
JRadioButton.
 Le JRadioButton peut avoir deux états: sélectionné ou pas.
ButtonGroup bg = new ButtonGroup();
JRadioButton rb1 = new JRadioButton("bouton radio 1");
JRadioButton rb2 = new JRadioButton("bouton radio 2");
[Link](true);
[Link](rb1);
[Link](rb2);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 68


Les composants de base (11)
 JRadioButton (bouton radio, à choix exclusif), hérite de JToggleButton

import [Link].*;
class BoutonsRadio extends JPanel {
ButtonGroup groupeBoutons = new ButtonGroup();
public BoutonsRadio() {
JRadioButton bouton1 = new JRadioButton("Bouton radio 1");
[Link](bouton1);
[Link](bouton1);
JRadioButton bouton2 = new JRadioButton("Bouton radio 2 cochée",true);
[Link](bouton2);
[Link](bouton2);
}

public static void main(String[] args) {


JFrame cadre = new JFrame("Boutons radio");
[Link](3);
[Link]().add(new BoutonsRadio());
[Link](400,100);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 69


Les composants de base (12)
 JComboBox
 Un JComboBox est un composant qui permet de choisir
une option dans une liste déroulante.
 Son équivalent en AWT est la classe Choice.
 Un JComboBox peut être créé à partir d'un tableau ou
d'un Vector d'objets.
String[] choix = {"vrai", "faux"};
JComboBox cb = new JComboBox(choix);
On peut choisir un seul objet de la liste choix,
Les méthodes getSelectedIndex et getSelectedItem permettent
de connaître l'indice et l'objet sélectionné.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 70


Les composants de base (13)
 JComboBox: liste déroulante

import [Link].*;
class BoiteCombo extends JPanel {
public BoiteCombo() {
String[] matieres={"BD", "Compilation", "IHM", "Réseaux"};
JComboBox choix = new JComboBox(matieres);
JLabel etiquette = new JLabel("Choisissez une matière : ");
add(etiquette);
add(choix);
}
public static void main(String[] args) {
JFrame cadre = new JFrame("Choix dans une liste");
[Link](3);
[Link]().add(new BoiteCombo());
[Link](400,100);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 71


Les capacités communes des composants (1)
 activation / désactivation du composant (le composant réagit ou non
aux interactions avec l'utilisateur).
 setEnabled(boolean);
 isEnabled() -> boolean

 visibilité/invisibilité d'un composant


 setVisible(boolean);
 isVisible() -> boolean

 bulles d'aide ("tooltips")


 setToolTipText(String);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 72


Les capacités communes des composants (2)
 Contrôle des couleurs d'un composant
 Deux méthodes permettent de définir les couleurs d'un composant
 setForeground (Color c) : la couleur de l’encre avec
laquelle on écrira sur le composant
 setBackground (Color c) : la couleur du fond

 Ces deux méthodes utilisent un argument instance de la classe


[Link].

 Il est aussi possible de créer une couleur spécifique (RGB)


int r = 255, g = 255, b=0;
Color c = new Color(r, g, b);
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 73
Les capacités communes des composants (3)
 Contrôle des polices de caractères
 La police utilisée pour afficher du texte dans un composant peut être
définie avec setFont(...)avec comme argument une instance de la
classe [Link].
 Font f = new Font ("TimesRoman", [Link], 14) ;
 Les constantes de style de police sont en réalité des valeurs entières,
parmi celles citées ci-après :
 [Link]
 [Link]
 [Link]
 [Link] + [Link]
 Les tailles en points doivent être définies avec une valeur entière.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 74


Bordures des composants Swing (1)
 Des bordures peuvent être dessinées, avec une fabrique de bordures
(BorderFactory), autour de chaque composant graphique. Parmi ces types :
 AbstractBorder : ne fait rien

 BevelBorder : une bordure 3D en surépaisseur ou en creux

 CompoundBorder : composition de plusieurs bordures

 EmptyBorder: sans bordures

 EtchedBorder: une bordure gravée

 LineBorder : bordure d'une seule couleur

 MatteBorder: style matt de gravure

 SoftBevelBorder : une bordure 3D aux coins arrondis

 TitledBorder : une bordure avec un titre

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 75


Bordures des composants Swing (2)
Les différentes classes :
 AbstractBorder : ne fait rien, elle permet d'indiquer les définitions d'une bordure
invisible sans aucune taille.
 BevelBorder : une bordure 3D en surépaisseur ou en creux
 CompoundBorder : composition de plusieurs bordures
 EmptyBorder: permet de fournir une bordure vide et transparente avec espacement sans
les dessinés.
 EtchedBorder: permet d'intégrer une simple bordure gravé.
 LineBorder : permet d'intégrer une ligne de bordure épaisse et d'une simple couleur.
 MatteBorder: permet d'intégrer une bordure de style mat de gravure dans une couleur
solide ou un icône en carreau.
 SoftBevelBorder : permet d'intégrer une bordure en biseau relevé ou abaissé avec
coins adoucis.
 TitledBorder : permet d'intégrer une bordure arbitraire avec un ajout d'un titre en
chaine de caractères dans une position et une justification spécifié.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 76


Bordures des composants Swing (complément)
EtchedBorder
Etched signifie gravé en français,
- soit de l’extérieur: [Link],
- soit de l'intérieur: [Link].

RAISED
Border EtchedBorderRaised =
[Link]([Link]);

LOWERED
Border EtchedBorderLowered =
[Link]([Link]);

RaisedBevelBorder
Crée une bordure sous forme d'un bouton relâché avec des nuances lumineuses et plus sombre pour les
ombres.

Border RaisedBevelBorder = [Link]();

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 77


Bordures des composants Swing (complément)
TitledBorder
TitledBorder a cinq constructeurs, voici un exemple qui englobe tous les paramètres qui
permettent d'ajouter un titre à une bordure avec un style de bordure précis, position, fonte et couleur.
Border LoweredBevelBorder = [Link]();
Border EtchedBorderRaised =
[Link](LoweredBevelBorder, "titre",
[Link],[Link],
new Font("Arial", [Link] , 13), [Link]);

EtchedBorder
Ce style regroupe deux styles en un seul. Par exemple, on veut dessiner une LineBorder à l'intérieur
de RaisedBevelBorder:
Border lineborder = [Link]();
Border RaisedBevelBorder =
[Link]([Link]);
Border EtchedBorderRaised =
[Link](lineborder, RaisedBevelBorder);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 78


Bordures des composants Swing (complément)
LoweredBevelBorder
Crée une bordure sous forme d'un bouton appuyé avec des nuances lumineuses et plus sombre pour les
ombres.

Border LoweredBevelBorder = [Link]();

MatteBorder
Crée une bordure avec 5 paramètres, les 4 premiers traitent la largeur du trait gauche, droit, haut et bas,
et le dernier pour colorer les bords.

Border matteborder = [Link](1, 1, 3, 1,


[Link]);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 79


Bordures des composants Swing (3)
Exemple: BevelBorder : une bordure 3D en surépaisseur ou en creux
import [Link];
import [Link];
import [Link];
import [Link];
public class Bordures0 extends JFrame {
public Bordures0() {
getContentPane().setLayout(new FlowLayout());
JLabel e = new JLabel("[Link]
[Link]([Link]([Link]));//ou LOWERED
add(e);
}
public static void main(String[] args) {
JFrame f = new Bordures0();
[Link]("Bordure en surépaisseur");
[Link](3);
[Link](280, 100);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 80


Bordures des composants Swing (4)
import [Link].*; // Container
import [Link].*; // JLabel, JPanel, JFrame
import [Link];
import [Link];
class Bordures1 extends JFrame {
Bordures1() {
setTitle("1- Bordures avec Swing");
Container f = (Container) getContentPane();
setBounds(10, 10, 300, 100);
JPanel panneau = new JPanel();
[Link](panneau);
JLabel eta = new JLabel("Une étiquette 1"); // JLabel: texte avec bordure
[Link]([Link]());
[Link](eta);
JLabel etb = new JLabel("Une étiquette 2"); // JLabel: texte avec bordure
[Link]([Link]([Link]));
[Link](etb);
setVisible(true);
} // Fin du Constructeur
public static void main(String[] args) {
new Bordures1();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 81
Bordures des composants Swing (5)
class Bordures2 extends JFrame {
Bordures2() {
setTitle("2- Bordures avec Swing");
setDefaultCloseOperation(3);
setBounds(10, 10, 350, 150);
JPanel panneau = new JPanel();
add(panneau);
// JLabel: texte en html + bordure + fond cyan
JLabel etb = new JLabel
("<html>Un texte <br><b>en gras</b>"+"<br><i> et italique</i><u> et souligne</html>");
[Link]([Link]("Texte en html"));
[Link](true); // pour avoir la couleur de fond
[Link]([Link]);
[Link]("survol de l'étiquette"); // l'aide au survol de la souris
[Link](etb);
setVisible(true);
}
public static void main(String[] args) {
new Bordures2();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 82


Bordures des composants Swing (6)
LineBorder: La méthode [Link](Color, int) crée une simple
bordure. Le premier paramètre représente la couleur et le deuxième, la largeur du trait.
Exemple :
import [Link].*; // pour BorderLayout, Color, Dimension
import [Link].*; // pour JFrame, JLabel, JPanel, BorderFactory
import [Link].*; // [Link]

public class Bordures3 extends JPanel{


public Bordures3(){
JFrame f = new JFrame("3- Bordures avec Swing");
JPanel panneau = new JPanel();
JLabel et = new JLabel("LineBorder");
[Link](et);
// créer une bordure de trait vert et largeur minimale 2
Border lineborder = [Link]([Link], 2);
// associer à l'etiquette et
[Link](lineborder);

[Link](panneau);
[Link](300, 100);
[Link](JFrame.EXIT_ON_CLOSE);
[Link](true);
}

public static void main(String[] args) {


new Bordures3();
}
} // [Link], 5

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 83


Gestion des dimensions d'une fenêtre (1)
Nous avons pu fixer la taille de la fenêtre créé, on va essayer d'examiner comment
connaître les dimensions des composants et agir sur elles.
1- Connaître les dimensions de l'écran de l'utilisateur:
La méthode getScreenSize de la classe utilitaire Toolkit (du paquetage
[Link]) fournit les dimensions de l'écran sous la forme d'un objet de type
Dimension (contient 2 champs publiques height et width).
La méthode getScreenSize s'applique à un objet de type Toolkit, contenant
les informations relatives à l'environnement qu'on doit d'abord créer explicitement à l'aide
d'une méthode statique getDefaultToolkit de cette même classe Toolkit.
2- Connaître les dimensions d'un composant:
On peut connaître les dimensions d'un composant quelconque à l'aide de la méthode
getSize, qui fournit un objet de type Dimension.
Dimension dim = getSize();
int largeur = [Link], hauteur = [Link];
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 84
Gestion des dimensions d'une fenêtre (2)
 Pour obtenir dans 2 variables haut et larg les dimensions de l'écran,
depuis n'importe quel point du programme :

Toolkit tk = [Link](); // pour connaitre l'environnement


Dimension dimEcran = [Link](); // pour connaitre les dimensions de l'écran
larg = [Link];
haut = [Link];

 Pour imposer dans le constructeur d'une fenêtre qu'elle ait des dimensions
égales à la moitié de celles de l'écran :
TailleFenetre() {
setTitle("Exemple taille fenêtre");
Toolkit tk = [Link]();
Dimension dimEcran = [Link]();
int larg = [Link];
int haut = [Link];
setSize (larg/2, haut/2); // prendre la moitié de l'écran
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 85


Gestion des dimensions d'une fenêtre (3)
Exemple pour donner une taille à la fenêtre de 1/4 de l'écran :

import [Link];
import [Link];
import [Link];

public class TailleFenetre extends JFrame {


TailleFenetre(){
setTitle("Exemple taille fenêtre");
Toolkit tk = [Link](); // pour connaitre l'environnement
Dimension dimEcran = [Link](); // les dimensions de l'écran
int larg = [Link];
int haut = [Link];
[Link]("Largeur= "+larg+" Hauteur= "+haut);
setSize (larg/4, haut/4); // le quart de mon écran
setVisible(true);
}
public static void main(String[] args) {
new TailleFenetre();
}
}
Mon écran 1 : Largeur = 1024, Hauteur = 600
Mon écran 2 : Largeur = 1280, Hauteur = 800

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 86


Gestion des dimensions d'un composant (1)
Les composants ont une taille fixée automatiquement par le gestionnaire de
placement, nous pouvons la modifier par la méthode setPreferredSize
import [Link].*;
import [Link].*;
class FenetreTailleBoutons extends JFrame {
int NBOUTONS = 4;
JButton bouton[];
public FenetreTailleBoutons() {
setTitle("Modification taille boutons");
setSize(300, 150);
Container contenu = getContentPane();
[Link](new FlowLayout());
bouton = new JButton[NBOUTONS];
for (int i=0; i<NBOUTONS; i++) { // création de 4 boutons
bouton[i] = new JButton("NUMERO: "+(i+1));
[Link](bouton[i]);
}
}
public void setTailleBoutons(int num, int l, int h) {
bouton[num].setPreferredSize(new Dimension(l, h));// choix de la taille
bouton[num].revalidate(); // recalcule les dimensions
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 87


Gestion des dimensions d'un composant (2)
import [Link];
public class TestTailleBoutons {
public static void main (String args[]) {
Scanner in = new Scanner([Link]); // pour la saisie
FenetreTailleBoutons fenetre = new FenetreTailleBoutons();
[Link](true);
int num, l, h;
while(true) {
[Link]("numéro bouton: ");
num = [Link]();
[Link]("largeur bouton: ");
l = [Link]();
[Link]("hauteur bouton: ");
h = [Link]();
[Link](num-1, l, h);
}
}
} Test:
numéro: 3
largeur bouton: 100
hauteur bouton: 50
numéro: ...
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 88
Les composants Swing, (les composants AWT en italique).
Component (setSize, getSize, setCursor) AWT
Label AWT
Container (add, setLayout, remove) AWT
JComponent (setBorder, setToolTipText, setOpaque, setBackground)
JLabel (setText, getText, setIcon, getIcon)
JComboBox (addItem, getSelectedItem)
AbstractButton (setText, setIcon, setPressedIcon,
setSelectedIcon, setMnemonic, isSelected, setEnabled,
addActionListener)
JButton
JToggleButton
JCheckBox
JRadioButton
JMenuItem (setEnabled)
JMenu
JCheckBoxMenuItem

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 89


Les composants Swing, (les composants AWT en italique).
Component (setSize, getSize, setCursor) AWT
Label AWT
Container (add, setLayout, remove) AWT
JComponent (setBorder, setToolTipText, setOpaque, setBackground)
JMenuBar
JPanel
JToolBar
JScrollPane
JTabbedPane
JSplitPane
JTextComponent
JTextField
JTextArea
JEditorPane
JList
JTree
JTable

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 90


Les composants Swing, (les composants AWT en italique).
Component (setSize, getSize, setCursor) AWT
Label AWT
Container (add, setLayout, remove) AWT
Window AWT
Frame AWT
JFrame
Dialog AWT
JDialog
Jwindow

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 91


Interfaces Homme - Machine

Chapitre 2 : Les gestionnaires de placement

SMI - S6
Année universitaire 2017-2018

Prof. M.D. RAHMANI mrahmani@[Link]


Gestionnaire de placement (1)
 Le gestionnaire de placement (Layout Manager) gère le positionnement et le
(re)dimensionnement des composants d’un conteneur.
 Le réagencement des composants dans un conteneur a lieu lors de :
 la modification de la taille du conteneur,
 le changement de la taille ou le déplacement d'un des composants.
 l'ajout, l'affichage, la suppression ou le masquage d'un composant.

 Le comportement d'un gestionnaire de placement est défini par l'interface


[Link], qui spécifie comment un conteneur et un
gestionnaire de placement communiquent.
 L'interface LayoutManager introduit des méthodes pour :
 Demander des informations à propos des tailles des composants que le gestionnaire
de placement gère,
 Prévenir le gestionnaire de placement lorsque des composants sont ajoutés ou enlevés
du conteneur,
 Donner une taille et une position aux composants gérés.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 2
Gestionnaire de placement (2)
 Méthodes concernant la taille des composants :
 Tout composant graphique (classe [Link]) possède plusieurs
méthodes de consultation pour aider le processus de placement.
Chacune de ces méthodes renvoie un objet [Link] décrivant la
taille demandée.
Ces méthodes sont les suivantes :
 public Dimension getPreferredSize() : renvoie la taille souhaitée pour
un composant,
 public Dimension getMinimumSize() : renvoie la plus petite taille
souhaitée pour un composant,
 public Dimension getMaximumSize() : renvoie la plus grande taille
souhaitée pour un composant.
 Ces méthodes sont utilisées par le gestionnaire de placement pour calculer la place et la
taille des composants.
 Selon leur nature, un gestionnaire de placmement peut satisfaire ou ignorer les souhaits
que ces méthodes expriment.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 3
Gestionnaire de placement (3)
 Gestionnaires de placement et conteneurs :
 Les gestionnaires de placement doivent être associés aux conteneurs (classe
[Link]) pour faire leur travail.
 Si un conteneur n'a pas de gestionnaire de placement associé, alors il place les
composants comme indiqué par le programmeur à l'aide des méthodes
setLocation() et setSize() ou setBounds().
 On associe un gestionnaire de placement et un conteneur en appelant la méthode
setLayout(LayoutManager) du conteneur. Par exemple :
JPanel p = new JPanel();
[Link](new BorderLayout());

Remarque : Certains conteneurs, comme [Link], possèdent


un constructeur bien pratique qui prend un gestionnaire de placement
comme argument :
JPanel p = new JPanel(new BorderLayout());

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 4


Gestionnaire de placement (4)
 Tout conteneur possède un gestionnaire de placement par défaut.
 Il est possible d'en changer grâce à la méthode setLayout().

 Les gestionnaires de placement par défaut sont :


 Le BorderLayout pour Window et ses descendants (Frame, Dialog,
JFrame, JWindow)
 Le FlowLayout pour Panel et ses descendants (Applet, JApplet,
JPanel)

 Une fois installé, un gestionnaire de placement fonctionne "tout seul" en


interagissant avec le conteneur, nous n'aurions pas besoin de créer un
objet pour lui associer les méthodes du gestionnaire (exception faite de
CardLayout).
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 5
Gestionnaire de placement (5)
 Les principaux gestionnaires de placement de AWT sont :
 FlowLayout,placer à la suite
 BorderLayout, placer aux 4 point cardinaux
 GridLayout, placer dans une grille
 CardLayout, un composant à la fois
 GridBagLayout, placement complexe

 Certains gestionnaires introduits par swing sont :


 BoxLayout : placer verticalement ou horizontalement,
 GroupLayout : depuis Java 6, placer des groupes de composants en distinguant le
placement vertical et horizontal.

 Important : Nous pouvons les utiliser séparément ou les combiner pour


produire des interfaces flexibles.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 6
Gestionnaire de placement (6)
 Indications de positionnement :

 Quand on ajoute un composant dans un conteneur, on ne donne pas la


position exacte du composant,

 On donne plutôt des indications de positionnement au gestionnaire de


placement :
 explicites ; exemple [Link]
 implicites; définies par l'ordre d'ajout dans le conteneur.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 7


FlowLayout (1)
 Le FlowLayout est le plus simple des gestionnaires de AWT

 Gestionnaire de placement utilisé par défaut dans les Panel et les


descendants si aucun LayoutManager n'est spécifié.

 Un FlowLayout peut spécifier :


 une justification à gauche, à droite ou centrée,
 un espacement horizontal ou vertical entre deux composants.
 Par défaut, les composants sont centrés à l'intérieur de la zone qui leur est
allouée.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 8


FlowLayout (2)
 Principe
 Rajoute les composants au fur et à mesure
 La taille préférée des composants l’emporte
 Pour ce gestionnaire, les tailles minimales et maximales n'ont aucun intérêt.
 Si tous les composants ne peuvent pas tenir dans l'objet Container, certains
composants peuvent ne pas apparaître.

 Alignement des composants


 Lors de la construction d'un gestionnaire FlowLayout, nous pouvons spécifier un
paramètre d'alignement d'une ligne de composants par rapport aux bords verticaux de la
fenêtre
 new FlowLayout ([Link])
 alignement: LEFT, CENTER (valeur par défaut), RIGHT
 Exemple : [Link](new FlowLayout([Link]));
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 9
FlowLayout (3)
Intervalle entre les composants
 Lors de la construction, nous pouvons spécifier une séparation entre les composants
(par défaut, elle est de 5 pixels dans les deux directions) :
 new FlowLayout (int alignement, int hintervalle,int vintervalle)
 alignment: LEFT, CENTER, RIGHT

 hintervalle: L’intervalle horizontal entre les composants


 vintervalle: L’intervalle vertical entre les composants
 Exemple : Les composants centrés avec 10 pixels sur la ligne et 15 pixels entre les lignes,
 [Link](new FlowLayout([Link], 10, 15));

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 10


Exemple 1: FlowLayout (4)
import [Link].*; // pour FlowLayout
import [Link].*;
class Fenetre1 extends JFrame {
public Fenetre1() {
setTitle ("1- Essai FlowLayout");
setSize(300,200);
JButton monBouton = new JButton("Un bouton");
setLayout(new FlowLayout()); // le gestionnaire par défaut est BorderLayout
add(monBouton); // un bouton centré
setDefaultCloseOperation(3); //l e bouton occupe tout l'espace
}
}

public class Essai1FlowLayout {


public static void main(String args[]) {
Fenetre1 f1 = new Fen1Bouton();
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 11


Exemple 2: FlowLayout (5)
Un conteneur portant trois boutons
import [Link].*; // pour FlowLayout
import [Link].*;
class Fenetre2 extends JPanel {
public Fenetre2() {
setLayout(new FlowLayout()); //facultatif pour JPanel
JButton bouton = new JButton("Oui");
add(bouton);
bouton = new JButton("Non");
add(bouton);
bouton = new JButton("Sans avis");
add(bouton);
}
}
public class Essai2FlowLayout {
public static void main(String[] args) {
JFrame f2 = new JFrame("2- Essai FlowLayout");
[Link](3);
[Link](new Fenetre2());
[Link](300, 150);
//[Link](); // pour une taille des boutons, calcul récursif des positions et des tailles
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 12
Exemple 3: FlowLayout (6)
Exemple: Un cas de changement d'intervalles
import [Link].*;
import [Link].*; // pour FlowLayout
class Fenetre3 extends JPanel {
public Fenetre3() {
setLayout(new FlowLayout([Link],10, 15));
add(new JButton("Un"));
add(new JButton("Deux"));
add(new JButton("Trois"));
add(new JButton("Un"));
add(new JButton("Deux"));
add(new JButton("Trois"));
}
}
class Essai3FlowLayout { // par défaut 5x5 pixels
public static void main(String[] args) {
JFrame f3 = new JFrame("3- Essai FlowLayout");
[Link](3);
[Link](new Fentre3());
[Link](250, 150);
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 13
Redimensionnement avec FlowLayout (1)

Redimensionnement

Redimensionnement

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 14


Redimensionnement avec FlowLayout (2)
 Laprésentation FlowLayout positionne les composants ligne par ligne.
Chaque fois qu'une ligne est remplie, une nouvelle ligne est commencée.

 Le gestionnaire FlowLayout n'impose pas la taille des composants mais


leur permet d'avoir la taille qu'ils préfèrent.
 Le FlowLayout cache réellement et effectivement les composants qui ne
rentrent pas dans le cadre.
 L'équivalent vertical du FlowLayout n'existe pas dans la librairie awt ,
pour faire une représentation verticale, on peut utiliser BoxLayout,
fourni par Swing.

 Le FlowLayout n'a d'intérêt que quand il y a peu de composants.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 15


BorderLayout (1)
 BorderLayout divise son espace de travail en cinq zones: NORTH,
SOUTH, EAST, WEST et CENTER.
 Les composants sont ajoutés par nom à ces zones (un seul composant par zone).
 Exemple: NORTH

setLayout(new BorderLayout());
JButton b1 = new JButton("Le bouton Nord"); WEST CENTER EAST
add(b1, [Link]);
 Si une des zones ne contient rien, sa taille est 0. SOUTH

 Espacement entre les régions : Par défaut les composants ne sont pas espacés,
nous pouvons préciser un intervalle particulier au moment de la construction :
Exemple : [Link](new BorderLayout(10,15);
 BorderLayout est le gestionnaire par défaut de JFrame et JDialog

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 16


Exemple 1 : BorderLayout (2)
import [Link].*;
import [Link].*; // pour BorderLayout
class Essai1BorderLayout extends JPanel {
public Essai1BorderLayout() {
setLayout(new BorderLayout());
JButton b1 = new JButton("Nord");
add(b1);
JButton b2 = new JButton("Sud");
add(b2);
JButton b3 = new JButton("Est");
add(b3);
JButton b4 = new JButton("Ouest");
add(b4);
JButton b5 = new JButton("Centre");
add(b5);
}
public static void main(String[] args) {
JFrame f1 = new JFrame("1-Essai BorderLayout");
[Link](3);
[Link](new Essai1BorderLayout());
[Link](300, 150);
[Link](true);
}
}
Remarque : Si nous ne précisons pas la position, seul le dernier composant est visible et occupe toute la fenêtre.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 17
Exemple 2: BorderLayout (3)
import [Link].*;
import [Link].*; // pour BorderLayout
class Essai2BorderLayout extends JPanel {
public Essai2BorderLayout() {
setLayout(new BorderLayout());
//setLayout(new BorderLayout(10, 15));
JButton b1 = new JButton("Nord");
add(b1, [Link]);
JButton b2 = new JButton("Sud");
add(b2, [Link]);
JButton b3 = new JButton("Est");
add(b3, [Link]);
JButton b4 = new JButton("Ouest");
add(b4, [Link]);
JButton b5 = new JButton("Centre");
add(b5, [Link]);
}
public static void main(String[] args) {
JFrame f2 = new JFrame("2-Essai BorderLayout");
[Link](3);
[Link](new Essai2BorderLayout());
[Link](300, 150);
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 18
BorderLayout (4)
 Stratégie de placement du BorderLayout
 S'il y a un composant dans la partie placée dans la partie NORTH, il récupère sa
taille préférée, respecte sa hauteur préférée si possible et fixe sa largeur à la totalité
de la largeur disponible de l'objet Container.
 S'il y a un composant dans la partie placée dans la partie SOUTH, il fait pareil que
dans le cas de la partie NORTH.
 S'il y a un composant dans la partie placée dans la partie EAST, il récupère sa taille
préférée, respecte sa largeur préférée si possible et fixe sa hauteur à la totalité de la
hauteur encore disponible.
 S'il y a un composant dans la partie placée dans la partie WEST, il fait pareil que
dans le cas de la partie EAST.
 S'il y a un composant dans la partie CENTER, il lui donne la place qui reste, s'il en
reste encore.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 19


BorderLayout (5)

Redimensionnement

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 20


Exemple 3: BorderLayout (6)
import [Link].*;
import [Link].*; // pour BorderLayout
class Essai3BorderLayout extends JPanel {
public Essai3BorderLayout() {
setLayout(new BorderLayout());
JLabel etiquette = new JLabel("Nom: ");
add(etiquette, [Link]);
JTextField champNom = new JTextField();
add(champNom, [Link]);
}
public static void main(String[] args) {
JFrame f3 = new JFrame("3-Essai BorderLayout");
[Link](JFrame.EXIT_ON_CLOSE);
[Link](new Essai3BorderLayout());
//[Link](300, 100);
[Link]();
[Link](true);
}
}

Remarque : Si nous agrandissons, l' étiquette "Nom" garde sa valeur préférée, seul le champ de texte change
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 21
Exemple 4: BorderLayout (7)
class Essai4BorderLayout extends JPanel {
public Essai4BorderLayout() {
setLayout(new BorderLayout());
JButton b1 = new JButton("Nord");
add(b1, [Link]);
JButton b2 = new JButton("Ouest");
add(b2, [Link]);
JButton b3 = new JButton("Centre");
add(b3, [Link]);
}
public static void main(String[] args) {
JFrame f4 = new JFrame("4-Essai BorderLayout");
[Link](3);
[Link](new Essai4BorderLayout());
[Link](300, 150);
[Link](true);
}
}

Remarques :
 Il n'est pas obligatoire de placer 5 composants, les emplacements non pourvus sont ignorés.
 Cette interface peut servir pour un éditeur, avec une barre d'outils en haut, l'arborescence des
fichiers et répertoires à gauche et le document au centre.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 22
GridLayout (1)
 Le GridLayout dispose les composants dans une grille.
 Découpage de la zone d'affichage en lignes et en colonnes qui définissent
des cellules de dimensions égales, les tailles minimales et souhaitées sont
ignorées.
 Chaque composant à la même taille
 quand les composants sont ajoutés dans les cellules, le remplissage
s’effectue de gauche à droite et de haut en bas.
 Les 2 paramètres sont les lignes et les colonnes.
 Construction d'un GridLayout : new GridLayout(3,2);
JPanel p = new JPanel();
[Link](new GridLayout(3,2);

Remarque : Une meilleure manière de spécifier les lignes et les colonnes d'un
GridLayout est de toujours mettre l'un des deux à zéro. Une valeur nulle pour
ligne ou colonnes signifie "n'importe quel nombre de".
N.B. On ne peut pas spécifier zéro pour les deux.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 23
GridLayout (2)
Exemple 1
import [Link].*;
import [Link].*;
class Essai1GridLayout extends JPanel{
Essai1GridLayout() {
setLayout(new GridLayout(3,2));
//setLayout(new GridLayout(3,2,5,10)); espacées 5x10 pixels
for (int i = 1; i < 7; i++)
add(new Button([Link](i)));
}
public static void main(String args[]){
JFrame f1 = new JFrame("1- Essai GridLayout");
[Link](3);
[Link](new Essai1GridLayout());
[Link]();
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 24
GridLayout (3)
Exemple 2: 5 boutons au lieu de 6, une case sera vide.

import [Link].*;
import [Link].*;
class Essai2GridLayout extends JPanel{
Essai2GridLayout() {
setLayout(new GridLayout(3,2));
for (int i = 1; i < 6; i++)
add(new Button([Link](i)));
}
public static void main(String args[]){
JFrame f2 = new JFrame("2- Essai GridLayout");
[Link](3);
[Link](new Essai2GridLayout());
[Link]();
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 25


GridLayout (4)
 Lors d’un redimensionnement, les composants
changent tous de taille mais leurs positions relatives
ne changent pas.

Redimensionnement

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 26


CardLayout (1)
 Le CardLayout n'affiche qu'un composant à la fois :
 les composants sont considérés comme empilés, à la façon d'un tas de
cartes.
 Usage typique pour les onglets

 La présentation CardLayout permet à plusieurs composants de


partager le même espace d'affichage de telle sorte que seul l'un d'entre
eux soit visible à la fois.

 Pour passer de l’affichage d’un composant à un autre on appelle les


méthodes first, last, next, previous ou show
 Nous allons le reprendre avec la gestion des événements.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 27


CardLayout (2)
import [Link].*;
import [Link].*;
public class EssaiCardLayout extends JFrame {
public EssaiCardLayout() {
[Link]("Fenêtre avec CardLayout");
JButton b1 = new JButton("Afficher Carte 2");
JButton b2 = new JButton("Afficher Carte 1");
JTextField t1 = new JTextField("Carte 1");
JTextField t2 = new JTextField("Carte 2");
JPanel Cartes = new JPanel();
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
[Link](new CardLayout());
[Link](b1);
[Link](t1);
[Link](p1);
[Link](b2); Après chaque clic, on passe à l'autre panneau !!
[Link](t2);
[Link](p2);
add(Cartes);
}
static public void main(String[] args) {
EssaiCardLayout f = new EssaiCardLayout();
[Link](300,100);
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 28
BoxLayout ([Link])
 Le BoxLayout ([Link])
 C'est le gestionnaire par défaut du conteneur Box qui est un conteneur swing
(Box et non Jbox !).
 Les composants sont placés horizontalement, dans une ligne de gauche à
droite, ou verticalement dans une colonne de haut vers le bas.
Exemple:
[Link](new BoxLayout(panneau, BoxLayout.Y_AXIS));

[Link](Component.CENTER_ALIGNMENT);

[Link](bouton);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 29


BoxLayout ([Link]) (2)
 Le BoxLayout ([Link]):
import [Link].*;
public class EssaiBoxLayout extends JFrame {
private ButtonGroup boutons = new ButtonGroup();
private JRadioButton dhs = new JRadioButton(" Dirhams ", true);
private JRadioButton euros = new JRadioButton(" Euros ");
public EssaiBoxLayout() {
setTitle("Fenêtre avec BoxLayout");
setLayout(new BoxLayout(getContentPane(), BoxLayout.X_AXIS));
add(new JTextField(10));
[Link](dhs);
[Link](euros);
add(dhs);
add(euros);
add(new JButton(" Conversion ");
add(new Jlabel(" 0 Dirhams");
pack();
setDefaultCloseOperation(3);
setVisible(true);
}
public static void main(String[] args) {
new EssaiBoxLayout();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 30
Exemple récapitulatif: FlowLayout (1)
/* Même exemple avec plusieurs gestionnaires de placement */
import [Link];
import [Link].*;
public class F_FlowLayout extends JFrame {
JButton nord = new JButton("Nord");
JButton ouest = new JButton("Ouest");
JButton sud = new JButton("Sud");
JButton centre = new JButton("Centre");
JButton est = new JButton("Est");
JPanel panneau = new JPanel(); // FlowLayout par défaut
public F_FlowLayout() {
setTitle("Fenêtre avec FlowLayout");
setSize(300, 200);
setDefaultCloseOperation(3);
[Link](nord);
[Link](ouest);
[Link](sud);
[Link](centre);
[Link](est);
add(panneau);
setVisible(true);
}
public static void main(String[] args) {
new F_FlowLayout();
}
} Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 31
Exemple récapitulatif: BorderLayout (2)
/* Même exemple avec plusieurs gestionnaires de placement */
import [Link];
import [Link].*;
public class F_BorderLayout extends JFrame {
JButton nord = new JButton("Nord");
JButton ouest = new JButton("Ouest");
JButton sud = new JButton("Sud");
JButton centre = new JButton("Centre");
JButton est = new JButton("Est");
public F_BorderLayout() {
setTitle("Fenêtre avec BorderLayout");
setSize(300, 200);
setDefaultCloseOperation(3);
add(nord, [Link]);
add(ouest, [Link]);
add(sud, [Link]);
add(centre, [Link]);
add(est, [Link]);
setVisible(true);
}
public static void main(String[] args) {
new F_BorderLayout();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 32
Exemple récapitulatif: GridLayout (3)
/* Même exemple avec plusieurs gestionnaires de placement */
import [Link];
import [Link].*;
public class F_GridLayout extends JFrame {
JButton nord = new JButton("Nord");
JButton ouest = new JButton("Ouest");
JButton sud = new JButton("Sud");
JButton centre = new JButton("Centre");
JButton est = new JButton("Est");
public F_GridLayout() {
setTitle("Fenêtre avec GridLayout");
setSize(300, 200);
setDefaultCloseOperation(3);
setLayout(new GridLayout(3,2));
add(nord);
add(ouest);
add(sud);
add(centre);
add(est);
setVisible(true);
}
public static void main(String[] args) {
new F_GridLayout();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 33
Exemple récapitulatif: CardLayout (4)
/* Même exemple avec plusieurs gestionnaires de placement */
import [Link];
import [Link].*;
public class F_CardLayout extends JFrame {

JButton nord = new JButton("Nord");


JButton ouest = new JButton("Ouest");
JButton sud = new JButton("Sud");
JButton centre = new JButton("Centre");
JButton est = new JButton("Est");
public F_CardLayout() {
setTitle("Fenêtre avecCardLayout");
setSize(300, 200);
setDefaultCloseOperation(3);
setLayout(new CardLayout());
add(nord);
add(ouest);
add(sud);
add(centre);
add(est);
setVisible(true);
}
public static void main(String[] args) {
new F_CardLayout();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 34
Exemple récapitulatif: BoxLayout (5)
/* Même exemple avec plusieurs gestionnaires de placement */
import [Link].*;
import [Link].*;
public class F_BoxLayout extends JFrame {

JButton nord = new JButton("Nord");


JButton ouest = new JButton("Ouest");
JButton sud = new JButton("Sud");
JButton centre = new JButton("Centre");
JButton est = new JButton("Est");
public F_BoxLayout() {
setTitle("Fenêtre avec BoxLayout");
setSize(300, 200);
setDefaultCloseOperation(3);
setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
add(nord);
add(ouest);
add(sud);
add(centre);
add(est);
setVisible(true);
}
public static void main(String[] args) {
new F_BoxLayout();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 35
GridBagLayout (1)
 Le gestionnaire GridBagLayout fournit des fonctions de présentation
complexes
 basées sur une grille dont les lignes et les colonnes sont de taille variables.
 permet à des composants simples de prendre leur taille préférée au sein
d'une cellule, au lieu de remplir toute la cellule.
 permet aussi l'extension d'un même composant sur plusieurs cellules.

 Le GridBagLayout est compliqué à gérer.


 Dans la plupart des cas, il est possible d’éviter de l’utiliser en le remplaçant
par des conteneurs imbriqués avec des gestionnaires de placement
différents.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 36


GridBagLayout (2)

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 37


D’autres gestionnaires?
 On peut imposer à un container de ne pas avoir de gestionnaire en fixant
LayoutManager à la valeur null

 JFrame f = new JFrame();

[Link](null);

 A la charge alors du programmeur de positionner chacun des


composants, manuellement, en indiquant leur position absolue dans le repère de
la fenêtre.

 C’est à éviter, sauf dans des cas particuliers,.

 Il est possible d’écrire ses propres Gestionnaires de


placement…
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 38
Mise en forme complexe : utilisation de plusieurs
gestionnaires de placement
super("AppliComplexeLayout");
setLayout(new BorderLayout());

JPanel pnorth = new JPanel();


[Link](new FlowLayout());
[Link](B1); [Link](B2);
[Link](B3); [Link](B4);
[Link](pnorth,[Link]);

JPanel pcenter = new JPanel();


[Link](new GridLayout(2,2));
[Link](GR1); [Link](GR2);
[Link](GR3); [Link](GR4);
[Link](pcenter,[Link]);

JPanel psouth = new JPanel();


[Link](new FlowLayout());
[Link](jl); [Link](jtf);
[Link](psouth, [Link]);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 39


Arborescence de conteneurs
 Construction d'une interface par imbrication de conteneurs :
On peut élaborer une arborescence de composants à l'aide de
conteneurs pour obtenir l'interface souhaitée.
Exemple :
[Link](composantTexte);
Ma fenêtre [Link](bouton1);
[Link](bouton2);
Composant bouton 1 [Link](panneauGauche);
pour affichage [Link](panneauDroit);
d'un texte bouton 2 [Link](grandPanneau);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 40


Arbre d'imbrication
 Construction d'une interface par imbrication de conteneurs :
On peut associer un gestionnaire à chaque conteneur intermédiaire.
Exemple :

Ma fenêtre Type de conteneur


Gestionnaire de placement
Composant bouton 1 contrainte contrainte

pour affichage
d'un texte bouton 2 Type de conteneur Type de conteneur
Gestionnaire de placement Gestionnaire de placement

composant composant composant

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 41


Récapitulatif
 FlowLayout: un flux de composants placés les uns derrière les autres

 BorderLayout: ecran découpé en 5 zones (North, West,


South, East, Center)

 GridLayout: grille, une case par composant, chaque case de la même


taille

 CardLayout: onglets : on affiche un élément à la fois

 BoxLayout: un flux de composants placés les uns derrière les autres,


verticalement ou horizontalement

 GridBagLayout: une grille complexe, plusieurs cases par composant


Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 42
Interfaces Homme - Machine
Chapitre 3: Composants du texte
Boîtes de dialogue

SMI - S6
Année universitaire 2017-2018

Prof. M.D. RAHMANI


mrahmani@[Link]
Plan:
 Composants du texte :
◦ La classe JTextComponent
◦ Méthodes communes des composants du texte
◦ La classe JTextField
◦ La classe JTextArea
◦ La classe JPasswordField
◦ La classe JFormattedTextField
◦ Les classes JEditorPane et JTextPane
 Boîtes de dialogue :
◦ La classe JOptionPane
 Dialogue de message
 Dialogue de confirmation
 Dialogue de saisie
 Dialogue personnalisé
◦ La classe JDialog
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 2
Composants du Texte
On peut définir des zones de texte modifiables ou non modifiables
par l'utilisateur.
 La zone de texte la plus simple est l'affichage d'une ligne non modifiable
par l'utilisateur : cela peut être réalisé par une instance de la classe
[Link].
 Pour avoir une ligne modifiable par l'utilisateur, on utilise une instance
de la classe [Link].
 Pour avoir une zone de texte sur plusieurs lignes, on utilise une instance
de la classe [Link]. Une telle zone peut posséder des
ascenseurs. La police de caractères est la même dans toute la zone de
texte.
 Les classes [Link] et [Link]
permettent de faire des zones de texte plus complexes, incluant différents
styles et des images.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 3
La classe abstraite JTextComponent (1)
La classe abstraite JTextComponent fait partie du paquetage
[Link] et a les sous-classes dédiées suivantes :
 JTextField : saisie d'un texte sur une ligne.
 JPasswrodField : spécialisée pour la saisie d'un mot de passe, le texte saisi est
remplacé, par défaut, par des astérisques.
 JFormattedTextField : pour la saisie d'une valeur numérique ou une date.
 JTextArea : un texte sur plusieurs lignes.
 JEditorPane : permet l'édition et l'affichage d'un texte formaté comme un
document RTF ou HTML, en conjonction avec les classes des paquetages
[Link] et [Link].
 JTextPane hérite de JEditorPane propose des fonctionnalités supplémentaires
comme l'affichage de plusieurs polices et plusieurs styles dans le même document,
l'incorporation d'images, etc...
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 4
La classe abstraite JTextComponent (2)
 Arborescence des classes dédiées à la gestion du texte:

JComponent

JTextComponent

JTextArea JTextField JEditorPane

JPasswordField JFormattedField JTextPane

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 5


Composants du Texte: méthodes communes
 Modification ou récupération du texte
◦ void setText("le texte");
◦ String getText(); String getText(int début, int nbcar);

 Copier, Couper / Coller


◦ void copy() ou void cut()
◦ void paste();

 Interdire ou autoriser la saisie


◦ void setEditable(false ou true);

 Récupérer ou changer la couleur de la sélection (le fond ).


◦ Color getSelectionColor();
◦ void setSelectionColor(Color couleur);

 Gestion des marges intérieures de la zone de texte,


◦ Insets getMargin()
◦ [Link](new Insets(haut, gauche, bas, droit));

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 6


La classe JTextField (1)
 Usage : Un champs d'une seule ligne de saisie de texte
 Création d’un JTextField
◦ JTextField tf = new JTextField();
◦ JTextField tf = new JTextField("un texte");
◦ JTextField tf = new JTextField(20);// crée un champ de 20 colonnes
 Modification du texte
◦ [Link]("le texte");
 Récupérer le texte
◦ [Link]();
 Copier, Couper et Coller
◦ [Link]()ou [Link]()
◦ [Link]();
 Interdire saisie
◦ [Link](false);
 Récupère ou change la couleur de fond d'un texte sélectionné
◦ [Link]()
◦ [Link]([Link])
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 7
La classe JTextField (2)
Les méthodes propres à la classe JTextField
 Spécification de la fonte du texte à afficher
◦ [Link]();
 Spécification du nombre de caractères dans le texte
◦ [Link]();

 Exemple d'un constructeur qui propose un texte par défaut avec un


nombre souhaité de colonnes :

◦ JTextField tf = new JTextField("Introduisez votre texte", 20);

Remarque : le gestionnaire de placement peut bien ignorer le nombre préféré de


caractères.

 On peut supprimer un texte récupéré par getText() :


◦ String texte = [Link]().trim();

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 8


La classe JTextField (3)
Exemple 1 avec JTextField :

class ChampTexte1 extends JFrame {

public ChampTexte1() {
setTitle("Texte 1");
JTextField copie = new JTextField("Entrez votre nom",50);
//getContentPane().add([Link],copie) ;
add([Link],copie) ; // BorderLayout par défaut
setDefaultCloseOperation(3);
setSize (250, 100) ;
setVisible(true) ;
}

public static void main (String args[]){


new ChampTexte1() ;
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 9


La classe JTextField (4)
Exemple 2 : avec JTextField :
class ChampTexte2 extends JFrame {
public ChampTexte2() {
setTitle("Saisie des coordonnées");
JPanel panneau = new JPanel();
[Link](new BoxLayout(panneau, BoxLayout.Y_AXIS)); // vertical, à gauche
JLabel eNom = new JLabel("Nom:");
[Link](eNom);
JTextField tNom = new JTextField(30); // a le focus
[Link](tNom);
JLabel ePrenom = new JLabel("Prénom:");
[Link](ePrenom);
JTextField tPrenom = new JTextField(30);
[Link](tPrenom);
JButton bouton = new JButton("Valider");
[Link](bouton);
add(panneau);
setDefaultCloseOperation(3);
pack();
setVisible(true) ;
}
public static void main (String args[]){
new ChampTexte2() ;
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 10
La classe JTextArea (1)
 Usage : Un champs de plusieurs lignes de saisie de texte
 Création d’un JTextArea
◦ JTextArea ta = new JTextArea(3, 20); // 3 lignes et 20 colonnes
Remarque : Les valeurs données n'indiquent qu'une préférence, le
gestionnaire de placement peut toujours agrandir ou réduire la zone de texte.

 Retour automatique à la ligne: pour éviter que des longues lignes


ne soient tronquées, on active le retour automatique à la ligne avec la méthode
setLineWrap() :
◦ [Link](true); // saut de ligne automatique

 Barre de défilement: Une zone de texte ne dispose pas de barres de


défilement. Il faut mettre la zone de texte dans un panneau avec barre de
défilement JScrollPane :
◦ JTextArea ta=new JTextArea(8, 40); // 8 lignes de 40 colonnes chacune
◦ JScrollPane ascenceur = new JScrollPane(ta);
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 11
La classe JTextArea (2)
Exemple 1 avec JTextArea :

class ChampTextArea1 extends JFrame {

public ChampTextArea1() {
setTitle("Texte Area 1");
JTextArea monTexte = new JTextArea();
[Link]("La meilleure des hypothèses n'est pas celle qui se rapproche le mieux de la
complexité du réel, mais celle qui tout en restant simple, a le pouvoir d'explication et de prévision le
plus large possible.\n");
[Link](false); // interdire le changement du texte, par défaut true
[Link](true); // pour un passage à la ligne automatique
add(monTexte);
setDefaultCloseOperation(3);
setSize(300,200) ;
setVisible(true) ;
}

public static void main (String args[]){


new ChampTextArea1() ;
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 12
La classe JTextArea (3)
Remarque :

Il est prudent d'insérer systématiquement les composants JTextArea


dans des conteneurs JScrollPane de telle sorte que des barres de
défilement apparaissent lorsque cela s'avère nécessaire (suite au
redimensionnement de la fenêtre englobante ou si le texte déborde de la
zone prévue).

JTextArea ta = new JTextArea("texte.....");


JScrollPane zoneDefilement = new JScrollPane(ta);
[Link](zoneDefilement);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 13


La classe JTextArea (4)
Exemple 2 avec JTextArea :
import [Link].*;
public class ChampTextArea2 extends JFrame {
ChampTextArea2() {
setTitle("Exemple ave défilement");
JPanel panneau = new JPanel();
JTextArea ta = new JTextArea(contenu, 6, 16);
[Link](true);
[Link](new JScrollPane(ta));
add(panneau);
setDefaultCloseOperation(3);
setSize(350, 200);
setVisible(true);
}

static String contenu = "La meilleure des hypothèses n'est pas celle qui se rapproche le mieux de
la complexité du réel mais celle qui tout en restant simple a le pouvoir
d'explication et de prévision le plus large possible";
public static void main(String[] args) {
new ChampTextArea2();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 14
La classe JPasswordField (1)
 Usage : Une sous classe de JTextField pour saisir un mot de passe ou
des données sensibles.
 Création d’un JPasswordField
◦ JPasswordField pf = new JPasswordField();

 Un caractère d'écho est utilisé à la place, généralement un astérisque (*).


La méthode setEchoChar() permet de choisir le caractère d'écho à faire
apparaître à la place des caractères entrés par l'utilisateur.
◦ setEchoChar('#'); // permet de mettre '#' à la place de '*'

 Pour récupérer le texte saisi, on utilise la méthode : getPassword()


plutôt que getText().

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 15


La classe JPasswordField (2)
Exemple 1 : Création d'un champ pour un mot de passe
import [Link].*;
public class MotDePasse1 extends JFrame {
MotDePasse1() {
setTitle("Zone de mot de passe");
Jpanel panneau = new JPanel();
JPasswordField motDePasse1 =
new JPasswordField("Mon mot de passe",20);
[Link]('#');
[Link](motDePasse1);
add(panneau);
setDefaultCloseOperation(3);
setSize(300, 100);
setVisible(true);
}
public static void main(String[] args) {
new MotDePasse1();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 16
La classe JPasswordField (3)
Exemple 2 : Création de plusieurs champs pour mots de passe
public class MotDePasse2 extends JFrame{
MotDePasse2(){
setTitle("Exemples de Mot de Passe");
JPanel p = new JPanel();
[Link](new GridLayout(4,2));
[Link]([Link]("Mots de passe"));
JLabel l1 = new JLabel("Type 1"); JLabel l2 = new JLabel("Type 2");
JLabel l3 = new JLabel("Type 3"); JLabel l4 = new JLabel("Type 4");
JPasswordField t1 = new JPasswordField(10);
JPasswordField t2 = new JPasswordField(2);
JPasswordField t3 = new JPasswordField(" 175cm");
JPasswordField t4 = new JPasswordField("Mot de passe",10);
[Link]('#'); [Link]('%');
[Link]('&'); [Link]('M');
[Link](l1); [Link](t1);
[Link](l2); [Link](t2);
[Link](l3); [Link](t3);
[Link](l4); [Link](t4);
add(p);
setSize(350, 150);
setVisible(true);
setDefaultCloseOperation(3);
}
public static void main(String args[]) {
new MotDePasse2();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 17
La classe JFormattedTextField (1)
 Usage : Un champs de mise en forme d'un texte, pour les nombres, les
dates, les adresses IP,...
Il gère des types tels que Integer et Date.

 Création d’un JFormattedTextField


◦ JFormattedTextField ftf = new JFormattedTextField();

 Le format se fait par les méthode setValue() et getValue() :


◦ [Link](new Date()); setValue(new Integer(21)); //
◦ [Link](); //

 Utilisation de MaskFormatter pour formater un numéro de téléphone:


◦ MaskFormater mftf = null;
try { mftf =new MaskFormatter("(+212) 0#.##.##.##.##"); }
catch (PArseException e) { [Link](" Erreur");
[Link](); }
JFormattedTextField tf = new JFromattedTextField(mftf);
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 18
La classe JFormattedTextField (2)
 Création d’un champ en format entier :
◦ JFormattedTextField champEntier =
new JFormattedTextField([Link]());
◦ JFormattedTextField champEntier =
new JFormattedTextField(21);

 Proposer une valeur par défaut :


◦ [Link](21);
 Les différents formats de Date :
◦ JFormattedTextField date = new
JFormattedTextField([Link]([Link]));
// court 25/02/2016
◦ /JFormattedTextField date = new
JFormattedTextField([Link]());
//moyen par défaut 25 Février 2016
◦ JFormattedTextField date = new
JFormattedTextField([Link]([Link]));
// complet jeudi 25 février 2016
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 19
La classe JFormattedTextField (3)
 Exemple :
public class TexteFormate1 extends JFrame {
SimpleDateFormat formatDate = new SimpleDateFormat("dd/MM/yyyy");
JFormattedTextField anniversaire = new JFormattedTextField(formatDate);
JFormattedTextField age = new
JFormattedTextField([Link]());
JFormattedTextField telephone;
Box groupe = [Link]();
TexteFormate1() throws ParseException {
new JFrame();
setSize(300, 150);
[Link](new JLabel("Date anniversaire :"));
[Link](new Date());
[Link](anniversaire);
[Link](new JLabel("Âge : "));
[Link](new Integer(21));
[Link](age);
[Link](new JLabel("Téléphone :"));
telephone = new JFormattedTextField(new
MaskFormatter("0#.##.##.##.##"));
[Link]("[Link].08");
[Link](telephone);
add(groupe);
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 20
La classe JFormattedTextField (3)
 Exemple :
Date date = (Date)[Link]();
Number nombre = (Number)[Link]();
int age = [Link]();
String telephone = (String)[Link]();
setTitle("Texte Formaté");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}

public static void main(String[] args) throws ParseException {


new TexteFormate1(); }
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 21


La classe JEditorPane
Cette classe permet d'afficher des pages plus complexes, plus riches
comme les formats RTF ou HTML.
JEditorPane permet de gérer l'affichage web par la méthode setPage:
JEditorPane epTexte = new JEditorPane();
[Link](false);
[Link]([Link]

Pour assigner un style à un document, on a la méthode :


setEditorKit
Elle nécessite un composant StyleEditorKit, 2 styles sont
prédéfinis:
HTMLEditorKit : pour les documents HTML
RTFEditorKit : pour les documents RTF
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 22
La classe JTextPane
C'est une sous classe de JEditorPane, qui propose des méthodes
d'affectation de style (gras, italique,...) dans le document à l'aide de :

StyleConstants et SimpleAttributeSet.
[Link]([Link]

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 23


Les boîtes de dialogue (1)
Une boîte de dialogue sert à afficher un message ou à obtenir des
informations de l'utilisateur.
Types de boites de dialogue
 Il est possible de créer des boites de dialogue « standard » à partir des
classes suivantes :
 JOptionPane
 JColorChooser
 JFileChooser
 ProgressMonitor
 Il est possible de créer des boites de dialogue personnalisées à partir de
la classe suivante :
 JDialog

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 24


Les boîtes de dialogue (2)
Elle peut être crée de 2 manières:
1- Création standard à l'aide de la classe JOptionPane, en faisant
appel à une méthode statique telle que:
[Link]
Les dialogues affichés à l'aide des méthodes showXxxDialog de la
classe JOptionPane sont tous de type modaux.
2- Création d'une boîte de dialogue personnalisée et plus élaborée à
l'aide de la classe JDialog.
Les boîtes crées par cette méthode peuvent être modales ou non.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 25


La classe JOptionPane(1)
La classe JOptionPane, permet de créer une fenêtre de dialogue
(fenêtre séparée), qui est un conteneur de haut niveau de type JDialog
pour afficher les informations et recevoir les réponses de l'utilisateur.
Les méthodes statiques [Link] réalisent les
opérations suivantes:
o création de l'objet boîte de dialogue,
o affichage,
o gestion du dialogue avec l'utilisateur,
o fermeture de la boîte de dialogue,
o transfert éventuel d’informations.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 26


La classe JOptionPane(2)
 Nous avons 3 types de boîtes de dialogues que nous pouvons créer en
utilisant 3 méthodes différentes de la classe JOptionPane :
◦ Les boîtes de messages obtenues par l'invocation de la méthode
showMessageDialog
◦ Les boîtes de confirmation obtenues par l'invocation de la méthode
showConfirmDialog
◦ Les boîtes de saisie obtenues par l'invocation de la méthode
showInputDialog

 Une boîte personnalisable, permettant plusieurs options, obtenue par


l'invocation de la méthode showOptionDialog

Remarque: la fenêtre devient invisible après le choix de l’utilisateur.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 27


La classe JOptionPane(3)
Exemple d'utilisation :
Les méthodes d'affichage de la a classe JOptionPane sont
statiques, il n'est donc pas nécessaire d'instancier une classe pour les
utiliser.
Pour afficher un message on utilise la méthode showMessageDialog
de la classe JOptionPane.
[Link](fenetre, "un message");
fenetre est le composant parent, souvent c'est la fenêtre principale.
[Link](fenetre, "Problème de connexion",
JOptionPane.WARNING_MESSAGE);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 28


La classe JOptionPane(4)
Icônes prédéfinies sur une boite :
Un paramètre type de message permet de sélectionner une icône.
Les valeurs possibles sont :
 ERROR_MESSAGE
 INFORMATION_MESSAGE
 WARNING_MESSAGE
 QUESTION_MESSAGE
 PLAIN_MESSAGE
Valeurs de retour d’une boite :
Les valeurs de retour possibles pour une boite sont :
 YES_OPTION
 NO_OPTION
 OK_OPTION
 CANCEL_OPTION
 CLOSED_OPTION

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 29


Dialogue de message: showMessageDialog(1)

La méthode showMessageDialog informe l'utilisateur en affichant


un texte simple et un bouton de confirmation.
Cette méthode propose plusieurs options.
On peut afficher un icône correspondant au message (point
d'exclamation, information, ...);
La boîte de dialogue reste affichée tant que l'utilisateur n'a pas cliqué sur
le bouton et bloque l'application en cours.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 30


Dialogue de message: showMessageDialog(2)
Exemple 1 : affichage d'un message d'information simple
import [Link].* ;
class MaFenetre extends JFrame {
MaFenetre () {
setTitle ("Essai message 1") ;
setSize (400, 150) ;
}
}

public class Message1 {


public static void main (String args[]) {
MaFenetre f = new MaFenetre() ;
[Link](3);
[Link](true) ;
[Link] ("avant message") ;
[Link](f, "Bonjour, Message 1");
[Link] ("après message") ;
}
}

Remarques : - f est le composant parent, qui peut être la fenêtre principale de l'application.
- La boîte de dialogue est positionnée au milieu de cette fenêtre
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 31
Dialogue de message: showMessageDialog(3)
Exemple 2 : affichage d'un dialogue d'avertissement :
On peur modifier l'aspect en fonction du type de message

import [Link].* ;
public class Message2 {
public static void main (String args[]) {
JFrame f = new JFrame();
[Link]("Avertissement!");
[Link](300, 200, 500, 250);
[Link](true) ;
[Link] ("avant message") ;
[Link](f, "Problème de connexion !",
"Connexion impossible", JOptionPane.WARNING_MESSAGE);
[Link] ("après message") ;
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 32
Dialogue de confirmation: showConfirmDialog(1)

La méthode showConfirmDialog demande un renseignement à


l'utilisateur en attente d'une réponse par oui ou non.
Cette méthode affiche un texte simple et 2 boutons 'YES', 'NO'.
Sans paramètres, elle ajoute un bouton 'CANCEL' pour annuler la
question.
[Link](fenetre, "Donnez une réponse ?");
On peut personnaliser la boîte de dialogue, en donnant par exemple un
titre et uniquement 2 boutons 'YES' et 'NO'.
[Link](fenetre, "Aimez vous la Pizza ?",
"Choix d'un plat", JOptionPane.YES_NO_OPTION);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 33


Dialogue de confirmation: showConfirmDialog(2)
Exemple 1 : Dialogue de confirmation sans paramètre

import [Link].* ;
public class Confirmation1 {
public static void main (String args[]) {
while (true) {
int rep = [Link](null, "voulez-vous continuer ?");
[Link] ("réponse : " + rep);
}
}
}
Clic oui: réponse 0
Clic non: 1
Clic annuler 2
Clic sur le bouton X: -1

Remarque : Pas de logo Java car la boîte n'a pas de parent JFrame (null).

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 34


Dialogue de confirmation: showConfirmDialog(3)
Exemple 2 : Dialogue de confirmation avec paramètres
import [Link].* ;
public class Confirmation2 {
public static void main (String args[]) {
int rep = [Link](null, "aimez vous la pizza ?",
"Choix d'un plat", JOptionPane.YES_NO_OPTION);
if(rep==JOptionPane.YES_OPTION) {
[Link] ("On vous sert une pizza, bonne appétit !");
}
if(rep==JOptionPane.NO_OPTION) {
[Link] ("On vous sert une chawarma, bonne appétit !");
}
}
}

Console:
On vous sert une pizza, bonne appétit !
On vous sert une chawarma, bonne appétit !
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 35
Dialogue de saisie: showInputDialog(1)
La méthode showInputDialog affiche une boîte de dialogue
constituée d'une zone de texte (JTextField) et des boutons de validation.
La méthode retourne une chaîne de caractère (String) si l'utilisateur a
clique sur OK, sinon elle renvoie null.

[Link](fenetre, "Donnez votre nom: ");


On peut personnaliser la boîte de dialogue, en donnant par exemple un
titre.
[Link](fenetre, "Donnez vote nom: ",
"Identité", JOptionPane.INFORMATION_MESSAGE);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 36


Dialogue de saisie: showInputDialog(2)
Exemple 1 : Boite de saisie standard
import [Link].* ;
public class Saisie1 {
public static void main (String args[]) {
String txt ;
while (true) {
txt = [Link] (null, "Donnez un texte") ;
if (txt == null) [Link] ("pas de texte saisi") ;
else [Link] ("texte saisi : " + txt + " de longueur " + [Link]()) ;
}
}
}
Console :
Bouton OK
texte saisi : Cours IHM pour SMI S6 de longueur 21
Bouton Annuler
pas de texte saisi

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 37


Dialogue de saisie: showInputDialog(3)
Exemple 2 : Boîte de saisie personnalisée
import [Link].* ;
public class Saisie2 {
public static void main (String args[]) {
String nom ;
while (true) {
nom = [Link] (null, "Entrez votre nom",
"Identification", JOptionPane.INFORMATION_MESSAGE) ;
if (nom == null) [Link] ("pas de nom saisi") ;
else [Link] ("votre nom est : " + nom ) ;
}
}
} Console :
Bouton OK
votre nom est : Bennani Ali
Bouton Annuler
pas de nom saisi

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 38


Boite de dialogue personnalisée: showOptionDialog(1)
Pour concevoir des boîtes de dialogues personnalisées, nous utilisons la
méthode showOptionDialogue.
Cette méthode admet 8 paramètres (certains peuvent être null).
Elle renvoie un entier qui correspond au bouton cliqué.
showOptionDialog(Component parentComponent, Object message,
String title, int optionType, int messageType,
Icon icon, Object[] options, Object initialValue);

 parentComponent : la fenêtre parente de la boîte de dialogue,


 message : un ou plusieurs messages à afficher s'il s'agit d'un tableau,
 title : le titre de la fenêtre,
 optionType : variables pour configurer les boutons,
 messageType : permet l'affichage d'une icône prédéfinie dans la classe JOptionPane.
 icon : cette variable nous permet de choisir une icone propre.
 options : une variable pour configurer diverses options.
 initialValue : permet de définir des valeurs par défaut pour les différents champs.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 39


Boite de dialogue personnalisée: showOptionDialog(2)
Exemple : Une boîte de dialogue personnalisée avec 3 étiquettes et 2 champs de texte.
import [Link].* ;
public class DPersonnalisee1 {
public static void main (String args[]) {
JLabel eCoordonnees = new JLabel("Entrez votre nom et prénom");
JLabel eNom = new JLabel("Nom : ");
JLabel ePrenom = new JLabel("Prenom : ");
JTextField tNom = new JTextField();
JTextField tPrenom = new JTextField();
Object[] tableau = new Object[]{eCoordonnees, eNom, tNom, ePrenom, tPrenom};
JFrame f = new JFrame();
int reponse = [Link](f, tableau,
"Saisie des Nom et Prénom", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE, null, null, null);
new DPersonnalisee1();
if (reponse == JOptionPane.OK_OPTION) {
[Link] ("Nom : "+[Link]()+ " Prénom: "+[Link]()) ;
}
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 40
Boite de dialogue personnalisée: showOptionDialog(3)
Exemple : Une boîte de dialogue personnalisée avec 3 étiquettes et 2 champs de texte.

Console :
Nom : Bennani Prénom : Lina

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 41


Boîte de dialogue personnalisée: JDialog (1)
 Construction:
Supposons que fenetre est un objet conteneur de type JFrame,
JDialog bd = new JDialog (fenetre, // fenêtre parente
"Boîte de dialogue", // titre de la boîte
true); // boîte modale, false pour non modale
 Affichage:
Comme c'est le cas d'une fenêtre de type JFrame, une boîte de dialogue
doit avoir une taille (avec setSize ou setBounds) et la rendre visible
avec setVisible:
[Link](true); // affiche la boîte de dialogue

 Le gestionnaire par défaut est BorderLayout.

 Remarque: Si la boîte est modale, l'instruction suivante ne sera pas


exécutée, tant que l'utilisateur n'aura pas mis fin au dialogue.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 42
Boîte de Dialogue: la classe JDialog (2)
 Arborescence :

Container

Window

Frame Dialog JWindow

JFrame JDialog

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 43


Boîte de dialogue personnalisée: JDialog (3)
 Exemple 1 de boite de dialogue avec JDialog :

import [Link];
public class MonDialogue1 {
public static void main(String[] args){
JDialog dialogue1 = new JDialog();
[Link](300, 200);
[Link](true);
}
}

Par défaut, cette boite est non modale

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 44


Boîte de dialogue personnalisée: JDialog (4)
 Exemple 2 de boite de dialogue avec JDialog:

import [Link].*;
public class MonDialogue2 {
public static void main(String[] args){
JFrame cadre = new JFrame();
JDialog dialogue2 = new JDialog(cadre,"Boîte de dialogue");
[Link](300, 200);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 45


Boîte de dialogue personnalisée: JDialog (5)
 Exemple 3 de boite de dialogue avec JDialog:
Import [Link].*;
import [Link].*;
public class MonDialogue3 {
public static void main(String[] args) {
JFrame cadre = new JFrame();
JDialog dialogue3 = new JDialog (cadre,"Boîte de dialogue",true);
JLabel e = new JLabel("Votre nom");
[Link](e, [Link]);
JTextField t = new JTextField(10);
[Link](t, [Link]);
JButton b = new JButton("OK");
[Link](b, [Link]);
[Link](200,100);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 46


Interfaces Homme - Machine
Chapitre 4:
- Conteneurs intermédiaires,
- Gestions d'événements (1ère partie)

SMI - S6
Année universitaire 2017-2018
Prof. M.D. RAHMANI
mrahmani@[Link]
Plan (1)
 Conteneurs intermédiaires:
 JPanel, panneau générique, sans représentation graphique.
 JScrollPane, panneau à défilement: un panneau affichant
une partie d'un composant trop grand pour être affiché en entier.
 JSplitPane, panneau divisé: un panneau séparé en 2 parties
redimensionnables, affichant chacune un composant.
 JTabbedPane, panneau à onglets: permet de partager une
même surface entre plusieurs composants.
 JDeskTopPane,panneau à bureau, permet l'ouverture de
plusieurs documents (fichiers) simultanément
 JToolBar,la barre d'outils: des outils sous forme de boutons.
 JLayeredPane, panneaux superposés: un composant
permettant de superposer plusieurs composants.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 2
Types de Composants

On peut distinguer 3 types de composants :

 Conteneurs primaires (lourds)


 Conteneurs intermédiaires (légers)
 Composants atomiques (légers)

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 3


Les composants de type conteneurs (1)
Les conteneurs sont destinés à contenir d'autres composants pour
constituer une interface graphique à plusieurs fonctions.
Nous avons 2 niveaux de conteneurs :
Conteneurs de 1er niveau (top level) : ils constituent généralement les fenêtres principales:
 JWindow :
Toute fenêtre primaire sans bordure et sans barre de titre et menu.
 JFrame :
Tout cadre primaire avec une bordure et une barre de titre.
 JDialog :
Toute boite de dialogue sous la responsabilité d'un cadre ou d'une autre
boite de dialogue.
 JApplet :
Des applications pour le Web.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 4


Les composants de type conteneurs (2)
Conteneurs de 2eme niveau :
Ces composants servent à regrouper et/ou présenter d’autres
composants.
• Quelque conteneurs intermédiaires :
 JPanel
 JScrollPane
 JSplitPane
 JTabbedPane
 JToolBar

Ce sont des composants légers

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 5


Les composants de types atomiques (3)
Composants atomiques :
• Ces composants ne sont pas composés d’autres composants.
• Quelques composants atomiques :
 JLabel
 JButton
 JTextField
 JComboBox
 JTable

Ce sont des composants légers

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 6


Conteneurs intermédiaires

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 7


La classe JPanel (1)
C'est le conteneur léger générique.
Son gestionnaire par défaut est le FlowLayout.
Pour ajouter un composant à un panneau, on utilise la méthode add.
Exemple :
public class Identite extends JPanel {
Public Identite() {
JLabel eNom = new JLabel("Nom : ");
JLabel ePrenom = new JLabel("Prénom : ");
JLabel eAdresse = new JLabel("Adresse : ");
JTextField tNom = new JTextField(8);
JTextField tPrenom = new JTextField(8);
JTextArea tAdresse = new JTextArea("",4, 8);
add(eNom);
add(tNom);
add(ePrenom);
add(tPrenom);
add(eAdresse);
add(tAdresse);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 8


La classe JPanel (2)
public class TestJPanel {
public static void main(String[] args) {
JFrame cadre = new JFrame();
[Link](new Identite());
[Link]();
[Link](3);
[Link]("Identité");
[Link](true);
}
}

Remarque :
 Pour pouvoir utiliser le panneau Identite de type JPanel, il faut l'inclure dans un
cadre de type JFrame.
 Le redimensionnement ne modifie pas la taille préférée des composants mais leur
position
 Le conteneur de type JPanel peut être imbriqué y compris dans un JPanel.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 9


La classe JScrollPane (1)
Les applications d'édition du texte ou des images n'affichent souvent
qu'une partie d'un document de grande taille.
Le composant JScollPane, panneau à défilement, permet d'insérer
des glissières, appelées ascenseurs, affichées sur les côtés pour se déplacer
dans le document.
Ce composant ne peut contenir qu'un seul composant.
Si on veut accueillir plusieurs composants, on les met dans un
JPanel que l'on place dans un ScrollPane.
Le gestionnaire de placement d'un JScrollPane est obligatoirement
un JScrollPaneLayout.
Exemple :
Affichage d'une image de grande taille :
- L'image est chargée en utilisant JLabel,
- Ce JLabel est passé au constructeur sur-défini de JScrollPane,
- Nous considérons une taille de la fenêtre petite par rapport à la
taille de l'image.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 10
La classe JScrollPane (2)
Exemple :
public class TestJScrollPane {
public TestJScrollPane() {
JFrame cadre = new JFrame();
JLabel eImage = new JLabel(new ImageIcon("[Link] "));
JScrollPane pDefilement = new JScrollPane(eImage);

[Link](pDefilement);
[Link]("Le chemin par Google Map !");
[Link](400,400);
[Link](3);
[Link](false); // true laisse la possibilité de redimensionnement
[Link](true);
};
public static void main(String [] args) {
new TestJScrollPane();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 11


La classe JScrollPane (3)
Remarque : Les barres de défilement apparaissent quand c'est nécessaire.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 12


La classe JSplitPane (1)
Nous séparons une interface en deux volets pour mettre en vis-à-vis
deux documents, ou un document et une barre d'outils.
La séparation peut être horizontale ou verticale selon les besoins.
Le composant JSplitPane, panneau divisé, ne permet d' accueillir
que deux composants séparés par une barre de division, déplaçable,
verticale ou horizontale.
Les composants peuvent être également de type JSplitPane.
L'utilisateur ne peut modifier la barre de séparation au delà de la
taille minimale des composants.
Exemple :
Affichage de deux zones, une de texte de type JTextArea et l'autre
une image insérée dans un Jlabel, séparées par une barre verticale :
Une version surchargée du constructeur permet d'instancier le
conteneur JSplitPane tout en spécifiant les 2 composants à accueillir et le
sens de division.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 13
La classe JSplitPane (2)
Exemple :
public class TestJSplitPane {
public TestJSplitPane() {
JFrame cadre = new JFrame();
JLabel eImage = new JLabel(new ImageIcon("[Link]"));
JTextArea ta = new JTextArea(texte, 20, 10);
[Link](true); // passage automatique à la ligne
JSplitPane pSeparation = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
ta, eImage); // ou VERTICAL_SPLIT
[Link](pSeparation);
[Link]("Le chemin par Google Map !");
[Link]();
[Link](3);
[Link](true); // autoriser le redimensionnement
[Link](true);
};
static String texte = "Il ne faut pas se fier aveuglément à la technologie. Un chauffeur qui a
été guidé par la géolocalisation de Google !";
public static void main(String [] args) {
new TestJSplitPane();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 14


La classe JSplitPane (3)
JSplitPane.VERTICAL_SPLIT JSplitPane.HORIZONTAL_SPLIT

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 15


La classe JTabbedPane (1)
Le composant JTabbedPane, panneau à onglets, permet de construire des
interfaces avec plusieurs sous-conteneurs dont un seul est affiché, en utilisant des
onglets (Tab).
La même idée qu'un gestionnaire de placement de type CardLayout.
Cette approche permet de classer des informations différentes en ne faisant
apparaître que celles qui sont pertinentes.
La méthode addTab() permet d'ajouter un composant dans un sous-
conteneur, généralement de type JPanel.
L'emplacement des onglets est configurable dans le constructeur par
JTabbedPane.(TOP, BOTTOM, LEFT, RIGHT)
Au début c'est le 1er onglet qui apparait.
On ne peut pas changer le gestionnaire de placement d'un JTabbedPane.

Exemple :
Affichage de 2 composants, on utilise deux classes dérivées de JPanel.
La classe principale dérive de JTabbedPane,
Les éléments sont ajoutés avec la méthode addTab().
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 16
La classe JTabbedPane (2)
Exemple 1 :
public class TestJTabbedPane1 extends JFrame {
public TestJTabbedPane1() {
JTabbedPane pOnglets = new JTabbedPane([Link]); // par défaut
JLabel nom = new JLabel(" Nom : ");
JTextField tNom = new JTextField(10);
JLabel prenom = new JLabel(" Prénom : ");
JTextField tPrenom = new JTextField(10);
JPanel identite = new JPanel();
[Link](nom); [Link](tNom);
[Link](prenom); [Link](tPrenom);
[Link](" Identité ", identite); // ajout d'un 1er panneau avec le titre de l'onglet

JLabel niveau = new JLabel(" Niveau : ");


JTextField tNiveau = new JTextField(10);
JLabel annee = new JLabel(" Année : ");
JTextField tAnnee = new JTextField(10);
JPanel etudes = new JPanel();
[Link](niveau); [Link](tNiveau);
[Link](annee); [Link](tAnnee);
[Link](" Etudes ", etudes); // ajout d'un 2ème panneau avec le titre de l'onglet

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 17


La classe JTabbedPane (3)
add(pOnglets);
setTitle("Saisie d'informations");
pack(); // la taille dépend du plus grand onglet
setDefaultCloseOperation(3);
setResizable(false); // bloquer le changement de la taille
setVisible(true);
};
public static void main(String [] args) {
new TestJTabbedPane1();
}
}

Remarque :
- Les onglets sont numérotés à partir de 0.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 18


La classe JTabbedPane (4)
Exemple 2: Un album de photos
public class TestJTabbedPane2 {
public TestJTabbedPane2() {
JFrame cadre = new JFrame();
JTabbedPane pOnglets = new JTabbedPane();
JLabel eImage1 = new JLabel(new ImageIcon("[Link] "));
JPanel image1 = new JPanel();
[Link](eImage1);
[Link](" Photo 1 ", image1);
JLabel eImage2 = new JLabel(new ImageIcon("[Link] "));
JPanel image2 = new JPanel();
[Link](eImage2);
[Link](" Photo 2 ", image2);
JLabel eImage3 = new JLabel(new ImageIcon("[Link] "));
JPanel image3 = new JPanel();
[Link](eImage3);
[Link](" Photo 3 ", image3);
JLabel eImage4 = new JLabel(new ImageIcon("[Link] "));
JPanel image4 = new JPanel();
[Link](eImage4);
[Link](" Photo 4 ", image4);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 19


La classe JTabbedPane (5)
[Link](pOnglets);
[Link]("Album photos");
[Link]();
[Link](3);
[Link](true);
[Link](true);
};
public static void main(String [] args) {
new TestJTabbedPane2();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 20


La classe JToolBar (1)
Le composant JToolBar, barre d'outils, permet de construire des
barres d'outils regroupant plusieurs composants.

C'est un conteneur qui se redimensionne et peut être déplacé.

Il utilise le gestionnaire BoxLayout, horizontal par défaut.

On peut séparer des groupes de composants avec la méthode


addSeparator.

Exemple1 : Construction d'une barre d'outils pour un éditeur de texte


simple.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 21


La classe JToolBar (2)
Exemple 1 :
public class TestJToolBar1 {
public TestJToolBar1() {
JButton bOuvrir = new JButton(new ImageIcon("[Link]"));
JButton bEnregistrer = new JButton(new ImageIcon("[Link]"));
JButton bCouper = new JButton(new ImageIcon("[Link]"));
JButton bCopier = new JButton(new ImageIcon("[Link]"));
JButton bColler = new JButton(new ImageIcon("[Link]"));

[Link]("Ouvrir un fichier"); // ajout de bulles d'aide


[Link]("Enregistrer le fichier");
[Link]("Couper vers le presse papier");
[Link]("Copier vers le presse papier");
[Link]("Coller depuis le presse papier");

JToolBar tb = new JToolBar();


[Link](bOuvrir);
[Link](bEnregistrer);
[Link](); // ajout d'une barre de séparation
[Link](bCouper);
[Link](bCopier);
[Link](bColler);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 22


La classe JToolBar (3)
Exemple 1 (suite) :
JPanel panneau = new JPanel();
[Link](new BorderLayout());
[Link](tb, [Link]);

JFrame cadre = new JFrame();


[Link](panneau);
[Link]("Barre d'outils");
[Link](600, 400);
[Link](3);
[Link](true);
};
public static void main(String [] args) {
new TestJToolBar1();
}
}
Remarque :
La séparation
La barre d'outils peut être déplacée à l'aide de la méthode setFloatable
Le chemin nom des fichiers doit être de la forme: C:\\TPIHM2018\\Images\\[Link]
ou: C:/TPIHM2018/Images/[Link]
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 23
La classe JToolBar (4)
Exemple 2:
public class TestToolBar2 {
public TestToolBar2() {
JToolBar tb = new JToolBar();
[Link](true); // true par défaut
[Link](new JButton("Ouvrir"));
[Link](new JButton("Enregistrer"));
[Link]();
Icon ic =new ImageIcon("[Link]");
[Link](new JButton("Email", ic));
[Link](new JRadioButtonMenuItem("ON/OF"));
JFrame cadre = new JFrame();
[Link](tb, BorderLayout.PAGE_END);
// en bas de page ou par défaut en haut : PAGE_START
[Link]("Barre d'outils (2)");
[Link](600, 200);
[Link](3);
[Link](true);
};
public static void main(String [] args) {
new TestToolBar2();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 24
La classe JDesktopPane (1)
Le composant JDesktopPane, panneau à bureau, permet
l'ouverture de plusieurs documents (fichiers) simultanément,
simulation d'une application MDI (Multiple Document Interface). Il
affiche des fenêtres JInternalFrame à l'intérieur de l'application.
Un objet JInternalFrame permet d'avoir des petites
fenêtres dans une fenêtre, mais ce n'est pas un conteneur de haut
niveau.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 25


La classe JDesktopPane (2)
Exemple 1 : Création d'une fenêtre interne
public class TestJDesktopPane1 {
public static void main(String[] args) {
boolean resizable = true;
boolean closeable = true; (iconifiable) (maximizable) (closeable)
boolean maximizable = true; Réduire Agrandir Fermer
boolean iconifiable = true;
String title = "Cadre interne";
JInternalFrame icadre = new JInternalFrame(title, resizable, closeable,
maximizable,iconifiable);
[Link](300, 300);
[Link](true);
[Link](new JTextArea());
JDesktopPane desktop = new JDesktopPane();
[Link](icadre);

JFrame f = new JFrame("Cadre externe");


[Link](desktop);
[Link](400, 400);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 26


La classe JDesktopPane (3)
Exemple 2:

class CadreMDI extends JInternalFrame {


public CadreMDI() {
super("", true, true, true, true);
}

public void setImage(String nomImage) {


JPanel p = new JPanel();
JLabel uneImage = new JLabel(new ImageIcon(nomImage));
[Link](uneImage);
[Link](p);
[Link](nomImage);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 27


La classe JDesktopPane (4)
Exemple 2 : Présentation de 3 fichiers de type image
public class TestJDesktopPane2 extends JDesktopPane {
CadreMDI[] images;
String[] nomsFichier = {"[Link]", "[Link]","[Link]"};
public TestJDesktopPane() {
super();
images = new CadreMDI[3];
for(int i=0; i<3; i++) {
images[i] = new CadreMDI();
images[i].setSize(200, 200);
images[i].setLocation(100*i, 50*i); // effet à 3 D !
images[i].setImage(nomsFichier[i]);
images[i].setVisible(true);
[Link](images[i]);
}
}
public static void main(String[] args) {
JFrame f = new JFrame();
[Link](new TestJDesktopPane2());
[Link](3);
[Link](true);
[Link](500, 500);
[Link]("Afficheur d'images");
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 28
La classe JLayeredPane (1)
Le composant JLayeredPane, panneau à 3D ou panneau des
composants en couches, permet de positionner les composants dans un espace
à trois dimensions, à l'intérieur de l'application.
C'est la classe mère de JDesktopPane.
A chaque composant de ce conteneur sont associés deux entiers
appelés niveau (layer) et position (position) indiquant qui est affiché au
dessus.
Ces deux entiers définissent l'ordre d'empilement des composants
contenus dans le panneau.

Pour ajouter un composant à un objet JLayeredPane, nous écrivons :


add(Composant c, Integer i);
plus l'entier est grand, moins la couche est profonde

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 29


La classe JLayeredPane (2)
public class TestJLayeredPane extends JFrame {
public TestJLayeredPane() {
super("Test JLayeredPane");
setSize(300, 200);
setDefaultCloseOperation(3);
JLayeredPane lp = getLayeredPane();
// Création de 3 boutons
JButton b3 = new JButton("3");
[Link]([Link]);
[Link](60, 100, 60, 60);
JButton b2 = new JButton("2");
[Link]([Link]);
[Link](40, 60, 60, 60);
JButton b1 = new JButton("1");
[Link]([Link]);
[Link](20, 20, 60, 60);
// Place les boutons dans les différentes couches
[Link](b1, new Integer(1));
[Link](b2, new Integer(2));
[Link](b3, new Integer(3));
}
public static void main(String[] args) {
TestJLayeredPane composant = new TestJLayeredPane();
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 30
La gestion des événements (1ère partie)

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 31


Plan
 La gestion des événements
 Gestion d'un clic dans la fenêtre, l'interface MouseListener
 Gestion d'un composant avec un écouteur
 Gestion de plusieurs composants avec un écouteur
 Adaptateurs et classes anonymes
 Principaux types d'interface :
 MouseListener, MouseMotionListener
 ActionListener
 WindowListener
 KeyListener
 FocusListener
 ItemListener
 AdjustmentListener
 TextListener

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 32


Conception d'une interface graphique

La création d'une interface graphique est constituée des étapes


suivantes :
 Créations des composants atomiques,
 Création des conteneurs,
 Association aux conteneurs des gestionnaires de placement,
 Ajout des composants atomiques et conteneurs intermédiaires aux
conteneurs.
 Ajout des gestionnaires d'événements.

3
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 3
La gestion des événements (1)
 La programmation événementielle repose sur des événements générés
par des actions :
 de l'utilisateur sur un composant de l'interface (pression d'un touche du clavier ou
un clic sur un bouton...),
 par le programme (horloge, compteur..).
 Il est possible d’apporter une réponse automatique à tout événement. Il
suffit de lier la source de l’événement à un (ou plusieurs) écouteur(s).
 Source : composant qui crée l’événement, généralement suite à une action de
l’utilisateur.
 Ecouteur : objet qui traite l’événement en exécutant une méthode en rapport avec
la nature précise de celui-ci. La classe de l'objet implémente une interface spécifique.

 Principe : un composant déclenche un événement, envoyé sous forme d'un objet


ev à un ou plusieurs objets écouteurs (listeners) qui doivent être enregistrés au
préalable auprès du composant. Ces écouteurs réagissent alors à l'événement.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 34
La gestion des événements (2)

Exemple du processus de traitement d'un événement

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 35


Les types d'événements (1)
 Nous considérons 2 types d'événements :
 Evénements de bas niveau, générés directement par des actions
élémentaires de l'utilisateur.
Exemples:
 appui sur un bouton de souris ou une touche du clavier
 relâchement du bouton de souris ou de la touche du clavier
 déplacement du pointeur de souris.

 Evénements logiques de haut niveau ou sémantiques engendrés par


plusieurs actions élémentaires, qui correspondent à une action complète
de l'utilisateur.
Exemples :
 frappe d'une lettre majuscule
 clic de souris
 choix d'un élément dans une liste.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 36
Les types d'événements (2)
 Exemple :
 La frappe d'un 'A' majuscule engendre 5 événements :

4 événements de bas niveau :


 appui sur la touche Majuscule
 appui sur la touche A
 relâchement de la touche A
 relâchement de la touche Majuscule

1 événement logique :
 frappe du caractère 'A' majuscule

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 37


Les types d'événements (3)
 Suite de l'exemple : Cela se traduit par :

 Evénements de niveaux différents :


L’événement KEY_TYPED correspond à l’entré ev d’un caractère.
C’est un événement de haut niveau.
Par exemple, la frappe d’un A engendre :
- 4 événements de bas niveau :
- Appui KEY_PRESSED sur la touche Shift
- Appui KEY_PRESSED sur la touche A
- Relâchement KEY_RELEASED de la touche A
- Relâchement KEY_RELEASED de la touche Shift

- 1 événement de haut niveau


- Frappe KEY_TYPED du caractère A
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 38
Les types d'événements (4)

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 39


Les événements de bas niveau
Ces événements sont définis dans [Link]

 FocusEvent : gain ou perte du focus sur un composant.


 MouseEvent : mouvements et clics de souris et entrer ou sortir.
 KeyEvent : événements clavier.
 WindowEvent : actions sur une fenêtre, ouverture, fermeture,...
 ComponentEvent : changement de taille, position ou visibilité
d'un composant.
 ContainerEvent : ajout et suppression d’un composant

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 40


Les événements sémantiques
Ces événements sont définis [Link] et
[Link]

 ActionEvent : activer un bouton, un champ textuel ...,

 TextEvent : modification du texte entré.. .

 ItemEvent : sélection dans une liste ou dans un groupe de cases à cocher

 AdjustementEvent : déplacement du curseur d'un ascenseur

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 41


L'écoute des événements (1)
 Ecouteurs d'événements :
Tous les composants sont des sources possibles d'événements.
Chaque type de composant propose des méthodes permettant à un
objet écouteur de s'enregistrer ou d'annuler son enregistrement.
 Forme générale : addXxxListener() et removeXxxListener ,
 Exemple: pour un composant de type JButton :
addActionListener et removeActionListener.

 Type d'événement : à chaque type d'événement, on associe une


interface de type d'écouteur :
 Exemple : à ActionEvent on associe ActionListener.
ActionListener est une interface qui possède une méthode
actionPerformed() qui prend un objet ActionEvent comme
argument
Cette méthode détermine la réponse de l'écouteur à l'événement.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 42
L'écoute des événements (2)
 Exemple: gestion d'un clic sur un bouton :
 soit b un objet de type JButtton

 ec1, ec2, ..., ecn des objets enregistrés comme écouteurs de b, instances des
classes qui implémentent l'interface d'écoute ActionListener.

 Lors d'un clic sur le bouton b :


 b transmet un objet ActionEvent ev qui correspond à cet événement.
 ev est passé à la méthode actionPerformed() de l'Interface
ActionListener pour ec1, ec2, ..., ecn.
 les ec1, ec2, ..., ecn réagissent à la réception de l'événement

 Remarques :
 Un objet peut écouter plusieurs composants,
 Un composant peut s'écouter lui même,

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 43


Les principaux types d'écouteurs d'événements (1)
Chaque type d'événement correspond à une interface d'écouteurs.
 MouseListener, MouseMotionListener : liées aux événements de la souris
 ActionListener: se déclenche pour une bouton pressé, pour un lien de menu choisi,
pour un champ textuel modifié.
 WindowListener: permet de récupérer auprès d'une fenêtre les événements de
l'ouverture, de fermeture, d'activation, de désactivation, d'iconification et de desiconification.
 KeyListener: Il se produit un événement clavier chaque fois qu'une touche est pressée ou
relâchée.
 CareListener: se déclenche quand, dans un éditeur, le curseur est bougé ou du texte
sélectionné.
 ChangeListener: permet d'être notifié des changements dans un JSlider, un
JColorChooser ou bien un JSpinner.
 ItemListener: permet de savoir quand un item est sélectionné ou non, en particulier un
élément dans les JCheckBox, les JComboBox et les JCheckBoxMenuItem.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 44


Les principaux types d'écouteurs (2)
Ecouteur / Evénement Méthodes de l'écouteur Evénement généré par
ActionListener actionPerformed() AbstractButton,
ActionEvent Button, JComboBox,
JFileChooser,
JTextField, List,
Timer
FocusListener focusGained() Component
FocusEvent focusLost()
MouseListener mouseClicked() Component
MouseEvent mouseEntered()
mouseExited()
mousePressed()
mouseReleased()
MouseMotionListener mouseDragged() Component
MouseEvent mouseMoved()
KeyListener KeyPressed() Component
KeyEvent keyReleased()
keyTyped()
TextListener textValueChanged() TextComponent
TextEvent
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 45
Les principaux types d'écouteurs (3)
Listeners / Event Méthodes de listener Générés par
ItemListener itemStateChanged() AbstractButton,
ItemEvent CheckBox, JComboBox,
ItemSelectable,
List,Choice,
CheckboxMenuItem
WindowListener windowActivated() Window
WindowEvent windowClosed()
windowClosing()
windowDeactivated()
windowDeiconified()
WindowIconified()
windowOpened()
ComponentListener componentHidden() Component
ComponentEvent componentShown()
componentMoved()
componentReized()
CaretListener caretUpdate() JTextComponent
CaretEvent
ListeSelectionListener valueChanged() JList,
ListeSelectionEvent ListSelectionModel
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 46
Gestion d’événements: Mécanismes et structure
 Les Sources d’événements
 JButton, JList, JMenuItem, JTextField, JScrollBar, JCheckBox, JComponent,
Container, JWindow
 Evénements
 ActionEvent, AdjustmentEvent, ComponentEvent, ContainerEvent,
FocusEvent, ItemEvent, KeyEvent, MouseEvent, TextEvent, WindowEvent
 Les Interfaces Ecouteurs
 ActionListener, AdjustmentListener, ComponentListener, ContainerListener,
FocusListener, ItemListener, KeyListener, MouseListener,
MouseMotionListener, WindowListener
 Les Adaptateurs correspondants
 ActionAdapter, WindowAdapter, KeyAdapter, MouseAdapter, etc.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 47


Les interfaces Mouse(Motion)Listener (1)
MouseListener : les événements générées à l'aide d'une souris, clic sur
un bouton, déplacement du pointeur.
MouseMotionListener : les événements générées à l'aide du
mouvement d'une souris, glissement, déplacement .
Evénement : MouseEvent
Ecouteur : MouseListener Ecouteur: MouseMotionListener
- Méthodes: - Méthodes:
mouseClicked(MouseEvent) mouseDragged(MouseEvent)
mouseEntered(MouseEvent) mouseMoved(MouseEvent)
mouseExited(MouseEvent)
mousePressed(MouseEvent)
mouseReleased(MouseEvent)

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 48


L'interface MouseListener (2)
 void mouseClicked(MouseEvent ev): appelée lorsqu'un bouton de la
souris est "cliquée" (pressée puis relâchée au même endroit).
 void mouseEntered(MouseEvent ev): appelée lorsque le pointeur de
la souris commence à survoler le composant dont on guette les événements.
 void mouseExited(MouseEvent ev): appelée lorsque le pointeur de
la souris cesse de survoler le composant dont on guette les événements.
 void mousePressed(MouseEvent ev): appelée lorsqu'un bouton de la
souris est pressé, le pointeur se trouve sur le composant dont on guette les
événements.
 void mouseReleased(MouseEvent ev): appelée lorsqu'un bouton de
la souris est relâché, alors qu'il avait été pressé quand le pointeur se trouvait
sur le composant dont on guette les événements.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 49


L'interface MouseMotionListener (3)

Cette interface concerne les mouvements de la souris.


Lorsqu'on fait bouger la souris sans appuyer sur un de ses boutons on dit
qu'on la "déplace" (move), lorsqu'on la fait bouger tout en maintenant un bouton
pressé on dit qu'on la "traîne" (drag). Cette interface comporte 2 méthodes :

 void mouseMoved(MouseEvent ev): appelée lorsque la souris change


de position sans qu'aucun bouton ne soit pressé.

 void mouseDragged(MouseEvent ev): appelée lorsque la souris


change de position avec un de ses boutons pressé.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 50


La classe MouseEvent (4)
 L'argument des méthodes des 2 interfaces MouseListener et
MouseMotionListener est un objet de type MouseEvent.

Les méthodes d'un tel objet sont:

 getX(), getY() qui renvoient les coordonnées du pointeur au


moment où l'événement a été notifié,
 getButton() qui permet de savoir quel bouton a été pressé.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 51


Gestion d'un clic dans la fenêtre (1)
Implémentation de l'interface MouseListener:
Il existe une catégorie d'événements souris qu'on peut traiter avec un écouteur de souris,
C'est un objet d'une classe qui implémente l'interface MouseListener.
Cette interface comporte 5 méthodes correspondant chacune à un événement particulier:
Une classe susceptible d'instancier un objet écouteur de ces différents événements aura la
forme:

class EcouteurSouris implements MouseListener {


public void mouseClicked(MouseEvent ev) {....}
public void mousePressed(MouseEvent ev) {....}
public void mouseReleased(MouseEvent ev) {....}
public void mouseEntered(MouseEvent ev){....}
public void mouseExited(MouseEvent ev){....}
// autres méthodes et champs de la classe
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018


52
Gestion d'un clic dans la fenêtre (2)
Exemple: Pour le cas de l'événement mouseEvent, appui suivi de
relâchement, sans déplacement, nous le traitons en redéfinissant la
méthode mouseClicked :
public void mouseClicked(MouseEvent ev) {
[Link]("Clic dans la fenêtre");
}
Remarque:
La classe implémentant l'interface MousListener doit redéfinir
toutes les méthodes.
Nous pouvons fournir des méthodes "vides" pour les autres
événements.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 53


Gestion d'un clic dans la fenêtre (3)
 Un programme qui affiche un message lors de chaque clic dans la fenêtre graphique.
import [Link].*;
import [Link].*; // pour MouseEvent et MouseListener
class Clic1 extends JFrame implements MouseListener {
public Clic1(){
setTitle ("Gestion de clics");
setBounds(10, 20, 300, 200);
addMouseListener(this); // la fenêtre sera son propre écouteur d'événements souris
}
public void mouseClicked(MouseEvent ev){ // méthode gérant un clic
setCursor(new Cursor(Cursor.HAND_CURSOR)); // le curseur change de forme
[Link]("Clic dans la fenêtre");
}
public void mousePressed (MouseEvent ev) {}
public void mouseReleased(MouseEvent ev){}
public void mouseEntered (MouseEvent ev){}
public void mouseExited (MouseEvent ev) {}

public static void main(String args[]) {


Clic1 clic1 = new Clic1(); Console :
[Link](true); Clic dans la fenêtre
} Clic dans la fenêtre
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 54
Gestion d'un clic dans la fenêtre (4)

Remarques:
 La gestion des événements fait appel au paquetage [Link].

 Les méthodes telles que mouseClicked doivent être publiques car


une classe ne peut pas restreindre les droits d'accès d'une méthode
qu'elle implémente.

 Aucune réaction si le clic est dans la barre de titre ou à l'extérieur, de


même lors d'un glissement (drag).

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 55


Gestion d'un clic dans la fenêtre (5)
Utilisation de l'information associée à un événement:
L'objet de type MouseEvent créé lors d'un clic, appartient à la
classe implémentant l'interface MouseListener.
Il a accès aux coordonnées du curseur au moment du clic par les
méthodes getX et getY.
Voici une version avec les coordonnées du point.
Modification de programme précédent:
public void mouseClicked(MouseEvent ev) { // méthode gérant un clic
int x = [Link]();
int y = [Link]();
[Link]("Clic au point : "+x+","+y);
}

Remarque: Les coordonnées du clic correspondent au conteneur et non à l'écran.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 56


Gestion d'un clic dans la fenêtre (6)
 Un programme qui affiche un message lors de chaque clic dans la fenêtre graphique.
import [Link].*;
import [Link].*; // pour MouseEvent et MouseListener
class Clic2 extends JFrame implements MouseListener {
public Clic2(){
setTitle ("Gestion de clics");
setBounds(10, 20, 300, 200);
addMouseListener(this); // la fenêtre sera son propre écouteur d'événements souris
}
public void mouseClicked(MouseEvent ev){ // méthode gérant un clic
int x = [Link]();
int y = [Link]();
[Link]("Clic au point : "+x+","+y);
}
public void mousePressed (MouseEvent ev) {}
public void mouseReleased(MouseEvent ev){}
public void mouseEntered (MouseEvent ev){}
public void mouseExited (MouseEvent ev) {}

public static void main(String args[]) {


Clic2 clic2 = new Clic2(); Console : Clic au point: 4,23
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 57
Les événements de la souris
Les 4 méthodes vides de la classe EcouteurSouris
découlent des contraintes suivantes:
 d'une part, pour pouvoir être enregistré comme écouteur
d'événements souris, un objet doit appartenir à une classe qui
implémente l'interface MouseListener,
 d'autre part, l'interface MouseListener se compose de 5
méthodes (abstraites) à redéfinir, correspondant aux 5 événements
qu'on peut déclencher avec une souris.
 Quand on implémente une interface XxxListener, il est
nécessaire de définir toutes les méthodes de l'interface même si un
petit nombre d'événements possibles nous intéresse.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 58


Les Adaptateurs (1)
Lorsqu’une interface XxxListener possède plusieurs méthodes, une
classe abstraite XxxAdapter implémentant cette interface est généralement
disponible.
Cette implémentation consiste à donner un corps vide à chaque
méthode.
Lorsqu’un nombre limité de méthodes d’une interface intéresse
l’utilisateur, on préfère étendre la classe Adapter plutôt qu’implémenter
l’interface Listener.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 59


Les Adaptateurs (2)
Les adaptateurs sont des implémentations toutes prêtes des interfaces
d'écouteurs d'événements, faites de méthodes vides.
Chaque interface XxxListener possède une classe abstraite
XxxAdapter correspondante.

Exemple:
class ClicSouris extends JFrame {
....
addMouseListener(new EcouteurSouris());
....
}
class EcouteurSouris extends MouseAdapter {
public void mouseClicked (MouseEvent ev) { ....}
...
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 60


Les Adaptateurs (3)
Utilisation d'une classe dédiée dérivée d'une classe Adapter
public class Clic3 extends JFrame {
Clic3() {
super("Gestion de clics");
setDefaultCloseOperation(3);
JPanel panneau = new JPanel();
[Link]([Link]);
EcouteurSouris ecouteur = new EcouteurSouris();
[Link](ecouteur);
add(panneau);
setSize(300, 150);
setVisible(true);
}
public static void main(String[] args) {
new Clic3();
}
}
class EcouteurSouris extends MouseAdapter {
public void mousePressed(MouseEvent ev) {
[Link]("Clic en ("+[Link]()+","+[Link]()+")");
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 61
Choix de la méthode de gestion des événements
La gestion des événements peut se faire de plusieurs manières:

1ère solution : Gestion des événements par la classe du conteneur graphique,


L'approche la plus simple, l'interface écouteur est implémenté par la classe graphique.

2ème solution : Gestion des événements par des classes dédiées,


Cette approche consiste à construire une classe par écouteur d'événement.

3ème solution : Gestion des événements par des classes membres internes,
Une classe membre peut accéder facilement aux éléments de la classe parente.
Cette méthode conduit à créer une classe interne par composant et par événement.

4ème solution : Gestion des événements par des classes membres internes anonymes,
Si une classe est crée pour n'être utilisée qu'une seule fois dans le programme, on peut
utiliser une classe anonyme.
Cette approche consiste en la construction d'un objet qui implémente une interface donnée
sans l'associer à une variable.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 62
Gestion des événements (1)
Solution 1 :
Considérer comme écouteur le conteneur des composants.
Il est donc nécessaire d’effectuer des tests afin de savoir quel est le
composant qui a généré l’événement.
On peut utiliser la méthode getSource définie dans EventObject.

Remarques :
- Positive : rapide à mettre en œuvre (si peu de composants).

- Négative :
- peu extensible
- il est nécessaire de déterminer quel composant a généré l’événement
(avec des successions de tests).
- si le nombre de composant est grand, la classe devient vite très complexe.
 On peut regrouper dans le code les traitements par type de composants.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 63
Choix de la méthode (1)
1ère solution: le panneau est son propre écouteur
class Souris1 extends JPanel implements MouseListener {
public Souris1() {
addMouseListener(this);
setBackground([Link]); // la couleur du début
}
public void mouseEntered(MouseEvent ev) {
setBackground([Link]);
}
public void mouseExited(MouseEvent ev) {
setBackground([Link]);
}
public void mousePressed(MouseEvent ev) {}
public void mouseReleased(MouseEvent ev) {}
public void mouseClicked(MouseEvent ev) {}

public static void main(String[] arg) {


JFrame f = new JFrame("1ère version");
[Link](new Souris1());
[Link](3);
[Link](300, 150);
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 69
Gestion des événements (2)
Solution 2 :
- Créer une classe externe au conteneur C, dédiée à la gestion des
événements.
- Créer un objet de cette classe dans le conteneur.
- Considérer cet objet comme l'écouteur des différents composants.
Remarques :
- Positive
On ne considère plus que le conteneur gère les événements.
- Négative
- Problème de maintenance, les 2 classes sont dépendantes.
- il est nécessaire de déterminer quel composant a généré l’événement,
avec des successions de tests.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 64
Choix de la méthode (2)
2ème solution: avec une classe dédiée qui dérive de MouseAdapter.
class Panneau extends JPanel {
public Panneau() {
addMouseListener(new Ecoute(this));
setBackground([Link]);
}
}
class Ecoute extends MouseAdapter {
JPanel panneau;
Ecoute(JPanel panneau) {
[Link] = panneau;
}
public void mouseEntered(MouseEvent ev) {
[Link]([Link]);
}
public void mouseExited(MouseEvent ev) {
[Link]([Link]);
}
}
public class Souris2 {
public static void main(String[] arg) {
JFrame f = new JFrame("2ème version");
[Link](new Panneau());
[Link](3);
[Link](300, 150);
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 70
Gestion des événements (3)
Solution 3 :
Créer une classe interne par composant afin de gérer les évènements
produits par celui-ci.
Associer à chaque composant, considéré comme écouteur , une
instance de la classe qui lui est associée.
Critique :
- Positive:
- solution extensible, si on associe à chaque composant sa propre
classe écouteur.
- il n’est plus nécessaire de déterminer quel composant a généré
l’événement si chaque composant a sa propre classe écouteur.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 65


Gestion des événements (4)
Solution 3 : Utilisation d'une classe dédiée interne

Les classes membres peuvent accéder facilement aux éléments de la


classe graphique englobante.
Cette approche conduit à créer une classe membre interne par
composant et par événement.

Private class EcouteurSourisInterne extends MouseAdapter {


public void mousePressed(MouseEvent e) {
// partie utile
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 66


Choix de la méthode (3)
3ème solution: avec une classe interne qui dérive de MouseAdapter.

public class Souris3 extends JPanel {


public Souris3() {
setBackground([Link]); // la couleur du début
addMouseListener(new Ecoute());
}
private class Ecoute extends MouseAdapter {
public void mouseEntered(MouseEvent ev) {
setBackground([Link]);
}
public void mouseExited(MouseEvent ev) {
setBackground([Link]);
}
}
public static void main(String[] arg) {
JFrame f = new JFrame("3ème version");
[Link](new Souris3());
[Link](3);
[Link](300, 150);
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 71
Gestion des événements (5)
Solution 4 :
Créer une classe interne anonyme par composant.

On associe alors une instance de cette classe anonyme lors de


l’enregistrement d’un écouteur.

Remarques :
- Positive
- il n’est plus nécessaire de nommer les classes.
- le code est proche du composant

- Négative
- moins de clarté ?
 Si la classe écoute un seul composant et ne comporte pas de méthodes
longues
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 67
Gestion des événements (6)
Solution 4: à la place de l'objet ecouteur nous aurons la classe anonyme
A la place de :
EcouteurSouris ecouteur = new EcouteurSouris();
[Link](ecouteur);
Nous aurons :
class ClicSouris extends JFrame {
....
addMouseListener(new MouseAdapter {
public void mouseClicked (MouseEvent ev) { ....}
...
});
...
}
Ici, on a créé un objet d'un type classe anonyme dérivée de
MouseAdapter et dans laquelle on a redéfini la méthode mouseClicked.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 68
Choix de la méthode (4)
4ème solution: avec une classe MouseAdapter et une classe interne et anonyme.
L'adaptateur est définit dans une classe interne et anonyme.
public class Souris4 extends JPanel {
public Souris4() {
addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent ev) {
setBackground([Link]);
}
public void mouseExited(MouseEvent ev) {
setBackground([Link]);
}
});
setBackground([Link]); // la couleur du début
}
public static void main(String[] arg) {
JFrame f = new JFrame("4ème version");
[Link](new Souris4());
[Link](3);
[Link](300, 150);
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 72
Interfaces Homme - Machine
Chapitre 5: Gestions d'événements (2ème partie)

SMI - S6
Année universitaire 2017-2018

Prof. M.D. RAHMANI


mrahmani@[Link]
L'interface ActionListener (1)
Cette interface concerne les événements générées par le composant à l'aide d'un clic
d'une souris, d'une touche entrée, sélection d'un élément.
Evénement : ActionEvent
Evénements générés par : AbstractButton, Button, JComboBox,
JFileChoose, JTextField, List, MenuItem, TextField.
Ecouteur : ActionListener
- Méthode: une seule méthode
ActionPerformed(ActionEvent)
- L'argument de cette méthode est un objet ActionEvent, muni de la méthode:
String getActionCommand(): renvoie une chaîne qui identifie l'action en
question.
La démarche:
- créer un écouteur qui sera un objet d'une classe qui implémente l'interface
ActionListener, qui ne comporte qu'une méthode actionPerformed;
- associer cet écouteur au bouton par la méthode
[Link](ecouteur);
Exemple: le titre d'un bouton pressé ou d'une case cochée.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 8


L'interface ActionListener (2)
class Fenetre1 extends JFrame implements ActionListener {
public Fenetre1() {
setTitle ("Un Bouton avec écouteur");
setSize(300,150);
setDefaultCloseOperation(3);
JButton monBouton = new JButton("Bouton sensible");
setLayout(new FlowLayout());
add(monBouton);
[Link](this); // la fenêtre écoute monBouton
}
public void actionPerformed(ActionEvent ev) {
[Link]("action sur le bouton !");
}

public static void main(String args[]) {


Fenetre1 f = new Fenetre1();
[Link](true);
}
}
Console: action sur le bouton !

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 9


L'interface ActionListener (3)
Gestion de plusieurs composants:
On peut faire de la fenêtre l'objet écouteur de plusieurs boutons.
Nous aurons 2 possibilités:

1- prévoir la même réponse, quel que soit le bouton.

2- prévoir une réponse dépendante du bouton concerné.

Pour identifier le composant source de l'événement, nous


utilisons la méthode getSource .

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 10


L'interface ActionListener (4)
1- Tous les boutons déclenchent la même réponse:
class Fenetre2 extends JFrame implements ActionListener {
public Fenetre2() {
setTitle("Deux boutons avec écouteur");
setSize(350, 150);
setDefaultCloseOperation(3);
JButton monBouton1 = new JButton("Bouton A");
JButton monBouton2 = new JButton("Bouton B");
setLayout(new FlowLayout());
add(monBouton1); add(monBouton2);
[Link](this); // la fenêtre écoute monBouton1
[Link](this); // la fenêtre écoute monBouton2
}
public void actionPerformed(ActionEvent ev){
[Link]("action sur un bouton"); // gestion commune des 2 boutons
}
public static void main(String args[]) {
Fenetre2 f = new Fenetre2();
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 11
L'interface ActionListener (5)
2- La réponse dépend du bouton concerné: la méthode getSource,
class Fenetre3 extends JFrame implements ActionListener {
public Fenetre3() {
setTitle("Avec deux boutons");
setSize(300, 200);
setDefaultCloseOperation(3);
monBouton1 = new JButton ("Bouton 1");
monBouton2 = new JButton ("Bouton 2");
setLayout(new FlowLayout());
add(monBouton1);
add(monBouton2);
[Link](this); // la fenêtre écoute monBouton1
[Link](this); // la fenêtre écoute monBouton2
}
JButton monBouton1, monBouton2;
public void actionPerformed(ActionEvent ev) {
if ([Link]() == monBouton1)
[Link] ("action sur le bouton 1");
if ([Link]() == monBouton2)
[Link] ("action sur le bouton 2");
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 12
L'interface ActionListener(6)
 String getActionCommand(): renvoie une chaîne qui identifie l'action en question.
3- La réponse dépend du bouton concerné: la méthode getActionCommand,
La définition d'une classe TroisBoutons de type JPanel qui est un conteneur
portant trois boutons et en même temps l'écouteur des actions dont ces boutons
sont la source:
import [Link].*;
import [Link].*;
class Fenetre4 extends JPanel implements ActionListener {
public Fenetre4() {
JButton bouton = new JButton("Oui");
[Link](this);
add(bouton);
bouton = new JButton("Non");
[Link](this);
add(bouton);
bouton = new JButton("Sans avis");
[Link](this);
add(bouton);
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 13
L'interface ActionListener(7)
public void actionPerformed(ActionEvent ev) {
if([Link]().equals("Oui"))
[Link]("Il a dit oui");

else if ([Link]().equals("Non"))
[Link]("Il a dit non");
else
[Link]("Il ne sait pas");
}

public static void main(String[] args) {


JFrame f = new JFrame("Trois boutons");
[Link](3);
[Link](new Fenetre4());
[Link](300, 150);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 14


L'interface ActionListener(8)
Utilisation d'une zone de texte
Il s'agit d'écrire un texte dans la zone centrale.
L'entier indiqué dans la petite zone de texte donne la taille de la police
de caractères utilisée dans la zone centrale.
On peut modifier cette taille, la demande sera prise en compte si on
appuie sur Entrée.

JLabel JTextField

JTextArea

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 15


L'interface ActionListener(9)
Utilisation d'une zone de texte
class TexteEtFonte extends JFrame implements ActionListener{
JTextField saisieTaille = new JTextField(5);
JTextArea grandeZone = new JTextArea(4, 10);
public TexteEtFonte() {
JLabel taille = new JLabel(" Taille de la fonte");
JPanel panneauTaille = new JPanel();
int tailleInitiale = 20;
[Link]([Link](tailleInitiale));
[Link](this); // écouter le champ de texte
[Link](new BorderLayout(5, 5)); // espacement h et v
[Link](taille, [Link]);
[Link](saisieTaille, [Link]);
// on définit une police de caractères correspondant aux caractéristiques indiquées.
Font fonte = new Font("TimesRoman", [Link], tailleInitiale);
// cette instruction permet de choisir la police de la zone centrale de texte.
[Link](fonte);
JScrollPane texteAsc = new JScrollPane(grandeZone);
add(panneauTaille, [Link]);
add(texteAsc, [Link]);
setDefaultCloseOperation(3);
pack();
setVisible(true);
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 16
L'interface ActionListener (10)

Utilisation d'une zone de texte

public void actionPerformed(ActionEvent ev) {


int taillePolice;
taillePolice = [Link]([Link]());
[Link](new Font("TimesRoman", [Link], taillePolice));
[Link]([Link]());
// récupérer le texte et lui affecter les nouvelles caractéristiques
}
public static void main(String[] arg) {
new TexteEtFonte();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 17


L'interface ActionListener(11)
Utilisation d'une fenêtre de dialogue pour avoir un avertissement

class Dialogue1 extends JFrame implements ActionListener {


JButton bouton = new JButton("Voir avertissement");
public Dialogue1() {
setTitle("Dialogue 1");
add(bouton);
[Link](this);
setDefaultCloseOperation(3);
setSize(250, 70);
setVisible(true);
}
public void actionPerformed(ActionEvent ev) {
[Link](this, "Ce n'est qu'un simple message",
"avertissement", JOptionPane.WARNING_MESSAGE);
}

public static void main(String[] arg) {


new Dialogue1();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 18
L'interface ActionListener(12)
Utilisation d'une fenêtre de dialogue pour poser une question et avoir une réponse
class Dialogue2 extends JFrame implements ActionListener {
JButton bouton = new JButton("Voir la question");
JLabel etiquette = new JLabel(" ");
public Dialogue2() {
add(bouton, [Link]);
add(etiquette, [Link]);
[Link](this);
setDefaultCloseOperation(3);
setSize(200, 80);
setVisible(true);
}
public void actionPerformed(ActionEvent ev) {
int reponse = [Link](null,
"Etes-vous de bonne humeur ?", "Votre tempérament",
JOptionPane.YES_NO_CANCEL_OPTION);
if (reponse == JOptionPane.YES_OPTION) [Link]("C'est bien :)");
else if (reponse == JOptionPane.NO_OPTION) [Link]("Courage :(");
else [Link]("ni l'un ni l'autre ?");
}
public static void main(String[] arg) {
new Dialogue2();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 19
L'interface ActionListener(13)
Utilisation d'une fenêtre de dialogue pour poser une question et avoir une
réponse libre
Avec la fenêtre de dialogue, les réponses possibles sont "oui", "non", "moyen", "pas
d'opinion".
Selon la réponse, l'action du programme est différente.
Tant que la fenêtre avec la question n'est pas fermée, l'application est bloquée : la
fenêtre de dialogue est modale.
On utilise ici la méthode [Link](...)

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 20


L'interface ActionListener(14)
Utilisation d'une fenêtre de dialogue pour poser une question et avoir une réponse libre
int reponse = [Link](null, "Etes-vous de bonne humeur ?",
"Boutons personnalisés", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
null, choix, choix[0]); :
Le premier paramètre indique la fenêtre "parent" ; si ce paramètre vaut null, la fenêtre de dialogue apparaît
au milieu de l'écran ;
le second paramètre donne l'énoncé de la question ;
le troisième paramètre donne le titre de la fenêtre de dialogue ;
le quatrième paramètre laisse libre le nombre de réponses ;
le cinquième paramètre donne le type du message ; c'est ce paramètre qui conduit à avoir un point
d'interrogation dans la fenêtre de dialogue ;
le sixième paramètre permet de choisir l'icône qui apparaît ;
le septième paramètre; donne la liste des choix ;
le dernier paramètre donne le choix par défaut, c'est celui-ci qui est retenu si la fenêtre est fermée par la
touche "return".
Les valeurs de retour sont des entiers donnant le numéro d'ordre de la réponse, en commençant à 0.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 21


L'interface ActionListener(15)
Exemple 5: Utilisation d'une fenêtre de dialogue pour poser une question et
avoir une réponse libre
public void actionPerformed(ActionEvent ev) {
String[] choix = {"oui", "non", "moyen", "pas d'opinion"};
int reponse = [Link] (null, "Etes-vous de bonne humeur ?",
"Boutons personnalises", JOptionPane.DEFAULT_OPTION,
JOptionPane.QUESTION_MESSAGE, null, choix, choix[0]);
switch(reponse) {
case 0 : [Link]("Bravo !");
break;
case 1 : [Link]("Courage !");
break;
case 2 : [Link]("Persévérons !");
break;
case 3 : [Link]("Vous ne savez pas !");
break;
}
}
public static void main(String[] arg) {
new EssaiDialogue3();
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 22
L'interface ActionListener (16)
La boite de dialogue: Choix d'une couleur
Choisir une couleur qui deviendra la couleur de fond du panneau qui se
trouve en-dessous du bouton.
Tant que la fenêtre pour choisir la couleur n'est pas fermée, l'application
est bloquée : la fenêtre de choix de couleur est modale.

Color couleur = [Link](null, "couleur du fond", [Link]);

Cette instruction fait apparaître la fenêtre qui permet de choisir une couleur.
- Le premier paramètre indique la fenêtre parente devant laquelle la fenêtre de choix
de couleur apparaîtra ; si ce paramètre vaut null, la fenêtre apparaît au centre de l'écran.
- Le second paramètre donne le titre à la fenêtre de choix de couleur.

On utilise le package: [Link];

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 23


L'interface ActionListener(17)
Choix d'une couleur
class Couleurs extends JFrame implements ActionListener {
JPanel panneau = new JPanel();
public Couleurs() {
JButton bouton = new JButton("choix de la couleur");
[Link](200, 200);
add(bouton, [Link]);
add(panneau, [Link]);
[Link](this);
setDefaultCloseOperation(3);
setLocation(100, 100);
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent ev) {
Color couleur = [Link]
(null, "couleur du fond", [Link]);
[Link](couleur);
}

public static void main(String[] arg) {


new Couleurs();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 24
L'interface WindowListener (1)
 WindowListener: les événements de cette interface sont les actions sur
une fenêtre: ouverture et fermeture et, dans le cas d'un cadre JFrame ou d'un
dialogue JDialog, les actions sur les éléments de la barre de titre, les
méthodes associées sont:
 void windowClosing(WindowEvent ev): appelée si l'utilisateur essaye de
fermer la fenêtre en agissant sur son menu système ou sa case de fermeture.
 void windowActivated(WindowEvent ev): la fenêtre rendu active.
 void windowDeactivated(WindowEvent ev): cesse d'être la fenêtre
active.
 void windowClosed(WindowEvent ev): si la fenêtre a été fermée suite à un
appel de sa méthode dispose.
 void windowOpened(WindowEvent ev)fenêtre est rendue visible pour la
1ère fois
 void windowIconified(WindowEvent ev): fenêtre minimisée.
 void windowDeiconified(WindowEvent ev): retrouver la taille normale.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 25


L'interface WindowListener (2)
Exemple 1 : Sortie avec WindowListener
public class TestWindowListener1 extends JFrame {
public TestWindowListener(){
setTitle("Fenêtre fermée par windowClosing");
Ecouteur ec = new Ecouteur();
addWindowListener (ec);
setBounds(100,100, 350, 100);
setVisible(true);
}
public static void main(String [] args){
new TestWindowListener1();
}
}
// même effet que setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
class Ecouteur implements WindowListener {
public void windowClosing(WindowEvent ev){
[Link](0);
}
public void windowOpened(WindowEvent ev){}
public void windowIconified(WindowEvent ev){}
public void windowDeiconified(WindowEvent ev){}
public void windowDeactivated(WindowEvent ev){}
public void windowClosed(WindowEvent ev){}
public void windowActivated(WindowEvent ev){}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 26
L'interface WindowListener (3)
Exemple 2 : Version avec WindowAdapter
import [Link].*;
import [Link].*;
public class TestWindowListener2 extends JFrame {
public TestWindowListener2() {
setSize("Fenêtre fermée par windowClosing");
addWindowListener(new Ecouteur2());
setBounds(100,100, 350, 100);
setVisible(true);
}
public static void main(String [] args){
new TestWindowListener2();
}
}

class Ecouteur2 extends WindowAdapter {


public void windowClosing(WindowEvent ev){
[Link](0);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 27
L'interface WindowListener (4)
 WindowEvent
 Window getWindow(): renvoie la fenêtre qui déclenche l’évènement.
 Exemple 3: Sortie contrôlée
public class CadreAvecSortie extends JFrame {
public CadreAvecSortie(String titre) {
super(titre);
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); // neutralise la croix de fermeture
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ev) {
sortie();
}
});
JPanel panneau = new JPanel();
[Link](new Dimension(200, 150));
[Link]([Link]);
getContentPane().add(panneau);
pack();
setVisible(true);
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 28


L'interface WindowListener (5)
 WindowListener:

public void sortie() {


if([Link](this, "Voulez vous quitter?",
"Attention",
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
[Link](0);
}

public static void main(String[] args) {


new CadreAvecSortie("Vous allez sortir par votre choix");
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 29


L'interface KeyListener (1)
KeyListener : contrôle du clavier, comme pour la souris, on retrouve:
Pressé/Relâché/Tapé
 keyPressed(KeyEvent ev) : touche du clavier pressée
 keyReleased(KeyEvent ev) : touche du clavier relâchée
 keyTyped(KeyEvent ev) : touche du clavier tapée

 Il existe une classe KeyAdapter.

 L'argument de ces méthodes est un objet KeyEvent,

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 30


L'interface KeyListener (2)
 Les méthodes associées à un objet KeyEvent :
 getKeyChar() dans keyTyped, qui renvoie le caractère associé à
la touche.
 getKeyCode()dans les 2 autres méthodes, qui renvoie un code
sous forme d'entier de type int pour les touches qui ne sont pas
associées à un caractère : flèches, F1, F2, ...., Suppr, etc...

 Les codes renvoyés par getKeyCode() correspondent à des


constantes définies dans la classe KeyEvent.
On a par exemple :
VK_CANCEL (touche Echap), VK_ENTER (touche Entrée),
VK_UP (flèche haut), etc...
Notation : VK pour Virtual Key
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 31
L'interface KeyListener (3)
 Exemple 1 de KeyListener :
// utilisation d'une classe dédiée
public class Clavier1 extends JFrame {
Clavier1() {
setTitle("Ecouteur du Clavier");
setSize(300, 100);
setVisible(true);
setDefaultCloseOperation(3);
addKeyListener(new EcouteurClavier());
}
public static void main(String[] args) {
new Clavier1();
}
}
class EcouteurClavier extends KeyAdapter {
public void keyReleased(KeyEvent ev){
if([Link]() == KeyEvent.VK_ESCAPE)
[Link]("Touche escape appuyée"); // dans la fenêtre
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 32
L'interface KeyListener (4)
 Exemple 2 de KeyListener :
// utilisation d'une classe interne anonyme
public class Clavier2 extends JFrame {
public Clavier2() {
setTitle("Ecouteur du Clavier");
setBounds(50, 100, 300, 300);
setDefaultCloseOperation(3);
JTextField champDeSaisie = new JTextField(20);

[Link](new KeyListener() {
public void keyTyped(KeyEvent ev) {
reponse(ev);
}
public void keyPressed(KeyEvent ev) {
// reponse(ev);
}
public void keyReleased(KeyEvent ev) {
reponse(ev);
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 33


L'interface KeyListener (5)
 Exemple 2 (suite) :
void reponse(KeyEvent ev) {
String keyString;
int id = [Link]();
if (id == KeyEvent.KEY_TYPED) {
char c = [Link]();
keyString = "caractère = '" + c + "'";
} else {
int keyCode = [Link]();
keyString = "code de la touche = " + keyCode + " (" +
[Link](keyCode) + ")";
}
[Link](keyString);
}
});

add(champDeSaisie);
setVisible(true);
}
public static void main(String[] args) {
new Clavier2();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 34
L'interface ItemListener (1)
Cette interface permet de réagir aux événements sémantiques liés à une sélection dans
une liste ou dans un groupe de cases à cocher.

ItemEvent : Un composant est sélectionné ou désélectionné,

Les composants sources de ItemEvent sont :


 Boutons : JComboBox, JButton, JToggleButton, JCheckBox

 Menus : JMenu, JMenuItem, JCheckBoxMenuItem,


JRadioButtonMenuItem

 Liste : Jlist
Pour associer l'écouteur d'événement à un composant, il faut utiliser la méthode
addItemListener().
Exemple :
Checkbox cb = new Checkbox("choix",true);
[Link](this);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 35


L'interface ItemListener (2)
Cette interface contient une seule méthode :
public void itemStateChanged(ItemEvent ev)

Il n’existe donc pas de classe ItemAdapter.


Pour connaitre l'état d'un objet source d'un événement ItemEvent, on
utilise la méthode getStateChange() qui retourne :
- [Link]
- [Link]

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 36


L'interface ItemListener (3)
Exemple :
import [Link].*;
public class TestItemListener implements ItemListener {
public void itemStateChanged(ItemEvent ev) {
// Lecture de l'état du bouton
int etat = [Link]();
if(etat == [Link]) {
// Actions effectuées quand le bouton a été sélectionné
...
}
else {
// Actions effectuées quand le bouton est désélectionné
...
}
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 37


L'interface ItemListener (4)
Exemple1 : Sélection d'un bouton à cocher
public class TestItemListener1 extends JFrame implements ItemListener{
public TestItemListenet1() {
setTitle("Choix);
Checkbox cb = new Checkbox("choix 1", true);
[Link](this);
add(cb);
setSize(250, 150);
setDefaultCloseOperation(3);
setVisible(true);
}
public void itemStateChanged(ItemEvent ev) {
int etat = [Link]();
if (etat == [Link])
[Link]("choix sélectionné");
else
[Link]("choix non sélectionné");
}
public static void main(String[] args) {
new TestItemListener1();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 38
L'interface ItemListener (5)
Exemple2 : Sélection d'un bouton à cocher
JCheckBox cb1 = new JCheckBox("choix 1", true);
[Link](new ItemListener() {
public void itemStateChanged(ItemEvent ev) {
int etat = [Link]();
if (etat == [Link])
[Link]("choix 1 sélectionné");
else
[Link]("choix 1 non sélectionné");
}
});
add(cb1);

JCheckBox cb2 = new JCheckBox("choix 2");


[Link](new ItemListener() {
public void itemStateChanged(ItemEvent ev) {
int etat = [Link]();
if (etat == [Link])
[Link]("choix 2 sélectionné");
else
[Link]("choix 2 non sélectionné");
}
});
add(cb2);
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 39
Interfaces Homme - Machine
Chapitre 6:
Gestions d'événements (3ème partie)
Dialogues prédéfinis

SMI - S6
Année universitaire 2017-2018

Prof. M.D. RAHMANI


mrahmani@[Link]
Plan
 La gestion des événements (3ème partie)
 FocusListener, recevoir ou perdre le focus
 TextListener, modification du texte entré,
 ComponentListener, déplacement, affichage, masquage ou
modification de taille de composants
 Dialogues prédéfinis :
 JColorChooser, choix de couleur
 JFileChooser, choix de fichier
 JProgressBar, barre de progression
 ProgressMonitor, dialogue de progression

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 2


Les principaux types d'écouteurs (2)
Ecouteur / Evénement Méthodes de l'écouteur Evénement généré par
ActionListener actionPerformed() AbstractButton,
ActionEvent Button, JComboBox,
JFileChooser,
JTextField, List,
Timer

FocusListener focusGained() Component


FocusEvent focusLost()
MouseListener mouseClicked() Component
MouseEvent mouseEntered()
mouseExited()
mousePressed()
mouseReleased()

MouseMotionListener mouseDragged() Component


MouseEvent mouseMoved()
KeyListener KeyPressed() Component
KeyEvent keyReleased()
keyTyped()

TextListener textValueChanged() TextComponent


TextEvent
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 3
Principaux types d'écouteurs (3)
Listeners / Event Méthodes de listener Générés par
ItemListener itemStateChanged() AbstractButton,
ItemEvent CheckBox, JComboBox,
ItemSelectable,
List,Choice,
CheckboxMenuItem
WindowListener windowActivated() Window
WindowEvent windowClosed()
windowClosing()
windowDeactivated()
windowDeiconified()
WindowIconified()
windowOpened()
ComponentListener componentHidden() Component
ComponentEvent componentShown()
componentMoved()
componentReized()
CaretListener caretUpdate() JTextComponent
CaretEvent
ListeSelectionListener valueChanged() JList,
ListeSelectionEvent ListSelectionModel
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 4
L'interface FocusListener (1)
- Un composant détient le focus s'il peut recevoir les frappes du clavier.
- Un seul composant peut détenir le focus à un moment donné .

- Il est possible de passer le focus à un autre composant :


- avec le clavier, en général avec une tabulation,
- avec la souris.

- par programmation : méthodes, demande, requestFocus et transfert,


transferFocus.

- Cette interface contient 2 méthodes :


public void focusGained(FocusEvent ev), recevoir le focus
public void focusLost(FocusEvent ev), perdre le focus
- ID de l'événement FocusEvent : FOCUS_GAINED et FOCUS_LOST
- Il existe une classe FocusAdapter
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 5
L'interface FocusListener (2)
Syntaxe :
public class Focus0 implements FocusListener {
public Focus0() {
[Link](this);
}
public void focusGained(FocusEvent ev) {
// traitement 1 associé au gain du focus
}
public void focusLost(FocusEvent ev) {
// traitement 2 associé à la perte du focus
}
}

Perte de focus d’un champ :


Il est parfois intéressant de s’assurer qu’un champ a été correctement saisi :
public void focusLost(FocusEvent ev) {
if (! [Link]() && ! isCorrect([Link]()))
[Link]();
}
 isTemporary retourne vrai si on est sûr de récupérer le focus (par exemple, parce
qu’on a sélectionné une autre fenêtre).
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 6
L'interface FocusListener (3)
Exemple 1 : Gain et Perte du focus par un composant
public class Focus1 extends JFrame implements FocusListener {
public Focus1() {
setLayout(new FlowLayout());
JButton b = new JButton("Réagit au Focus");
[Link](this);
add(b);
setTitle("Réaction au focus");
setSize(300, 150);
setDefaultCloseOperation(3);
setVisible(true);
} // un clic dans la fenêtre permet au bouton d'avoir le focus
public void focusGained(FocusEvent ev) {
[Link]("On a gagné le focus");
}
public void focusLost(FocusEvent ev) {
[Link]("On a perdu le focus");
}
public static void main(String [] args) {
new Focus1();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 7
L'interface FocusListener (4)
Exemple2 : Gain et Perte du focus par plusieurs composants
public class Focus2 extends JFrame implements FocusListener {
JTextField champ1, champ2;
JButton b = new JButton("Bouton");
public Focus2() {
setTitle("Test FocusListener 1");
JLabel eChamp1 = new JLabel("Champ1", [Link]);
champ1 = new JTextField(15);
[Link](this);
JLabel eChamp2 = new JLabel("Champ2", [Link]);
champ2 = new JTextField(15);
[Link](this);
JPanel p1 = new JPanel();
[Link](new GridLayout(2,2));
[Link](eChamp1); [Link](champ1);
[Link](eChamp2); [Link](champ2);
add(p1, [Link]);
[Link](this);
JPanel p2 = new JPanel();
[Link](b);
add(p2, [Link]);

setDefaultCloseOperation(3);
pack();
setVisible(true);
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 8
L'interface FocusListener (5)
Exemple2 (suite) : Gain et Perte du focus par plusieurs composants
public void focusGained(FocusEvent ev) {
if([Link]().equals(champ1)) // ou [Link]()==champ1
[Link]("Le champ de texte 1 a gagné le Focus du clavier.\n");
else if([Link]().equals(champ2))
[Link]("Le champ de texte 2 a gagné le Focus du clavier.\n");
else if([Link]().equals(b)) {
[Link]("Le bouton a gagné le focus du clavier.\n");
}
public void focusLost(FocusEvent ev) {
if([Link]().equals(champ1))
[Link]("\n Le Champ de texte 1 a perdu le focus du clavier.\n");
else if([Link]().equals(champ2))
[Link]("\n Le Champ de texte 2 a perdu le focus du clavier.\n");
else if([Link]().equals(b))
[Link]("\n Le bouton a perdu le focus du clavier.\n");
}
public static void main(String args[]) {
new Focus2();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 9


L'interface FocusListener (6)
Exemple3 : Gain et Perte du focus par plusieurs composants et écriture dans un autre composant
public class Focus3 extends JFrame {
Jlabel etiquette;
public Focus3() {
setTitle("Utilisation de FocusListener");
setLayout(new GridLayout(3,0));
JButton Ok = new JButton("Oui"); JButton Cancel = new JButton("Annuler");
[Link](new MonFocusListener());
[Link](new MonFocusListener());
add(Ok); add(Cancel);
etiquette = new JLabel("", [Link]); add(etiquette);
setSize(450, 200);
setVisible(true);
setDefaultCloseOperation(3);
}
private class MonFocusListener implements FocusListener {
public void focusGained(FocusEvent ev) {
JButton bouton = (JButton) [Link]();
[Link]([Link]()+" a gagné le focus");
}
public void focusLost(FocusEvent arg0) {}
}
public static void main(String[] args) {
new Focus3();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 10
L'interface TextListener (1)
 Cette interface permet de réagir aux modifications de la zone de saisie
ou du texte.

 L'événement généré par un objet de type TextComponent ou


Object est TextEvent

 La méthode addTextListener() permet à un composant d'écouter


un composant de texte.

 La méthode textValueChanged() reçoit les événements.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 11


L'interface TextListener (2)
Exemple 1 : Copie du texte entré au clavier dans un champ de texte vers la console
public class Texte1 extends JFrame {
public Texte1() {
setTitle("Exemple de TextListener");
setDefaultCloseOperation(3);
TextField t = new TextField(40); // pas JTextField
add(t, [Link]);
pack();
setVisible(true);
[Link](new TextListener() {
public void textValueChanged(TextEvent ev) {
TextComponent tc = (TextComponent)[Link]();
[Link]("Le texte tapé: " + [Link]());
}
/* ou public void textValueChanged(TextEvent ev) {
Object source = [Link]();
[Link]("saisi = "+((TextField)source).getText());
}
*/ });
}
public static void main(String args[]) {
new Texte1();
}
} Console: Le texte tapé: SMI S6
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 12
L'interface TextListener (3)
Exemple 2 : Copie du texte entré au clavier dans un champ de texte vers un autre
public class Texte2 extends JFrame {
public Texte2(){
setTitle("Utilisation de TextListener");
setSize(400,200);
setDefaultCloseOperation(3);
setLayout(new GridLayout(0,1));
setVisible(true);
JLabel eTitre = new JLabel("Copie d'un champ de texte vers un autre", [Link]);
TextField champ = new TextField(30);
TextField copie = new TextField(30);
JPanel panneau = new JPanel();
[Link](champ);
[Link](copie);
add(eTitre);
add(panneau);
[Link](new TextListener(){
public void textValueChanged(TextEvent ev) {
[Link]("Copie => " + [Link]());
}
});
}
public static void main(String[] args){
new Texte2();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 13
L'interface ComponentListener (1)
ComponentListener: déplacement, affichage, masquage ou
modification de taille de composants

Méthodes : componentMoved(ComponentEvent ev)


componentShown(ComponentEvent ev)
componentHidden(ComponentEvent ev)
componentResized(ComponentEvent ev)

Evénements ComponentEvent générés par : Component

L'écoute se fait par la méthode addComponentListener

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 14


L'interface ComponentListener (2)
Exemple : Utilisation de ComponentListener sur un cadre de type JFrame
public class EssaiComponentListener extends JFrame {
public EssaiComponentListener() {
setTitle(" Utilisation ComponentListener ");
setSize(400, 150); setDefaultCloseOperation(3); setVisible(true);

addComponentListener(new ComponentListener(){
public void componentShown(ComponentEvent ev) {
[Link](" visible ");
}
public void componentHidden(ComponentEvent ev) {
[Link](" caché ");
}
public void componentMoved(ComponentEvent ev) {
[Link](" déplacé ");
}
public void componentResized(ComponentEvent ev) {
[Link](" redimensionné ");
}
});
}
public static void main(String[] args) {
new EssaiComponentListener();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 15
Plan

 Dialogues prédéfinis :
 JColorChooser, choix de couleur
 JFileChooser, choix de fichier
 JProgressBar, barre de progression
 ProgressMonitor, dialogue de progression

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 16


Le dialogue de sélection d'une couleur JColorChooser (1)
Cette classe [Link] possède une méthode
statique showDialog qui permet d’ouvrir une boite prédéfinie proposant
l’ensemble des couleurs 24 bits possibles.

La méthode prend en paramètre :


 le composant parent de la boite,
 une chaîne de caractères à placer dans la barre de titre
 la couleur sélectionnée initialement

et retourne la couleur sélectionnée par l’utilisateur.

Color couleur = [Link](parent, "Choix d'une couleur",


[Link]);

couleur un objet de type Color, retourne la couleur sélectionnée.


Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 17
Le dialogue de sélection d'une couleur JColorChooser (2)

Exemple 1 : boite de choix d'une couleur

import [Link];
import [Link];
public class ChoixCouleur1 {
public static void main(String[] args) {
// Boite du dialogue du choix de la couleur
Color couleur = [Link](null,"Choix d'une couleur", [Link]);

// Test du choix et affichage


if (couleur == null) {
[Link]("Vous n'avez pas choisi ou vous avez fermé"); //si Annuler ou Fermer
} else {
[Link]("Votre couleur choisie est: " + couleur);
}
}
}
Console :
Votre couleur choisie est: [Link][r=0,g=204,b=153]
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 18
Le dialogue de sélection d'une couleur JColorChooser (3)
Exemple2 : boite de choix d'une couleur avec écouteur d'événements
class ChoixCouleur2 extends JFrame implements ActionListener {
JTextField texte = new JTextField("Un champ de texte qui change de couleur");
public ChoixCouleur2() {
setTitle("Choix d'une couleur");
JPanel panneau = new Jpanel(new BorderLayout());
[Link](new Dimension(350, 60));
JButton bouton = new JButton("choisir une couleur");
[Link](this); // un clic sur le bouton déclenche l'appel de la boite de dialogue
[Link](bouton, [Link]);
[Link](texte, [Link]);
add(panneau);
setDefaultCloseOperation(3);
setLocation(100, 100);
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent ev) {
Color couleur = [Link]
(null, "Couleur du fond", [Link]);
[Link](couleur);
}
public static void main(String[] arg) {
new ChoixCouleur2();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 19


Le dialogue de sélection de fichiers JFileChooser (1)
JFileChooser est un moyen pour créer les boites de dialogue pour
ouvrir, sauvegarder et visualiser les fichiers et les dossiers.

Pour faire apparaître la boite de dialogue JFileChooser, il suffit de


taper ces deux lignes de code:
// Contrairement aux boites de dialogues, un objet de type JFileChooser doit être crée
JFileChooser fc = new JFileChooser();
// la réponse quand un bouton est cliqué
int retour = [Link](composant_parent);

showOpenDialog ouvre la boite de dialogue d'ouverture de fichiers.


Cette méthode retourne une des trois valeurs possibles qui mentionnent
laquelle des options est choisie par l'utilisateur:
 JFileChooser.CANCEL_OPTION: l'utilisateur a annulé l'ouverture;
 JFileChooser.APPROVE_OPTION: l'utilisateur a validé l'ouverture;
 JFileChooser.ERROR_OPTION: une erreur est survenue.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 20
Le dialogue de sélection de fichiers JFileChooser (2)

Cette classe propose trois méthodes pour afficher un dialogue


d’ouverture de fichiers.
o showOpenDialog présente une boite de dialogue pour l’ouverture
d’un fichier,
o showSaveDialog une boite de dialogue pour la sauvegarde d’un
fichier,
o showDialog permet de spécifier des chaînes de caractères pour le
bouton de validation et le titre de la fenêtre afin de créer des boîtes
personnalisées.

Les trois méthodes renvoient un entier dont la valeur


correspond au bouton qui a été cliqué.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 21


Le dialogue de sélection de fichiers JFileChooser (3)
La méthode getSelectedFile renseigne sur le nom du fichier
sélectionné.
if ([Link](parent)== JFileChooser.APPROVE_OPTION){
[Link]("Le fichier est:"+[Link]());
}

Si la valeur de retour vaut JFileChooser.APPROVE_OPTION, la


valeur retourné est une instance de la classe File.

On obtient le nom du fichier avec getName() et son chemin absolu


avec getAbsolutePath().

Si l'utilisateur annule l'opération, un message s'affiche indiquant


l'annulation.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 22


Le dialogue de sélection de fichiers JFileChooser (4)
Exemple 1 : Cet exemple fait apparaître la boite de dialogue, sélectionne le fichier choisi:
import [Link];
import [Link];
public class ChoixFichier1 {
public ChoixFichier1() {
JFileChooser choix = new JFileChooser();
[Link](new File(".")); // le répertoire courant
int valeur = [Link](null);

if (valeur == JFileChooser.APPROVE_OPTION) {
File fichierSelectionne = [Link]();
[Link]("vous avez sélectionné : " + fichierSelectionne );
[Link]("\nnom du fichier: "+[Link]().getName());
[Link]("\nchemin absolu : "+[Link]().
getAbsolutePath());
}
}
public static void main(String[] arg) {
new ChoixFichier1();
}
}

Sur la console : vous avez sélectionné : fichier choisi avec son chemin
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 23
Le dialogue de sélection de fichiers JFileChooser (5)
Fichier et/ou répertoire :

 La méthode setFileSelectionMode permet à l'utilisateur de sélectionner


parmi des fichiers et/ou des répertoires.

 Cette méthode prend en paramètre l’une des valeurs suivantes :


 JFileChooser.FILES_ONLY // la valeur par défaut
 JFileChooser.DIRECTORIES_ONLY // uniquement les répertoires
 JFileChooser.FILES_AND_DIRECTORIES // les deux

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 24


Le dialogue de sélection de fichiers JFileChooser (6)
Exemple 2 : Affichage des répertoires uniquement.
import [Link];
import [Link];
public class ChoixFichier2 {
public ChoixFichier2() {
JFileChooser choixFichier = new JFileChooser();
[Link](JFileChooser.DIRECTORIES_ONLY);
int valeur = [Link](null);
if (valeur == JFileChooser.APPROVE_OPTION) {
File fichierSelectionne = [Link]();
[Link]("vous avez sélectionné : " + fichierSelectionne );
[Link]("\nnom du fichier: "+[Link]().getName());
[Link]("\nchemin absolu : "+[Link]().
getAbsolutePath());
}
}
public static void main(String[] args) {
new ChoixFichier2();
}
}

Sur la console : vous avez sélectionné : le répertoire choisi avec son chemin

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 25


Le dialogue de sélection de fichiers JFileChooser (7)
Pour ouvrir plusieurs fichiers, on doit déclarer l'objet de type File
sous forme d'un tableau rassemblant les fichiers sélectionnés.
On doit aussi demander à JFileChooser de nous donner la
possibilité de sélectionner plusieurs fichiers en utilisant
setMultiSelectionEnabled().
JFileChooser choix = new JFileChooser();
[Link](true) ;
int retour = [Link](parent);
if(retour == JFileChooser.APPROVE_OPTION){
// des fichiers ont été choisis
// (sortie par OK)
File[] fs=[Link]();
for( int i = 1; i<[Link]; ++i){
// nom du fichier
fs[i].getName());
// chemin absolu du fichier
fs[i].getAbsolutePath();
}
}else ... ; // pas de fichier choisi

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 26


Le dialogue de sélection de fichiers JFileChooser (8)
Exemple 3 : Cet exemple fait apparaître la boite de dialogue, sélectionne plusieurs fichiers:
import [Link];
import [Link];
public class ChoixMultiple {
public ChoixMultiple() {
JFileChooser choix = new JFileChooser();
[Link](true) ;
[Link](new File("."));
int valeur = [Link](null);
if (valeur == JFileChooser.APPROVE_OPTION) {
File[] fs=[Link]();
for( int i = 1; i<[Link]; ++i){
fs[i].getName(); // nom du fichier
fs[i].getAbsolutePath(); // chemin absolu du fichier
}
}
else [Link]("\n vous avez annulé");
}
public static void main(String[] args) {
new ChoixMultiple();
}
}
Sur la console : sélection de plusieurs fichiers avec CTRL + click
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 27
Le dialogue de sélection de fichiers JFileChooser (9)
Utilisation avec filtre: Les filtres permettent de ne visualiser que certains fichiers en
fonction de leurs suffixes. Il faut d’abord créer ces filtres, puis les ajouter au JFileChooser.
Exemple 4 : Un filtre des fichiers "word" et des répertoires.
import [Link];
import [Link];
import [Link];
public class TestChoixSelectif {
public static void main(String[] args) {
// Créer un filtre pour montrer uniquement les fichiers Word et les répertoires
FileFilter filtre = new FileFilter() {
@Override
public boolean accept(File f) {
if ([Link]()) {
return true;
}
String typeFichier = [Link]().toLowerCase();
if ([Link](".docx")) {
return true;
}
return false; // Rejeter les autres types de fichiers
}
@Override
public String getDescription() {
return "Document word";
}
};
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 28
Le dialogue de sélection de fichiers JFileChooser (10)
Utilisation avec filtre
Les filtres permettent de ne visualiser que certains fichiers en fonction de leurs
suffixes. Il faut d’abord créer ces filtres, puis les ajouter au JFileChooser.
Exemple 4 (suite): Un filtre des fichiers "word" et des répertoires.

// Ajouter le filtre
JFileChooser choixFichier = new JFileChooser();
[Link](filtre);

int returnValue = [Link](null, "Filtre du type de fichiers");


if (returnValue == JFileChooser.APPROVE_OPTION) {
}
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 29
Le dialogue de sélection de fichiers JFileChooser (11)

Utilisation multiple avec filtre :


On peut créer des instances des classes de filtres :
FileFilter filtreT = new FileFilter(new String[]{"txt"}, "les fichiers texte (*.txt)");

FileFilter filtreI = new FileFilter(new String[]{"gif","png", "jpeg"},


"les fichiers image (*.gif, *.png, *.jpeg)");

Et on les ajoute au dialogue choix de fichier :


JFileChooser choix = new JFileChooser();
[Link](filtreT);
[Link](filtreI);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 30


Les barres de progression : JProgressBar (1)
Une barre de progression est une boîte de dialogue, qu'on peut
placer dans un conteneur.

Elle permet à l'utilisateur d'être informé du déroulement d'une tâche


en cours, elle peut donner 3 informations :
 la proportion de travail qui a été effectuée,
 la proportion de travail restant / travail total,
 la vitesse relative d'exécution de la tâche.

Ces informations sont particulièrement appréciables lorsque


l'opération en question est lente...

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 31


Les barres de progression : JProgressBar (2)
 Création d'une barre de progression
JProgressBar()
JProgressBar(int orientation)
JProgressBar(int min, int max)
JProgressBar(int orientation, int min, int max)
JProgressBar(BoundedRangeModel newModel)

Un objet de type JProgressBar crée une barre de progression,


par défaut horizontale, mais il est possible de spécifier son orientation
([Link] ou [Link]).

Les valeurs min (pas de travail effectué) et max (tâche finie)


définissent les bornes inférieure et supérieure de la barre de progression.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 32


Les barres de progression : JProgressBar (3)
Exemple 1 : Création d'une barre de progression
public class BarreDeProgression1 extends JFrame {
BarreDeProgression1 () {
setTitle("Barre de progression");
setDefaultCloseOperation(3);
JProgressBar bar = new JProgressBar();
[Link](25);
[Link](true); // pour voir le pourcentage
Border border =
[Link]("Traitement...");
[Link](border);
add(bar, [Link]);
setSize(300, 100);
setVisible(true);
}

public static void main(String args[]) {


new BarreDeProgression1();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 33


Les barres de progression : JProgressBar (4)
Exemple 2 : Un bouton qui permet le redémarrage de la barre
public class BarreDeProgression2 extends JFrame {
private Thread t;
private JProgressBar bar;
private JButton lancer ;
public BarreDeProgression2(){
[Link](300, 80);
[Link]("Barre de progression");
[Link](3);
t = new Thread(new Traitement());
bar = new JProgressBar();
[Link](500);
[Link](0);
[Link](true); // montrer le pourcentage
[Link](bar, [Link]);
lancer = new JButton("Demarrage");
[Link](new ActionListener(){
public void actionPerformed(ActionEvent event){
t = new Thread(new Traitement());
[Link]();
}
});
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 34
Les barres de progression : JProgressBar (5)
Exemple (suite) :
[Link](lancer, [Link]);
[Link]();
[Link](true);
}
class Traitement implements Runnable {
public void run(){
[Link](false);
for(int val = 0; val <= 500; val++){
[Link](val);
try {
[Link](10);
} catch (InterruptedException e) {
[Link]();
}
}
[Link](true);
}
}
public static void main(String[] args){
new BarreDeProgression2();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 35
Les dialogues de progression : ProgressMonitor (1)

Un dialogue de progression affiche une barre de progression dans


une fenêtre de dialogue séparée.
Il donne la possibilité à l'utilisateur d'interrompre l'exécution de la
tâche en cours.
Contrairement à une barre de progression simple, un dialogue de
progression ne peut pas être réutilisé, il faut donc en instancier un nouveau
à chaque utilisation.
ProgressMonitor(Component parentComponent, Object message,
String information, int min, int max)
Crée un dialogue de progression rattaché au composant
parentComponent, et qui comporte un message, une information d'état et
les bornes min et max spécifiés.
Exemple :
progressMonitor = new ProgressMonitor(null, "Boîte de dialogue de
progression", "Initialiation . . .", 0, 100);
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 36
Les dialogues de progression : ProgressMonitor (2)
Exemple : utilisation d’une boîte de dialogue de progression à l’aide de ProgressMonitor

public class ExempleProgressMonitor extends JFrame implements ActionListener {


static ProgressMonitor progressMonitor;
static int compteur = 0;

public ExempleProgressMonitor( ) {
setSize("Dialogue de progression");
setSize(300,100);
setDefaultCloseOperation(3);
// Créer un objet ProgressMonitor
progressMonitor = new ProgressMonitor(null, "Boîte de dialogue de progression",null,
0, 100);
// Mise à jour de l'état de la barre de progression avec un Timer.
Timer timer = new Timer(500, this);
[Link]( );
setVisible(true);
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 37


Les barres de progression : ProgressMonitor (3)
// Mise à jour chaque 0.5 seconde
public void actionPerformed(ActionEvent e) {
[Link](new Update( ));
}
class Update implements Runnable {
public void run( ) {
if ([Link]( )) {
[Link]( );
[Link](1);
}
[Link](compteur+"% Terminé");
compteur += 2; // incrémentation par 2
[Link](compteur);
}
}

public static void main(String args[]) {


// Définir les propriétés de la boîte de dialogue
[Link]("[Link]", "Barre de progression");
[Link]("[Link]", "Annuler l'opération");
new ExempleProgressMonitor( );
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 38
Interfaces Homme - Machine
Chapitre 7 :
Les Menus

SMI - S6
Année universitaire 2017-2018
Prof. M.D. RAHMANI
mrahmani@[Link]
Plan
 Hiérarchie des composants pour les menus,
 Les composants d'un menu:
 JMenuBar
 JMenu
 Eléments d'un menu:
 JMenuItem
 JRadioButtonMenuItem
 JCheckButtonMenuItem
 Menu surgissant JPopupMenu
 Création d'un menu
 Imbrication des composants
 Construction d'un menu avec écouteurs
 Menu surgissant
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 2
Les menus (1)
Les menus peuvent être crées de 2 manières :

 Les menus déroulants (Drop-Down Menu) : les éléments,


généralement rassemblés dans une barre de menus (JMenuBar), sont
affichés (déroulés) lorsque l'utilisateur clique sur le titre de l'élément
(JMenu).

 Les menu contextuels, surgissants (Popup Menu) : les éléments sont


affichés en réaction à un clique sur le bouton droit de la souris et sont
présentés dans une fenêtre Pop-up indépendante (JPopupMenu) qui
est affiché à l'emplacement où l'on a déclenché le menu contextuel.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 3


Les menus (2)

 Contrairement aux menus déroulants JMenu, les composants contextuels


JPopupMenu nécessitent de définir un gestionnaire d'événement pour
déclencher l'affichage.

 L'affichage d'un menu contextuel est effectué par invocation de la méthode


show() de JPopupMenu associée à l'interface MouseListener.

Caractéristiques : Les éléments de menu peuvent :


contenir une image,
être de type bouton radio ou case à cocher,
avoir des raccourcis clavier, sous forme de mnémoniques ou d'accélérateurs.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 4


Les composants d'un Menu
Les menus sont mis en œuvre avec un ensemble de classes:
 JMenuBar: Une barre de menus contenant des composants JMenu,
 JMenu: Un menu déroulant ou un sous-menu représenté par une étiquette (titre),
 JMenuItem: Un élément (option) d'un menu ou d'un sous-menu,
 JRadioButtonMenuItem: Un élément d'un menu sous la forme d'un bouton radio,
 JCheckBoxMenuItem: Un élément d'un menu sous la forme d'une case à cocher,
 JSeparator, Un élément d'un menu sous la forme d'un séparateur de groupes
d'options,
 JPopupMenu, Un menu contextuel (surgissant),
 Toutes ces classes héritent de la classe JComponent.
 Les éléments de menus cliquables héritent de la classe JAbstractButton.
 MenuShortcut, ajout d'accélérateurs.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 5


Hiérarchie des composants pour les menus
Object

Component

Container

JComponent MenuShortcut

JMenuBar JPopupMenu JAbsractButton JSeparator

JMenuItem

JMenu JCheckboxMenuItem JRadioButtonMenuItem

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 6


Les composants d'un Menu (1)
1- La classe JMenuBar:
La construction de menus commence par la création d'une barre de menu
JMenuBar,
JMenuBar mb = new JMenuBar(); // création de la barre de menu

Pour ajouter des menus dans une barre de menu, on utilise la méthode add(),
[Link](unMenu); // ajout d'un menu à la barre de menu

Pour ajouter la barre de menu à une fenêtre, on utilise la méthode


setJMenuBar(mb),
[Link](mb); // association à une fenêtre

Remarque: Comme la classe JMenuBar hérite de la classe JComponent, il


est possible de créer plusieurs objets de type JMenuBar et de les positionner
par un gestionnaire de placement.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 7


Les composants d'un Menu (2)
2- La classe JMenu: Cette permet de créer un menu.
Un menu sera composé d'un ou plusieurs éléments (items) de menu.
JMenu menu = new JMenu(); // créer un menu
[Link]("Mon Menu"); // affecter le texte au menu
// affecter une icône au menu
[Link](new ImageIcon(getImage("./[Link]")));
[Link](KeyEvent.VK_M); // affecter le raccourci alt+M
[Link](menu); // ajouter le menu dans la barre de menu

Un menu peut être ajouté à un autre menu : on parle alors de sous-menus.

Pour ajouter des items dans un menu ou un sous menu:


[Link](unItem)

Pour insérer une séparation dans la liste des items


[Link]()
Remarque : Lire VK, value of key ou virtual key
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 8
Les composants d'un Menu (3)
3- Eléments de menu : items (options) d'un menu ou d'un sous menu.
Il y a trois sortes d'éléments de menu :

3.1- La classe JMenuItem


Ce composant permet de créer un élément de menu.
Cet item peut être muni d'un texte, d'une icône, d'un raccourci et d'un accélérateur.
Il peut être actif ou inactif.

JMenuItem mi = new JMenuItem(); // création

[Link](new ImageIcon(getImage("./[Link]"))); // affectation d'une image

[Link]("le texte"); // affectation du texte

[Link](true); // l'item de menu est actif

[Link](mi); // ajout de l'item à un menu

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 9


Les composants d'un Menu (4)
3- Item de menu
3.2- La classe JRadioButtonMenuItem
Un item de menu peut être un bouton radio. Il permet de faire des choix exclusifs :
on utilise un ButtonGroup pour grouper les boutons radio : un seul bouton du groupe peut
être sélectionné.

JRadioButtonMenuItem jrb1 = new JRadioButtonMenuItem();


[Link](true); // bouton choisi par défaut
JRadioButtonMenuItem jrb2 = new JRadioButtonMenuItem();
JRadioButtonMenuItem jrb3 = new JRadioButtonMenuItem();
ButtonGroup bg = new ButtonGroup();

[Link](jrb1);
[Link](jrb2);
[Link](jrb3);
3.3- La classe JCheckButtonMenuItem
Un item de menu peut être une case à cocher.
Les méthodes isSelected() et setSelected(boolean b) permettent de
savoir si une case est cochée, et de la cocher ou de la décocher.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 10


Création d'un menu (1)
Classes utilisées:

JMenuBar: représente la barre de menu d'une fenêtre,


Fichier Aide
JMenu: options visibles dans la barre de menu, Nouveau A propos
Quitter
JmenuItem: Item qui déclenchera par sa sélection
une action définie par le programmeur.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 12


Création d'un menu (2)
Exemple 1: [Link]
import [Link].*;
public class MenuEditeur1 extends JMenuBar {
JMenuItem nouveau, ouvrir, quitter, aPropos;
public MenuEditeur1() {
JMenu menuFichier = new JMenu("Fichier"); // création des éléments du menu
nouveau = new JMenuItem("Nouveau");
ouvrir = new JMenuItem("Ouvrir");
quitter = new JMenuItem("Quitter");
// ajout des éléments JMenuItem dans un JMenu
[Link](nouveau);
[Link](ouvrir);
[Link](); // pour séparer
[Link](quitter);
JMenu menuAide = new JMenu("Aide");
aPropos = new JMenuItem("A propos");
[Link](aPropos);
// ajout des objets JMenu dans la barre de menus
add(menuFichier);
add(menuAide);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 13
Création d'un menu (3)
Exemple 1 (suite): [Link]
import [Link].*;
public class FenetreAvecMenu extends JFrame {
public FenetreAvecMenu(){
setTitle("Fenêtre avec menu");
setSize(400,200);
setJMenuBar(new MenuEditeur1());
setVisible(true);
}

public static void main(String[] args) {


new FenetreAvecMenu();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 14


Création d'un menu (4)
Exemple 1 (2ème version): [Link]
public class MenuEditeur2 extends JFrame {
public MenuEditeur2() {
JMenu menuFichier = new JMenu("Fichier"); // création des éléments du menu
JMenuItem nouveau = new JMenuItem("Nouveau");
JMenuItem ouvrir = new JMenuItem("Ouvrir");
JMenuItem quitter = new JMenuItem("Quitter");
[Link](nouveau); // ajout des éléments JMenuItem dans un JMenu
[Link](ouvrir);
[Link](); // pour séparer
[Link](quitter);
JMenu menuAide = new JMenu("Aide");
JMenuItem aPropos = new JMenuItem("A propos");
[Link](aPropos);
// création de la barre de menu et ajout des objets JMenu
JMenuBar bar = new JMenuBar();
[Link](menuFichier);
[Link](menuAide);
setTitle("Fenêtre avec menu");
setSize(400,200);
setJMenuBar(bar);
setVisible(true);
}
public static void main(String[] args) {
new MenuEditeur2();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 15
Positionnement de menus (1)
JMenuBar est un composant qui dérive de JComponent, par conséquent nous
pouvons créer autant de composants JMenuBar et les positionner dans une fenêtre.
Exemple 2: [Link]
public class MenuEditeur extends JMenuBar {
JMenuItem nouveau, ouvrir, quitter, aPropos;
public MenuEditeur() {
JMenu menuFichier = new JMenu("Fichier"); // création des éléments du menu
nouveau = new JMenuItem("Nouveau");
ouvrir = new JMenuItem("Ouvrir");
quitter = new JMenuItem("Quitter");

[Link](nouveau); // ajout au menu des éléments de menu


[Link](ouvrir);
[Link](); // pour séparer
[Link](quitter);
JMenu menuAide = new JMenu("Aide");
aPropos = new JMenuItem("A propos");
[Link](aPropos);
add(menuFichier); // ajout des menus à la barre de menu
add(menuAide);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 16
Positionnement de menus (2)
Exemple 2 (suite): [Link]
import [Link].*;
public class FenetreAvec2Menus extends JFrame {
public FenetreAvec2Menus(){
setTitle("Fenêtre avec 2 menus");
setSize(400,200);
add(new MenuEditeur(), [Link]);
add(new MenuEditeur(), [Link]);

setVisible(true);
}

public static void main(String[] args) {


new FenetreAvec2Menus();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 17


Imbrication de menus (1)
Exemple 3 : [Link]
import [Link].*;
public class MenuEditeurP extends JMenuBar {
public MenuEditeurP() {
// création des éléments du menu
JMenu menuFichier = new JMenu("Fichier");
JMenuItem nouveau = new JMenuItem("Nouveau");
JMenuItem ouvrir = new JMenuItem("Ouvrir");
JMenuItem quitter = new JMenuItem("Quitter");

[Link](nouveau);
[Link](ouvrir);
[Link]();
[Link](quitter);

JMenu menuAide = new JMenu("Aide");


JMenuItem aPropos = new JMenuItem("A propos");
[Link](aPropos);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 18


Imbrication de menus (2)
Exemple 3 (suite) : [Link]
JMenu divers = new JMenu("Divers");
JMenu sousMenu1 = new JMenu("Sous menu 1");
[Link](sousMenu1);
JMenu sousMenu2 = new JMenu("Sous menu 2"); // prêt à recevoir des sous menus
[Link](sousMenu2);

JMenu sousMenu11 = new JMenu("Sous Menu 11");


[Link](sousMenu11);
JMenuItem cas11 = new JMenuItem("Cas 11");
[Link](cas11);

JMenuItem cas1 = new JMenuItem("Cas 1");


[Link](cas1);
JMenuItem cas2 = new JMenuItem("Cas 2");
[Link](cas2);

add(menuFichier);
add(menuAide);
add(divers);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 19


Imbrication de menus (3)
Exemple 3 (suite): [Link]
import [Link].*;
public class MenusImbriques extends JFrame {
public MenusImbriques(){
setTitle("Imbrication de menus");
setSize(400,200);
setJMenuBar(new MenuEditeurP());
setVisible(true);
}

public static void main(String[] args) {


new MenusImbriques();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 20


Imbrication des composants (1)
Exemple 4: ajout d'une barre d'outil à l'éditeur graphique [Link]
import [Link].*;
import [Link].*;
public class BarreOutils extends JPanel {
public BarreOutils(){
String[] etiquetteCouleurs = {"Bleu", "Rouge", "Jaune", "Vert"};
[Link]([Link]);
JComboBox listeCouleurs = new JComboBox(); // liste déroulante
for (int i=0; i<[Link]; i++)
[Link](etiquetteCouleurs[i]);
// l'ajout de la barre d'outils
[Link](listeCouleurs);
[Link](new JButton("Sauvegarder"));
[Link](new JButton("Tout effacer"));
[Link](new JButton("Quitter"));
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 21


Imbrication des composants (2)
[Link]
import [Link].*;
import [Link].*;
public class FenetreAvecBarreOutils extends JFrame {
public FenetreAvecBarreOutils(){
setTitle("Fenêtre avec barre d'outils");
setSize(400,300);
setJMenuBar(new MenuEditeur());
add(new BarreOutils());
setVisible(true);
}
public static void main(String[] args) {
new FenetreAvecBarreOutils();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 22


Les raccourcis clavier (1)
Les éléments de menus peuvent être associés à 2 types de raccourcis claviers:
 Les mnemonics : ils apparaissent sous la forme d'une lettre soulignée,
ils sont utilisables en combinaison avec la touche Alt.
Les mnémoniques concernent les menus et les éléments de menus
JMenuItem mi = new JMenuItem();
[Link](KeyEvent.VK_I); // affectation du raccourci alt+I
ou JMenuItem mi = new JMenuItem("Item",'I'); // valable uniquement pour un item

 Les accélérateurs : (hérités de JComponent) sont des touches


(peuvent être des touches de fonction) ou des combinaisons de touches
avec les touches Shift, Ctrl ou Alt qui sont affichés à la droite de
l'étiquette de l'élément du menu.
[Link]([Link](KeyEvent.VK_Z,
InputEvent.CTRL_MASK)); // affectation de l'accélérateur ctrl+z

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 23


Les raccourcis clavier (2)
o Un mnémonique est un caractère alphanumérique unique souligné dans un
nom de menu ou d'un élément de menu.
 On agit sur un menu de caractère mnémonique C en frappant la
combinaison Alt et C.
 Si le menu est affiché, on agit sur un élément de menu de caractère
mnémonique C en frappant uniquement ce caractère.
 Pour associer un caractère mnémonique à un menu ou à un élément de
menu, on utilise la méthode setMnemonic de la classe
AbstractButton comme suit :
JMenu unMenu = new JMenu("Menu1");
[Link]('M'); // M est le caractère mnémonique du menu unMenu.
ou [Link](KeyEvent.VK_M); // affectation du raccourci alt+M
JMenuItem item1 = new JMenuItem("Item1");
[Link]('I'); // I est le caractère mnémonique de l'élément item1
 Une autre forme possible valable uniquement pour un item et non un
menu: Jmenu item1 = new JMenuIem("Item1",'I')
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 24
Les raccourcis clavier (3)
o Un accélérateur est une combinaison de touches qu'on associe à un
élément de menu (pas à un menu) et qui s'affiche à droite de son nom.
• Même si le menu n'est pas affiché, l'appui sur la combinaison des
touches de l'accélérateur provoque la sélection de l'élément
correspondant.
• Pour associer un accélérateur à un élément de menu, on utilise la
méthode setAccelerator de la classe JMenuItem, à laquelle on
fournit, en argument, la combinaison de touches voulue.
 Pour cela, on utilise la méthode getKeyStroke de la classe
KeyStroke comme suit:
[Link](KeyEvent.VK_I, // touche I
InputEvent.CTRL_MASK); // + touche CTRL

 Association de la combinaison CTRL+I à un élément item1 :


JMenuItem item1 = new JMenuItem("Item1");
[Link]([Link](KeyEvent.VK_I,
InputEvent.CTRL_MASK));
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 25
Les raccourcis clavier (4)
Exemple 5 : menu avec mnémoniques et accélérateurs,
public class MenuAvecRaccourcis extends JFrame implements ActionListener {
JMenu couleur;
JMenuItem rouge, vert;
public MenuAvecRaccourcis() {
setTitle("Un menu avec raccourcis");
setSize(350, 100);
JMenuBar barreMenus = new JMenuBar(); // création de la barre de menus
setJMenuBar(barreMenus);
// création des menus et éléments de menus
couleur = new JMenu("Couleur"); [Link]('C');
[Link](couleur);

rouge = new JMenuItem("Rouge"); [Link]('R');


[Link](
[Link](KeyEvent.VK_R, InputEvent.CTRL_MASK));
[Link](rouge);
[Link](this);
vert = new JMenuItem("Vert"); [Link]('V');
[Link]([Link](
KeyEvent.VK_V, InputEvent.CTRL_MASK));
[Link](vert);
[Link](this);
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 26
Les raccourcis clavier (5)
Exemple 5 (suite) : menu avec mnémoniques et accélérateurs,

public void actionPerformed(ActionEvent ev) {


[Link]("Action avec chaine de commande = " +
[Link]());
if([Link]()==rouge) [Link]("Action option rouge");
if([Link]()==vert) [Link]("Action option vert");
}

public static void main(String[] args) {


MenuAvecRaccourcis mr = new MenuAvecRaccourcis();
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 27


Les raccourcis clavier (6)

 Nous pouvons associer plus d'une touche de commande à un accélérateur:

 Exemple: le cas de Ctrl + Maj + R


JMenItem item = new JMenuItem("Rouge");
[Link]([Link](KeyEvent.VK_R,
KeyEvent.CTRL_MASK + KeyEvent.SHIFT_MASK));

Remarque: On peut utiliser pour les touches de comande les 2 formes suivantes,

KeyEvent.CTRL_MASK ou InputEvent.CTRL_MASK

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 28


Les raccourcis clavier (7)
Exemple 5 : menu avec mnémoniques et accélérateurs,
public class MenuAvecRaccourcis2 extends JFrame implements ActionListener {
JMenuItem rouge;
public MenuAvecRaccourcis2() {
setTitle("Un menu avec raccourcis");
setSize(350, 100);
JMenuBar barreMenus = new JMenuBar();
setJMenuBar(barreMenus);
JMenu couleur = new JMenu("Couleur"); [Link]('C');
[Link](couleur);
rouge = new JMenuItem("Rouge"); [Link]('R');
[Link](
[Link](KeyEvent.VK_R, InputEvent.CTRL_MASK +
InputEvent.SHIFT_MASK )); // Ctrl + Maj + R
[Link](rouge);
[Link](this);
}
public void actionPerformed(ActionEvent ev) {
if([Link]()==rouge) [Link]("Action option rouge");
}
public static void main(String[] args) {
MenuAvecRaccourcis2 mr = new MenuAvecRaccourcis2();
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 29
Ajout d'une icone (1)
 Ajout d'une icône à un élément JItem de menu:
Les éléments d'un menu héritent comme les boutons de
JAbstractButton, ils peuvent contenir une étiquette, une image ou les 2.
 Nous pouvons spécifier une icône à l'aide des constructeurs suivant:

 JMenuItem(String etiquette, Icon icone); // icone et étiquette


 JMenuItem(Icone icone); // icone sans étiquette
 après la création, à l'aide de la méthode setIcon();

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 30


Ajout d'une icone (2)
Exemple 6 : Ajout d'icônes,
class MenuAvecIcones extends JFrame{
public MenuAvecIcones() {
setTitle ("Editeur avec icônes"); setSize (300, 150); setVisible(true);
JMenuBar barreMenus = new JMenuBar() ; /* création barre des menus */
setJMenuBar(barreMenus) ;
JMenu edition = new JMenu ("Edition") ;
[Link](edition) ;
/* création, ajour des items et lien avec écouteurs */
[Link](new JMenuItem("Copier", new
ImageIcon("[Link]"))).addActionListener (new ActionListener(){
public void actionPerformed(ActionEvent ev) {
[Link]();
}
});
[Link](new JMenuItem("Couper", new
ImageIcon("[Link]"))).addActionListener (new ActionListener(){
public void actionPerformed(ActionEvent ev) {
[Link]();
}
});
}
public static void main (String args[]) {
MenuAvecIcones f = new MenuAvecIcones();
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 31
Construction d'un menu avec écouteurs (1)
Nous pouvons associer des écouteurs à un menu ou ses éléments:
Exemple 6 :
class MenuAvecEcouteurs extends JFrame implements ActionListener, ItemListener {
public MenuAvecEcouteurs() {
setTitle ("Editeur avec ecouteurs") ;
setSize (300, 150) ;
barreMenus = new JMenuBar() ; /* création barre des menus */
setJMenuBar(barreMenus) ; /* création menu Couleur et son groupe de 2 boutons radio :
Rouge et Vert */
couleur = new JMenu ("Couleur") ;
[Link](couleur) ;
rouge = new JRadioButtonMenuItem ("Rouge") ;
[Link](rouge) ;
[Link] (this) ;
[Link] (this) ;
vert = new JRadioButtonMenuItem ("Vert") ;
[Link](vert) ;
[Link] (this) ;
[Link] (this) ;
ButtonGroup groupe = new ButtonGroup() ;
[Link](rouge) ;
[Link](vert) ;
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 32
Construction d'un menu avec écouteurs (2)
Exemple 6 (suite) :
/* création du menu Formes et ses cases a cocher Rectangle et Ovale */
formes = new JMenu ("Formes") ;
[Link](formes) ;
rectangle = new JCheckBoxMenuItem ("Rectangle") ;
[Link](rectangle) ;
[Link] (this) ;
[Link] (this) ;
ovale = new JCheckBoxMenuItem ("Ovale") ;
[Link](ovale) ;
[Link] (this) ;
[Link] (this) ;
}
public void actionPerformed (ActionEvent ev ) { // boutons radios
Object source = [Link]() ;
if (source == rouge) [Link] ("** Action option rouge") ;
if (source == vert) [Link] ("** Action option vert") ;
if (source == rectangle) [Link] ("** Action option rectangle") ;
if (source == ovale) [Link] ("** Action option ovale") ;
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 33


Construction d'un menu avec écouteurs (3)
public void itemStateChanged (ItemEvent ev) {
Object source = [Link]() ; // à vérifier directement avec if(rouge==[Link]())
if(source == rouge) [Link] ("** Item option rouge") ;
if(source == vert) [Link] ("** Item option vert") ;
if(source == rectangle) [Link] ("** Item option rectangle") ;
if(source == ovale) [Link] ("** Item option ovale") ;
[Link] ("Option selectionnée : ") ;
if([Link]()) [Link](" rouge");
if([Link]()) [Link](" vert");
if([Link]()) [Link](" rectangle");
if([Link]()) [Link] (" ovale");
[Link]() ;
}
private JMenuBar barreMenus ;
private JMenu couleur, formes ;
private JRadioButtonMenuItem rouge, vert;
private JCheckBoxMenuItem rectangle, ovale;

public static void main (String args[]) {


MenuAvecEcouteurs f = new MenuAvecEcouteurs();
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 34


Construction d'un menu avec écouteurs (4)
 Remarques:

 Les menus (JMenu) génèrent des événements de type MenuEvent lors de leur
affichage ou de leur disparition.
 L'écouteur associé est ajouté par addMenuListenerListener().
 L'interface à implémenter MenuListener est contenu dans le paquetage
[Link] contient 3 méthodes (pas d'adaptateurs !):
 menuSelected()
 menuDeselected()
 menuCanceled()

 peut utilisé généralement.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 35


Forme condensée de construction d'un menu (1)
 La méthode add() de JMenu, permet de créer automatiquement un
élément de menu JMenuItem.
 Exemple: rajouter l'élément Ouvrir au menu Fichier
 au lieu de:
JMenu fichier = new JMenu("Fichier");
JItemMenu ouvrir = new JMenu("Ouvrir"); // création
[Link](ouvrir); // ajout
 nous avons:
JMenu fichier = new JMenu("Fichier");
[Link]("Ouvrir"); // création et ajout
 pour lui associer un écouteur:
JMenuItem ouvrir = [Link]("Ouvrir");
[Link](écouteur); // ajout d'un écouteur
 Nous pouvons même faire 3 traitement en une seule ligne:
JMenu fichier = new JMenu("Fichier");
// création, ajout et lier un écouteur
[Link]("Ouvrir").addActionListener(écouteur);
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 36
Forme condensée de construction d'un menu (2)
Exemple 7 : Ecriture condensée, création, ajout d'un item et d'un écouteur
class MenuAvecEcouteurs2 extends JFrame{
public MenuAvecEcouteurs2() {
setTitle ("Editeur avec ecouteurs"); setSize (300, 150); setVisible(true);
JMenuBar barreMenus = new JMenuBar() ; /* création barre des menus */
setJMenuBar(barreMenus) ;
JMenu fichier = new JMenu ("Fichier") ;
[Link](fichier) ;
/* création, ajout des items et lien avec écouteurs */
[Link]("Ouvrir").addActionListener (new ActionListener(){
public void actionPerformed(ActionEvent ev) {
[Link]("** Iem Ouvrir **");
}
});
[Link]("Quitter").addActionListener (new ActionListener(){
public void actionPerformed(ActionEvent ev) {
[Link]("** Iem Quitter **");
}
});
}
public static void main (String args[]) {
MenuAvecEcouteurs2 f = new MenuAvecEcouteurs2();
[Link](true);
}
} Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 37
Les composants d'un Menu (5)
4- La classe JPopupMenu
Un menu surgissant se construit comme un menu, mais qui n'est pas rattaché à une barre
de menus mais à un composant.
Pour afficher un menu surgissant, il faut ajouter un écouteur d'événements et utiliser la
méthode show() de la classe JPopupMenu pour l'affichage.
JPopupMenu popup = new JPopupMenu();
JMenuItem menuItem = new JMenuItem("un item surgissant");
[Link](menuItem);
menuItem = new JMenuItem("un autre item surgissant");
[Link](menuItem);
[Link]();
menuItem = new JMenuItem();
[Link]("Quitter");
[Link](new
[Link]([Link](KeyEvent.VK_Q,
Event.CTRL_MASK, true)); // un accélérateur CTRL Q
[Link](new ActionListener() {
public void actionPerformed(ActionEvent ev) {
[Link](0);
}
});
[Link](menuItem);
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 11
Construction d'un menu surgissant (1)
Un menu surgissant de type JPopupMenu est un menu, sans nom, non
rattaché à une barre de menu dont la liste d'éléments apparaît suite à un clic
sur le bouton droit de la souris.

On crée un objet de type JPopupMenu, auquel on ajoute des objets de


type JMenuItem de la même manière que l'ajout à un objet de type
JMenu.

Exemple :
JPopupMenu menuS = new JPopupMenu(); // création d'un objet menu surgissant
JMenuItem haut = new JMenuItem("Haut"); // création d'un élément Haut
[Link](haut); // ajout au menu surgissant
JMenuItem bas = new JMenuItem("Bas"); // création d'un élément Bas
[Link](bas); // ajout au menu surgissant

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 38


Construction d'un menu surgissant (2)
Remarques :
 On peut utiliser des cases à cocher ou des boutons radio comme éléments d'un menu
surgissant,
 Contrairement à un menu usuel qui est affiché en permanence, un menu surgissant doit
être affiché explicitement par le programme en utilisant la méthode show de la classe
JPopupMenu, avec comme arguments, le composant parent et les coordonnées de la
position du menu.
Exemple : [Link]([Link](), [Link](), [Link]());
 Le menu reste affiché jusqu'à ce que l'utilisateur sélectionne un élément ou en cliquant à
côté.
 La classe MouseEvent dispose d'une méthode isPopupTrigger qui fournit la
valeur true si le bouton droit de la souris est concerné. Cette méthode est utilisable
dans mouReleased
Exemple :
public void mouseReleased(MouseEvent ev) {
if([Link]())
[Link]([Link](), [Link](), [Link]());
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 39
Construction d'un menu surgissant (3)
Exemple 8: un menu surgissant simple
public class MenuSurgissant1 extends JFrame {
public MenuSurgissant1(){
setTitle("Menu Surgissant");
setDefaultCloseOperation(3); setSize(300,150); setVisible(true);
// création du menu surgissant niveau et ses options haut et bas
JPopupMenu menuS = new JPopupMenu();
JMenuItem haut = new JMenuItem("Haut");
[Link](haut);
JMenuItem bas = new JMenuItem("Bas");
[Link](bas);
// asociation de l'écouteur MouseListener pour réagir au bouton droit
addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent ev) {
if([Link]()
[Link]([Link](),[Link](),[Link]());
[Link]("Position x= "+[Link]()+" y= "+[Link]());
}
});
}
public static void main(String[] args) {
new MenuSurgissant1();
}
} Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 40
Construction d'un menu surgissant (4)
Exemple 9: Ajout de raccourcis
public class MenuSurgissant2 extends JFrame {
public MenuSurgissant2() {
setTitle("Menu Surgissant"); setDefaultCloseOperation(3);
setSize(300,150); setVisible(true);
// créatiion du menu surgissant couleur et ses options rouge et vert
JPopupMenu couleur = new JPopupMenu();
JMenuItem rouge = new JMenuItem("Rouge"); [Link]('R'); // Alt+r
[Link]([Link](KeyEvent.VK_R,InputEvent.CTRL_MASK));
[Link](rouge);
JMenuItem vert = new JMenuItem("Vert"); [Link]('V'); // Alt+v
[Link]([Link](KeyEvent.VK_V,
KeyEvent.CTRL_MASK + KeyEvent.SHIFT_MASK)); // Ctrl+Maj+v
[Link](vert);
addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent ev) {
if ([Link]())
[Link]([Link](),[Link](),[Link]());
[Link]("Position x= "+[Link]()+" y= "+[Link]());
}
});
}
public static void main(String[] args) {
new MenuSurgissant2();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 41
Construction d'un menu surgissant (5)
Exemple 10: Ajout d'écouteurs d'événements
public class MenuSurgissant3 extends JFrame implements ActionListener {
JPopupMenu couleur;
JMenuItem rouge, vert;
public MenuSurgissant3() {
setTitle("Menu Surgissant");
setDefaultCloseOperation(3);
setSize(300,150);
setVisible(true);
couleur = new JPopupMenu(); // création du menu surgissant couleur et ses options rouge et vert
rouge = new JMenuItem("Rouge"); [Link]('R');
[Link]([Link](KeyEvent.VK_R,InputEvent.CTRL_MASK));
[Link](rouge);
[Link](this); // ajout d'écouteurs
vert = new JMenuItem("Vert"); [Link]('V');
[Link]([Link](KeyEvent.VK_V,
KeyEvent.CTRL_MASK + KeyEvent.SHIFT_MASK)); // Ctrl+Maj+v
[Link](vert);
[Link](this); // ajout d'écouteurs
addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent ev) {
if ([Link]())
[Link]([Link](),[Link](),[Link]());
}
});
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 42
Construction d'un menu surgissant (6)
Exemple 10: Ajout d'écouteurs d'événements

public void actionPerformed(ActionEvent ev) {


[Link]("Action avec chaine de commande = "
+ [Link]());
if([Link]()==rouge) [Link]("Action option rouge");
if([Link]()==vert) [Link]("Action option vert");
}

public static void main(String[] args) {


new MenuSurgissant3();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 43


Interfaces Homme - Machine
Chapitre 8 :
Les applettes Java
Composants spécialisés

SMI - S6
Année universitaire 2017-2018

Prof. M.D. RAHMANI


mrahmani@[Link]
Plan
 Les applettes Java :
 La classe JApplet,
 Ecriture et lancement d’une applette,
 La méthode init(),
 Cycle de vie d’une applette,
 Restrictions imposées aux applettes,
 La transformation d’une application graphique en une applette
 Composants spécialisés :
 JSlider, une glissière
 JSpinner, liste à défilement
 JList, liste
 JTable, un tableau de cellules
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 2
Environnements d'exécution (1)
A chaque besoin son environnement Java : applications, applettes,
servlettes,

Les trois principaux environnements d’exécution Java (frameworks en


anglais) sont (1) les applications , (2) les applettes et (3) les servlettes.

Chaque environnement utilise une catégorie de classes et un point


d’entrée différents;

Le point d’entrée d’un programme est la méthode appelée par la JVM


pour exécuter un programme.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 3


Environnements d'exécution (2)

1- Une application s'exécute sur une machine isolée ou


liée à un réseau.

La JVM et les fichiers .class d'une application


doivent être installés sur la machine.

Le point d'entrée d'une application est la méthode


main d'une classe.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 4


Environnements d'exécution (3)
2- Une applette s'exécute dans une page HTML, sur une
machine cliente liée à un serveur Web

La JVM, installée sur la machine cliente, est lancée par


le navigateur.

Les fichiers .class d'une applette sont installés sur


le serveur Web et téléchargés par le navigateur.
.
Le point d'entrée d'une applette est la méthode init.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 5


Environnements d'exécution (4)

3- Une servlette s'exécute sur un serveur Web pour


générer dynamiquement des pages HTML ou des
images.

La JVM et les fichiers .class d'une servlette doivent


être installés sur le serveur Web.

Le point d'entrée d'une servlette est la méthode


doGet.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 6


Hiérarchie des classes

Component

Container

Window JComponent Panel

Frame Dialog JWindow Applet

JFrame JDialog JApplet

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 7


La classe JApplet (1)

o La vocation d'une applette est d'être téléchargée sur une machine


donnée à partir d'une machine distante qui en fournit le code.

o Ce chargement est provoqué par un fichier contenant des commandes


HTML (Hyper Text Markup Language).

o Exécutée par l'interpréteur java du navigateur, une applette permet de


délocaliser certains traitements (animations graphiques, vérification de
la validité d'un formulaire, etc...) sur la machine cliente.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 8


La classe JApplet (2)
o Une applette est constituée d'une classe dérivée de
[Link], un conteneur de haut niveau, comme JFrame
et JDialog. Son gestionnaire par défaut est un BorderLayout.

o Au lancement d'une applette, on dispose automatiquement d'une fenêtre


graphique, ce qui n'est pas le cas d'une application.

o Les dimensions initiales de la fenêtre sont définies par des commandes du


fichier HTML lançant l'applette et non pas par le code de l'applette.

Remarque: pour le cas d'une application, la taille d'un objet de type


JFrame ou dérivé est généralement fixée dans son constructeur.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 9
La classe JApplet (3)
Un fichier HTML qui lance une applette fournit au minimum les
informations suivantes:

Nom du paramètre informations associées

CODE = Nom du fichier (.class) de l'applette


il peut se trouver sur une machine distante
exemple: CODE = "[Link]"
WIDTH = Largeur initiale de la fenêtre en pixels
exemple: WIDTH = 350
HEIGHT = Hauteur initiale de la fenêtre en pixels
exemple: HEIGHT = 100

Ces paramètres sont indispensables au lancement d'une applette

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 10


Ecriture et lancement d'une applette (1)
Une applette est destinée à être lancée dans une page web, par un
navigateur qui exploite le fichier HTML correspondant.
Avant son lancement, une applette ([Link]) doit être
compilée pour obtenir le byte code ([Link])
Le fichier HTML doit contenir au minimum la taille et le byte code
de l'applette.

Remarque:
Les EDI en général disposent de "visualiseurs d'applettes", qui
permettent d'exécuter une applette sans qu'il soit nécessaire de passer par
un navigateur web.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 11


Ecriture et lancement d'une applette (2)
Exemple 1: cas d'une applette dont le corps est vide.

import [Link];
public class PremiereApplette extends JApplet {
// corps vide
}

Le chemin : [Link]

Cet exemple d'applette crée un conteneur, de type JApplet vide.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 12


3- Ecriture et lancement d'une applette (3)
Remarque:
Sous Eclipse, lors de la création d'une applette, il faut à côté de la superclass préciser
[Link] au lieu de [Link].

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 13


Ecriture et lancement d'une applette (4)
Fichier HTML de lancement d'une applette:
Les commandes peuvent varier suivant le navigateur ou le visualiseur
(appletviewer fourni par le JDK de java) d'applettes utilisé.
Une balise spécifique de lancement de l'applette est le mot clé APPLET,
OBJECT ou EMBED, suivant les versions des navigateurs ou des visualiseurs.
Cette balise contient les informations: CODE, HEIGHT et WIDTH.
Exemple: [Link]
<HTML>
<BODY>
<APPLET CODE="[Link]" WIDTH=150 HEIGHT=100>
</APPLET>
</BODY>
</HTML>
Remarque:
le code de l'applette peut être dans un répertoire local ou une adresse URL.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 14
La méthode init (1)
L'exemple de l'applette précédente créait un conteneur, de type
JApplet vide.
On peut introduire dans ce conteneur comme c'est le cas pour un
JFrame ou un JDialog, des composants et leurs associer des écouteurs
d'événements.
Le gestionnaire par défaut d'une applette de la calsse JApplet est
BorderLayout, par contre, celui de la classe Applet est FlowLayout.
La méthode init() d'une applette est exécutée automatiquement lors
du lancement de l'applette.
On peut doter la classe applette d'un constructeur sans argument, qui
sera exécuté (automatiquement) pour construire l'objet correspondant.
Les opérations telles que création de composants, d'écouteurs...,
peuvent se faire dans le constructeur ou dans la méthode init().
Par convention, on préfère la méthode init().
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 15
La méthode init (2)
Exemple 2: Utilisation de la méthode init(): [Link]

import [Link].*;
import [Link].*;

public class Applette1 extends JApplet implements ActionListener{


JButton b;
public void init() {
b = new JButton("Avant !");
[Link](this);
add(b);
}
public void actionPerformed(ActionEvent e) {
if ([Link]().equals("Avant !"))
[Link]("Après !");
else
[Link]("Avant !");
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 16


La méthode init (3)
Exemple 3: Une applette avec 2 boutons et écouteurs d'événements qui créé:

 un panneau panneau qu'on ajoute au conteneur au centre avec une


couleur bleu par défaut.

 un autre panneau panneauCom placé en bas dans lequel on incorpore


deux boutons permettant d'agir sur la couleur du panneau supérieur.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 17


La méthode init (4)
Exemple 3 (suite): Utilisation de la méthode init(): [Link]
public class Applette2Boutons extends JApplet implements ActionListener {
JPanel panneau, panneauCom;
JButton rouge, jaune;
public void init() { // la méthode init()
panneau = new JPanel();
[Link]([Link]);
panneauCom = new JPanel();
rouge = new JButton("rouge");
jaune = new JButton("jaune");
[Link](this);
[Link](this);
[Link](rouge);
[Link](jaune);
add(panneau, "Center");
add(panneauCom,"South");
}
public void actionPerformed(ActionEvent e) {
if([Link]() == rouge) [Link]([Link]);
if([Link]() == jaune) [Link]([Link]);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 18


La méthode init (5)
Le fichier HTML associé: [Link]

<HTML>
<BODY>
<APPLET CODE="[Link]" WIDTH=250 HEIGHT=100>
</APPLET>
</BODY>
</HTML>

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 19


Cycle de vie d'une applette (1)
Les différentes méthodes concernées par la vie d'une applette:
Méthode Appel

init Après la création de l'objet applette

start Après init, puis chaque fois que l'applette redevient visible

stop Chaque fois que l'applette n'est plus visible, ainsi qu'avant destroy

destroy A la fin de l'exécution de l'applette, c-à-d:


- l'utilisateur quitte le navigateur si l'applette a été lancée ainsi;
- l'utilisateur a fermé la fenêtre de l'applette

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 20


Cycle de vie d'une applette (2)
Exemple 4: Appel des différentes méthodes: [Link]
import [Link];
public class VieApplette extends JApplet {
public VieApplette() {
[Link]("Construction");
}
public void init() {
[Link]("Appel init");
} Au démarrage:
public void start() {
[Link]("Appel start");
}
public void stop() {
[Link]("Appel stop"); A l'arrêt de l'applette: fermeture de la fenêtre
}
public void destroy() {
[Link]("Appel destroy");
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 21


Restrictions imposées aux applettes
Une applette est conçue à l'origine pour être exécutée sur un site
distant de celui qui en fournit le code.
Les concepteurs de Java avaient prévu des restrictions nécessaires
pour assurer une sécurité sur la machine d'exécution distante.
La machine virtuelle JVM interdit à une applette:
 d'accéder aux fichiers locaux;
 de lancer un programme exécutable local;
 d'obtenir des informations relatives au système local.
Remarques:
o Actuellement, la notion de gestionnaire de sécurité permet à un environnement de
définir les opérations permises aux applettes.
o La notion d'applette certifiée permet d'accorder des permissions supplémentaires à
une applette.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 22


Transformation d'une application en une applette
Une applette peut exploiter pleinement les possibilités d'une interface
graphique.
Une application peut être transformée en une applette à condition
qu'elle ne soit pas concernée par les restrictions de sécurité imposées aux
applettes.
Cette transformation peut se faire en:
o supprimant la méthode main() ou si on la conserve elle ne sera pas appelée lors
du lancement par la JVM,
o en transformant l'objet de type dérivé de JFrame en un objet dérivé de type
JApplet,
o en général, on évite de doter la classe dérivée de JApplet d'un constructeur; les
actions réalisées dans le constructeur sont à reporter dans la méthode init().
o en supprimant des instructions setTitle, setBounds, ....

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 23


Plan

Composants spécialisés :

 JSlider, une glissière


 JSpinner, liste à défilement
 JList, liste
 JTable, un tableau de cellules

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 24


Les glissières : JSlider (1)

Les glissières : JSlider


Un objet de type JSlider est un curseur coulissant ou une glissière
que manipule l’utilisateur pour choisir une valeur dans une gamme de
valeurs entières.
 Création :
JSlider glissiere = new JSlider(min, max, valeurInitiale);

 Si les valeurs extrêmes ne sont pas données, elles prennent les


valeurs par défaut 0, 100, et 50 pour la valeur initiale.
 Il est possible de la positionner horizontalement ou verticalement.
Un curseur vertical est construit avec :
JSlider glissiere = new JSlider([Link], min, max,
valeurInitiale);
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 25
Les glissières : JSlider (2)
 La position du curseur est fixée avec setValue et lue avec getValue,
 L’orientation peut être changée en utilisant la méthode setOrientation
 Les JSlider peuvent être configurés pour couvrir une étendue à l’aide de
setMinimum et setMaximum
 Les traits de graduation peuvent être rendus visibles avec la méthode
setPaintTicks.
 Ilest possible de tracer des repères, deux types sont proposés, les repères
majeurs et les repères mineurs; les intervalles de chaque type sont définis
avec setMinorTickSpacing et setMajorTickSpacing.
 On peut configurer les bornes et la position du curseur :
exemple:
JSlider sCouleur = new JSlider([Link],0,255,127);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 26


Les glissières : JSlider (3)
Personnaliser l'apparence d'un curseur coulissant
void setValue(int n)
int getValue() // fixe ou retourne la valeur courante du curseur.
void setMinimum(int minimum)
int getMinimum()
void setMaximum(int maximum)
int getMaximum() // fixe ou retourne la borne min ou max du curseur.
void setOrientation(int orientation)
int getOrientation() // fixe ou retourne l'orientation ([Link]
// ou [Link]) du curseur.
void setInverted(boolean b)
boolean getInverted() // fixe ou retourne si les bornes min et max du curseur
// sont inversées.
void setMajorTickSpacing(int n)
int getMajorTickSpacing() // fixe ou retourne l'espace entre les graduations
// principales.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 27


Les glissières : JSlider (4)
void setMinorTickSpacing(int n)
int getMinorTickSpacing()
// fixe ou retourne l'espace entre les graduations secondaires.
void setPaintTicks(boolean b)
boolean getPaintTicks()
// fixe ou retourne si les graduations doivent être tracées.
void setPaintLabels(boolean b)
boolean getPaintLabels()
// fixe ou retourne si les étiquettes des graduations doivent être tracées.

Gérer les déplacements du curseur :


void addChangeListener(ChangeListener)
// associe un écouteur de changements au curseur.
boolean getValueIsAdjusting()
// retourne true si l'utilisateur a terminé de déplacer le curseur.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 28


Les glissières : JSlider (5)
Exemple 1 :
public class CurseurCoulissant1 extends JFrame {
JPanel panneau = new JPanel();
JSlider curseurCoulissant = new JSlider();
public CurseurCoulissant1() {
setTitle("Un curseur coulissant");
setBounds(20, 20, 600, 200);
[Link]([Link]);
add(panneau);
[Link]([Link]);
[Link](100);
[Link](0); // valeur de départ du curseur
[Link](10); // 10 est la valeur séparant les chiffres
[Link](5); // 5 est la valeur séparant les tirets
[Link](true); // déssiner les tirets et les nombres
[Link](true);
[Link](true); // liaison entre tirets et la position du slider
[Link](new Dimension(400,50));
[Link]([Link]);
[Link](curseurCoulissant);
setVisible(true);
}
public static void main(String[] args) {
new CurseurCoulissant1();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 29
Les glissières : JSlider (6)
o Nous pouvons lui associer l'écouteur d'événement ChangeListener
du paquage [Link],
o Pour écouter un composant, on utilise la méthode addChangeListener
o Les événements associés de type, ChangeEvent peuvent être générés par:
AbstractButton, JProgressBar, JSlider, …
o La méthode getValue() nous donne la valeur associée au curseur.
o Cette interface dispose d'une seule méthode à redéfinir :
stateChanged(ChangeEvent ev);

Exemple : public void stateChanged(ChangeEvent ev){


(JSlider)[Link]()).getValue();
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 30


Les glissières : JSlider (7)
Exemple 2 : Curseur coulissant avec écouteur
public class CurseurCoulissant2 extends JFrame{
private JLabel etiquette = new JLabel("Valeur actuelle : 30");
public CurseurCoulissant2(){
setSize(300, 150); setTitle("Curseur coulissant");
setDefaultCloseOperation(3);
JSlider curseur = new JSlider();
[Link](100); [Link](0);
[Link](30); // valeur de départ du curseur
[Link](true); // dessiner les tirets et les nombres
[Link](true);
[Link](10); // 10 est la valeur séparant les tirets
[Link](20); // 20 est la valeur séparant les chiffres
[Link](new ChangeListener(){
public void stateChanged(ChangeEvent ev){
[Link]("Valeur actuelle : "+((JSlider)[Link]()).getValue());
}
});
add("North", curseur); add("South", etiquette);
}
public static void main(String[] args){
CurseurCoulissant2 glissiere = new CurseurCoulissant2();
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 31
Liste à défilement: JSpinner (1)
Le composant JSpinner permet à l'utilisateur de sélectionner une
information parmi une séquence ordonnée de valeurs à l'aide de 2 boutons
permettant de faire défiler les valeurs possibles.
Fonctionnellement, le composant JSpinner est proche d'un composant
JComboBox mais seule la valeur courante est visible.
Le composant JSpinner est un conteneur composé de 3 sous-
composants :
 Un champ appelé éditeur dans lequel seront affichées ou éditées les
valeurs.
 Deux boutons permettant de faire défiler les valeurs possibles.
La librairie Swing offre 3 modèles par défaut :
 SpinnerListModel
 SpinnerNumberModel
 SpinnerDateModel

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 32


Liste à défilement : JSpinner (3)
Exemple 1 : Création d'un modèle JSpinner pour les nombres
public class SpinnerNombre extends JFrame {
public SpinnerNombre() {
setTitle("Un JSpinner avec les nombres");
setLayout(new FlowLayout());
float init = 12.5f; // valeur initiale
float min = 0.0f; // valeur minimale
float max = 20.0f; // valeur maximale
float pas = 0.5; // incrément
SpinnerNumberModel snm = new SpinnerNumberModel(init, min, max, pas);
// Création du composant JSpinner
JSpinner note = new JSpinner(snm);
// Ajout de l'étiquette et du composant JSpinner
add(new JLabel("Note : ", [Link]));
add(note);
pack();
setVisible(true);
}
public static void main(String[] argv) {
new SpinnerNombre();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 34


Liste à défilement : JSpinner (4)
Exemple 2 : Création d'un modèle JSpinner pour Date et List
public class SpinnerDateEtListe extends JFrame {
public SpinnerDateEtListe() {
setTitle("Un JSpinner avec les dates");
JPanel = new JPanel(); [Link](new GridLayout(0,2));

JSpinner spinner1 = new JSpinner(new SpinnerDateModel( ));


[Link](new JLabel ("Date : ", [Link]));
[Link](spinner1);

String[] mois = {
"Janvier", "février", "Mars", "Avril", "Mai", "Juin", "Juillet",
"Aout", "Septembre", "Octobre", "Novembre", "Décembre"};
JSpinner spinner2 = new JSpinner(new SpinnerListModel(mois));
[Link](new JLabel("Mois : ", [Link]));
[Link](spinner2);
add("North", p);
setSize(350, 100); setVisible(true);
}
public static void main(String[] argv) {
new JSpinnerDateEtListe();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 35
Les listes JList (1)
 C'est une liste déroulante prédéfinie dans laquelle l'utilisateur peut choisir
un ou plusieurs éléments (items).
 On crée un objet de type JList en fournissant un tableau de chaînes à
son constructeur,
 String[] choix = {"choix1", "choix2", "choix3", "choix4"};
 JList liste = new JList(choix);
 Aucune valeur par défaut n'est sélectionnée.
 Pour choisir un élément d'un rang donné, on utilise la méthode:
 [Link](2); // sélection préalable de l'élément de rang 2
 On peut ajouter une barre de défilement,
 JScrollPane bDefilement = new JScrollPane(liste);

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 36


Les listes JList (2)
 Pour connaître la position d'un élément dans une liste :
int getSelectedIndex() // position d'un élément
int[] getSelectedIndices[] // tableau des positions de tous les éléments
 Pour choisir le type de sélection:
[Link](ListSelectionModel.SINGLE_SELECTION);
 Il y'a 3 types de listes caractérisés par les paramètres :
 SINGLE_SELECTION // sélection d'un seul élément
 SINGLE_INTERVAL_SELECTION // une seule plage d'éléments
 MULTIPLE_INTERVAL_SELECTION /* sélection d'un nombre quelconque de plages d'éléments */

 Pour sélectionner une plage d'éléments, l'utilisateur doit cliquer sur le 1er élément,
appuyer sur la touche MAJ, tout en la maintenant enfoncée, cliquer sur le dernier
élément de la plage.
 Pour sélectionner plusieurs plages d'éléments, on procède de la même manière
avec en plus un appui sur CTRL.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 37
Les listes JList (3)
 Exemple 1 : création d'une liste

public class Liste1 extends JFrame {


public Liste1 () {
setTitle("Choix dans une liste");
setSize (300, 160);
setDefaultCloseOperation(3);
setLayout (new FlowLayout());
liste1 = new JList (couleurs);
add(liste1);
}
public static void main(String args[]) {
Liste1 cadre = new Liste1();
[Link](true);
}
private String[] couleurs = {"rouge", "bleu", "gris", "vert", "jaune", "noir"};
private JList liste1;
}

Remarque: pour sélectionner plusieurs éléments, laisser appuyé le bouton CTRL


Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 38
Les listes JList (4)

 Exemple 1(bis) : création d'une liste avec une barre de défilement


public class ListeAvecDefilement {
public static void main(String args[]) {
String[] couleurs = {"rouge", "bleu", "gris", "vert", "jaune", "noir"};

JFrame cadre = new JFrame("Liste avec défilement");


[Link](3);
JList liste1bis = new JList(couleurs);
JScrollPane scrollPane = new JScrollPane(liste1bis);

[Link](scrollPane, [Link]);
[Link](300, 100);
[Link](true);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 39


Les listes JList (5)
 Evénements générés par les éléments d'une liste :
Une liste génère un seul type d'événement ListSelctionEvent, écouté
par ListSelectionListener dans [Link].*.
La méthode unique à redéfinir est valueChanged():
public void valueChanged(ListSelectionEvent ev)
Remarque :
Cette méthode génère un événement lors de l'appui sur le bouton de la souris et lors de
relâchement.
Pour pallier à cette redondance, la classe JList dispose d'une méthode
getValueIsAdjusting qui permet de savoir si l'on est ou non en phase de transition,
comme suit :
public void valueChanged(ListSelectionEvent ev) {
if(![Link]()) {
// accès aux éléments sélectionnés et traitements
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 40


Les listes JList (6)
 Pour une liste à sélection simple, la méthode getSelectedValue rend la
seule chaîne sélectionnée. Le résultat est de type Object et non String.
Il faut par conséquent procéder à une conversion explicite :
String ch = (String) [Link](); // cast obligatoire

 Pour une liste à sélection multiple, la méthode getSelectedValues


rend un tableau de chaînes sélectionnées. Le résultat est de type Object et
non String.
Pour afficher toutes les chaînes sélectionnées :
Object[] elements = [Link]();
for (int i=0; i<[Link]; i++)
[Link]((String) elements[i]); // cast obligatoire

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 41


Les listes JList (7)
 Exemple 2 : l'ajout d'un écouteur d'événements :
public class Liste2 extends JFrame implements ListSelectionListener {
public Liste2 () {
setTitle("Choix dans une liste 2");
setSize (300, 160);
setDefaultCloseOperation(3);
setLayout (new FlowLayout() );
liste2 = new JList (couleurs);
add(liste2);
[Link](this);
}
public void valueChanged (ListSelectionEvent ev) {
if (![Link]()) {
[Link] ("Action sur la liste - valeur sélectionnée:");
Object[] elements = [Link]() ;
for (int i = 0 ; i<[Link] ; i++)
[Link] ((String) elements[i]);
}
}
public static void main(String args[]) {
Liste2 cadre = new Liste2();
[Link](true);
}
String[] couleurs = {"rouge", "bleu", "gris", "vert", "jaune", "noir"};
JList liste2;
}

Résultat: Action sur la liste - valeur sélectionnée : bleu gris jaune


Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 42
Les listes JList (8)
 Exemple 3 : Choix multiple avec écouteur d'événements
public class ListeChoixMultiple extends JFrame {
public ListeChoixMultiple() {
couleursJList = new JList(TAB_COULEURS); // définition liste choix
[Link](5); // nb de lignes visibles
[Link](
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); // autorise la sélection multiple
JScrollPane spList = new JScrollPane( couleursJList ); // ajoute d'un ascenseur
add( spList, [Link] ); // ajoute le composant dans la fenêtre
//--- définition d'une étiquette
label = new JLabel( " Sélection: [Ctrl]+[click] ou [Shift]+[click] " );
add( label, [Link] );
button = new JButton("Sélection"); //--- définition bouton
[Link](new SelectionAction() );
add( button, [Link] );
pack();
}
//----- variables
JList couleursJList;
JLabel label;
JButton button;
//----- constantes
final static String[] TAB_COULEURS = {"blanc", "jaune", "rouge", "vert", "bleu",
"orange", "noir", "bleu clair", "rouge clair", "vert clair"};

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 43


Les listes JList (9)
 Exemple 3 : Choix multiple avec écouteur d'événements
//----- classes internes
private class SelectionAction implements ActionListener {
public void actionPerformed( ActionEvent e ) {
[Link]( "Votre sélection:" );
for ( Object item: [Link]() ) {
[Link]((String)item);
}
}
}
public static void main( String[] args ) {
ListeChoixMultiple cadre = new ListeChoixMultiple();
[Link](3);
[Link]( true );
}
}
Résultat :

Avec Ctrl + click : pas nécessairement contigu


Avec Shift + click: choix multiple contigu

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 44


Les tables JTable (1)
 Les tables du package [Link] sont des formats de
représentation des données à 2 dimensions,
 Dans une table, les informations sont représentées dans une grille
organisée en lignes et en colonnes.
 Chaque donnée est affichée dans une cellule.
 Les colonnes contiennent généralement un ensemble de données de
même type et peuvent posséder un titre.
 Le composant JTable possède plusieurs constructeurs dans lesquels les
données peuvent être transmises sous différentes formes:
Object[][], Vector ou TableModel
 Il est souvent utile d'insérer le composant JTable dans un conteneur
JScrollPane pour pouvoir défiler les données.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 45


Les tables JTable (2)
 Exemple 1 : un double clic permet d'accéder à un champ à modifier
public class TableNotes extends JFrame {
String[][] tDonnees =
{{"Nom1", "Prénom1", "note1"}, // Données
{"Nom2", "Prénom2", "note2"},
{"Nom3", "Prénom3", "note3"},
{"Nom4", "Prénom4", "note4"},
};
String[] titre = {"Nom", "Prénom", "Note"}; // En-tête
public TableNotes() {
setTitle("Table des notes");
setSize(600, 200);
setVisible(true);
setDefaultCloseOperation(3);
JTable table = new JTable(tDonnees, titre);
JScrollPane sTable = new JScrollPane(table);
add(sTable);
}
public static void main(String[] args) {
TableNotes tn = new TableNotes();
[Link](true);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 46
Les tables JTable (3)
 Exemple 2 : Création d'une table avec un modèle
import [Link].*; //pour DefaultTableModel
public class CreationJTable extends JFrame {
String titre[]={"Langage","Type"}; // L'en-tête de JTable
// Les valeurs de JTable
Object [][]valeurs={{"C","Procédural"}, {"Prolog", "Logique"},
{"C++","Procédural et Orienté Objet"}, {"Scala","Multi-paradigme"},
{"Java","Orienté Objet"}, {"Haskell","Fonctionnel"},
{"PHP","Procédural et Orienté Objet"}, {"Caml","Fonctionnel et Orienté Objet"}};
public CreationJTable() {
JTable table=new JTable(); // Créer un composant JTable
// utiliser le modèle du composant
[Link](new DefaultTableModel(valeurs, titre));
// Ajouter le composant dans un JScrollPane
JScrollPane jsp = new JScrollPane(table);
add(jsp);
}
public static void main(String [] arg) {
CreationJTable tab= new CreationJTable();
[Link]("Création d'une table");
[Link](350,150);
[Link](true);
}
} Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 47
Les tables JTable (4)
 Exemple 3 : Ajout d'une JCheckBox dans une table,
public class TableAvecCaseACocher extends JFrame {
JTable table;
String titre[]={"Langage","Type","Sélection"};
// Les valeurs de JTable
Object [][]valeurs={{"C","Procédural"}, {"Prolog", "Logique"},
{"C++","Procédural et Orienté Objet"}, {"Scala","Multi-paradigme"},
{"Java","Orienté Objet"}, {"Haskell","Fonctionnel"},
{"PHP","Procédural et Orienté Objet"}, {"Caml","Fonctionnel et Orienté Objet"}};
DefaultTableModel tabModel;
public TableAvecCaseACocher() {
// Créer un composant JTable
table=new JTable();

// Utiliser le modèle du composant


[Link](new DefaultTableModel(valeurs, titre){
Class[] types = new Class [] {
[Link], [Link], [Link]
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
});
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 48
Les tables JTable (5)
 Exemple 3 : Ajout d'une JCheckBox dans une table,
// Ajouter le composant dans un JScrollPane
JScrollPane jsp = new JScrollPane(table);
// Ajouter le JScrollPane dans le JFrame
add(jsp, [Link]);
}
public static void main(String [] arg) {
TableAvecCaseACocher tab= new TableAvecCaseACocher();
[Link]("Ajout des Cases à cocher dans une JTable");
[Link](450,150);
[Link](true);

}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 49


Interfaces Homme - Machine
Chapitre 9 :
Les threads
Le modèle de conception MVC

SMI - S6
Année universitaire 2016-2017

Prof. M.D. RAHMANI


mrahmani@[Link]
Plan:
 Introduction à la programmation concurrente,
 Les threads en Java,
 Définition de threads en Java,
 Déclaration, création et lancement d'un thread,
 Exemples d'utilisation,

 Les Timers
 Définition d'un Timer
 Exemples d'utilisation

 Le modèle MVC,
 Définition,
 Exemples d'utilisation
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 2
Introduction à la programmation concurrente (1)
 Programmation standard:

 Définition: Un processus représente l'environnement


d'exécution d'un programme, les données et le code de
l'application.
 Un programme exécute des instructions séquentiellement.
 Le développeur maîtrise la suite des opérations.
 L'exécution est prévisible.
 L'exécution est reproductible.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 3


Introduction à la programmation concurrente (2)
 La programmation concurrente:
 Un processus référence d'une part un espace mémoire pour stocker les données de
l'application et d'autre part un ensemble de threads pour exécuter le code qui
manipulera les données.
 Un processus est décomposé en threads (processus légers ou fils d'exécution).
 Un thread correspond à une tâche (plus en moins indépendant des autres) qui
s'exécute.
 Problèmes:
 Difficulté à synchroniser les tâches.
 Gestion des ressources partagées (mémoire, unité de calcul,…).
 L'exécution est imprévisible.
 Problème de reproductibilité.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 4
Introduction à la programmation concurrente (3)

 Programmation parallèle (ou répartie):


 Des processus s'exécutent sur plusieurs processeurs.

 Programmation concurrente:
 Les tâches sont gérées par un même processeur,
éventuellement sur plusieurs cœurs.

 Les mécanismes de synchronisation sont différents.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 5


Introduction à la programmation concurrente (4)
 Anatomie d'un processus:
 Un processus possède:
 un code à exécuter,
 un espace d'adressage,
 une priorité,
 un identifiant,
 un contexte d'exécution

 Les processus sont gérés par le système d'exploitation,

 Plusieurs processus peuvent s'exécuter en "parallèle".


Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 6
Introduction à la programmation concurrente (5)

 Anatomie d'un thread:


 Un thread est un fil d'exécution dans un processus:
 les threads d'un même processus se partagent l'espace d'adressage du
processus,
 ils possèdent:
 leur propre pile,
 leur propre contexte d'exécution,
 ils ont un cycle de vie semblable à celui d'un processus.

création Prêt, Bloqué, Elu, Terminé

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 7


Introduction à la programmation concurrente (6)
 Thread vs processus:
 Commun:
 sont des entités indépendantes, une fois créés,
 les créateurs de processus et de threads ont le contrôle sur eux,

 Non commun:
 les processus ont un espace d'adressage; les threads non,
 les processus enfants ne peuvent pas exercer de contrôle sur le
processus parent;
 N'importe quel thread peut exercer un contrôle sur le thread principal et
donc sur le processus entier.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 8


Les threads en Java (1)

 Utilité des threads:

 Puissance de modélisation: un monde multithreads,


 Puissance d'exécution: parallélisme,
 Légèreté grâce au partage des données,

 En Java, la gestion des threads est intégrée au langage:


 Simplicité d'utilisation,
 Les threads sont des objets: Classe définie dans le package:
[Link]

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 9


Les threads en Java (2)

 Exemples:
 Le langage Java est multi-threads, c'est à dire qu'il peut exécuter du code
à plusieurs endroits de façon indépendante.

 Dans un EDI comme Eclipse, un thread s'occupe de ce que tape


l'utilisateur, un autre est en charge de souligner les erreurs, un 3ème de la
coloration syntaxique, etc...

 Lors de la création d'un programme en Java, la JVM crée au moins un


thread qu'elle affecte au main qui est le point d'entrée du programme.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 10


Définition d'un thread Java
 La classe [Link] est au centre de la gestion des threads:
 Les threads sont des objets:
 Pour créer de nouveaux threads:
 Thread() et,
 Thread(Runnable cible)

 Pour exécuter un thread :


 void run() // le corps d'un thread
 void start() // lance l'exécution du thread, le thread s'exécute jusqu'à ce que
// sa méthode run se termine,

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 11


La classe Thread: les principales méthodes

 int getPriority(), void setPriority(int) : renvoie ou modifie la


priorité du thread.
 boolean isAlive() : renvoie un booléen qui indique si le thread est actif ou
non.
 currentThread() : donne le thread actuellement en cours d'exécution.
 setName(), getName() : fixe ou donne le nom du thread.
 void yield() : indique à l'interpréteur que le thread peut être suspendu pour
permettre à d'autres threads de s'exécuter.
 static void sleep(long) : mettre le thread en attente durant le temps
exprimé en millisecondes fourni en paramètre. Cette méthode peut lever une exception
de type InterruptedException si le thread est réactivé avant la fin du temps.
 void join() : opération bloquante - attend la fin du thread pour passer à
l'instruction suivante
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 12
Déclaration, création et lancement des threads (1)
 Pour créer un thread, deux solutions sont possibles :
 Dériver de la classe Thread :
On peut créer une classe qui dérive de la classe [Link].
Il suffit ensuite de redéfinir la méthode run(), méthode que le thread va exécuter.
 Implémenter l'interface [Link] :
On peut implémenter l'interface [Link] et redéfinir la méthode
run().
Ensuite on appelle le constructeur de Thread avec pour argument un objet de
l'interface Runnable.
 Dans tous les cas :
Pour lancer l'exécution d'un thread, on doit exécuter la méthode start() et en
aucun cas exécuter la méthode run().
Le thread créé a pour code la méthode run(), et a pour données celles du thread qui
l'a crée.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 13
Déclaration, création et lancement des threads (2)

 1ère méthode: dérivation de la  2ème méthode: : implémentation de


classe Thread, l'interface Runnable,
class Tache extends Thread {
... class Tache implements Runnable {
public void run() { ...
// code à exécuter par le thread public void run() {
... // code à exécuter par le thread
} ...
} }

Tache tache = new Tache(); }

Tache tache = new Tache();


Thread t = new Thread(tache);
ou Tache t = new Thread(new Tache());

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 14


Déclaration, création et lancement des threads (3)

 Exemple: un seul thread  2ème méthode: implémentation de


l'interface Runnable,
 1ère méthode : dérivation de la
classe Thread, public class TacheR implements Runnable {

public void run() {


public class TacheT extends Thread { [Link]("mon traitement");
}
public void run() {
[Link]("mon traitement"); public static void main(String[] args){
} Thread tacheR = new Thread(new
TacheR());
public static void main(String[] args){ [Link]();
TacheT tacheT = new TacheT(); }
[Link](); }
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 15


Déclaration, création et lancement des threads (4)
Quelle méthode choisir ?

 L'écriture du code est plus simple avec la dérivation de la classe Thread.


Chaque thread a ses propres données.

 Si on veut hériter d'une autre classe pour la classe qui contient la


méthode run(), on est obligé de choisir d'implémenter l'interface
Runnable.

 L'implémentation de l'interface Runnable facilite le partage des


traitements entre plusieurs threads.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 16


La classe Thread (1)
Exemple 1: L'affichage du thread et son créateur, le main
public class Thread1 {
public static void main(String[] args) {
Thread t = new Thread() { // on peut nommer le thread new Thread("Mon thread");
public void run() {
[Link]("Je suis bien dans le thread: "+
[Link]().getName()); // je suis dans le thread: Thread-0
}
};
[Link]();
[Link]("Je suis dans le thread: "+
[Link]().getName()); // je suis dans le thread : main
}
}

Console: l'ordre n'est pas respecté, les 2 threads s'exécutent en parallèle


Je suis dans le thread: main
Je suis dans le thread: Thread-0 ou Mon thread

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 17


La classe Thread (2)
Exemple 2: Création d'un thread qui affiche 10 fois son nom et un entier croissant,
class Thread2 extends Thread {
public Thread2(String nom) {
super(nom);
}
public void run() {
for(int i=0; i<10; i++) {
[Link](getName()+ " "+ i);
[Link](getName() + i +" terminé");
}
}
}
Un programme qui fait tourner en parallèle 2 exemplaires de ce thread:
public class Test2Threads {
public static void main(String[] args) {
new Thread2("Taza").start();
new Thread2("Casa Blanca").start();
}
}
Remarque : l'exécution n'est pas reproductible et l'ordre n'est pas respectée et possibilité de chevauchement !

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 18


La classe Thread (3)

 Exemple:
Création d'un thread qui affiche 10 fois son nom et
un entier croissant, puis s'endort pour une période de
1000 millisecondes

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 19


La classe Thread (4)
class ThreadSimple extends Thread {

public ThreadSimple(String nom) {


super(nom);
}

public void run() {


for(int i=0; i<10; i++) {
[Link](getName()+" "+i);
try { // la méthode sleep doit toujours être appelée dans un bloc try...catch
sleep((long)(1000));
} catch (InterruptedException e) {
}
[Link](getName()+ " terminé");
}}
}
Remarques :
La méthode sleep doit être appelée dans un bloc try...catch car c'est par le lancement d'une
exception InterruptedException que le thread endormi est réveillé si le temps indiqué est écoulé.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 20


La classe Thread (5)
Un programme qui fait tourner en parallèle 2 exemplaires de ce thread:
public class Test2Threads {
public static void main(String[] args) {
new ThreadSimple("Taza").start();
new ThreadSimple("Casa Blanca").start();
}
}

Remarque:
2 exécutions successives peuvent donner lieu à des imbrications "Taza"
et "Casa Blanca" différentes!
Résultat:
Taza 0
Casa Blanca 0
Taza terminé
Taza 1
Casa Blanca terminé Casa Blanca 1 Casa Blanca terminé Casa Blanca 2 ....

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 21


L'interface Runnable (1)
 La classe se déclare comme dans l'exemple précédent, mais on implémente Runnable au lieu
d'hériter de Thread :
class MonThread2 implements Runnable {
MonThread2() {
//code du constructeur
}
public void run() {
//code à exécuter dans le thread
}
}
 Pour créer et lancer un thread, on crée d'abord une instance de MonThread2, puis une instance
de Thread sur laquelle on appelle la méthode start() :
MonThread2 p = new MonThread2();
Thread t = new Thread(p);
[Link]();

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 22


L'interface Runnable (2)

Exemple 1:
class MonThread2 implements Runnable {
public void run() {
[Link] ("Je suis un thread !");
}
public static void main (String args []) {
// Un thread possède optionnellement un nom
Thread t = new Thread (new MonThread2(), "Mon Thread");
// [Link]() est démarré dans un nouveau thread après l'appel de start()
[Link]();
[Link] ("Ce code s'exécute en // de run()");
}
}
Résultat: Ce code s'exécute en // de run ()
Je suis un thread !

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 23


L'interface Runnable (3)
Exemple 2: un même Runnable est passé à 2 threads:
public class NouveauThreadAvecRunnable {
public static void main(String[] args) {
// le traitement encapsulé dans un Runnable
Runnable traitement = new Runnable() { // #1
public void run() {
[Link]("Je suis dans le thread: "
+ [Link]().getName());
}
};
Thread t1 = new Thread(traitement, "Premier thread"); // #2
[Link]();
Thread t2 = new Thread(traitement, "Second thread");
[Link]();
[Link]("Je suis dans le thread: "
+ [Link]().getName());
}
}
- Le traitement à exécuter , encapsulé dans un Runnable en #1, est passé à 2 threads en #2.
- L'ordre d'exécution par le processeur des différents threads est imprévisible et non
reproductible
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 24
La gestion de la priorité d'un Thread (1)

 La priorité du nouveau thread est égale à celle du thread dans lequel il est
créé.
 Un thread ayant une priorité plus haute recevra plus fréquemment le
processeur qu'un autre thread,
 La priorité d'un thread varie de 1 à 10. La classe Thread définit trois
constantes :
◦ MIN_PRIORITY : priorité inférieure (0)
◦ NORM_PRIORITY : priorité standard (5 : la valeur par défaut)
◦ MAX_PRIORITY : priorité supérieure (10)
 Pour déterminer la priorité d'un thread on utilise la méthode
getPriority() pour la modifier on utilise setPriority(int).

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 25


La gestion de la priorité d'un Thread (2)
public class Priorite1 extends Thread { // l'exemple fonctionne bien pour les données de priorité, mais pas
l'ordre
String chaine;
public Priorite(String chaine) {
[Link]=chaine;
}
public void run() {
[Link](chaine);
}
public static void main(String[] argv) {
[Link]("priorite actuelle : "+ [Link]().getPriority());
[Link]("priorite minimale : "+ Thread.MIN_PRIORITY);
[Link]("priorite normale : "+ Thread.NORM_PRIORITY);
[Link]("priorite maximale : "+ Thread.MAX_PRIORITY);
[Link]("Nombre de threads : " + [Link]());
//les trois threads qui suivent vont tourner en parallèle avec le thread main,
Priorite t1 = new Priorite("Taza"); [Link](Thread.MIN_PRIORITY); [Link]();
Priorite t2 = new Priorite("Rabat"); [Link](Thread.NORM_PRIORITY); [Link]();
Priorite t3 = new Priorite("Casa"); [Link](Thread.MAX_PRIORITY); [Link]();
}
}
// Les règles de priorité ne sont pas toujours respectées.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 26


La gestion de la priorité d'un Thread (3)
Résultat :

priorite actuelle : 5
priorite minimale : 1
priorite normale : 5
priorite maximale : 10
Nombre de threads : 1
Taza
Rabat
Casa

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 27


Synchronisation
 Les threads s'exécutant en parallèle sur des données qui peuvent être
communes, il faut gérer des conflits d'accès et des problèmes de
synchronisation entre threads.
 La synchronisation peut consister à entremêler les exécutions des threads de
manière à ce qu'ils n'accèdent à certaines données ou à certains morceaux de
code que chacun à leur tour alternativement.
 Une méthode plus simple est la synchronisation sur terminaison :
on veut qu'un morceau de code ne s'exécute qu'après qu'un thread
donné ait terminé.
[Link]() permet une telle synchronisation, la suite ne sera exécutée que
si t a terminé. Cette méthode lève une exception :
try {
[Link]();
} catch (InterruptedException e) {}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 28


Exemple: la somme des éléments d'un vecteur
Ecrire un programme qui calcule la somme des éléments d'un tableau:
int tableau[]={1,5,6,3,7,8,9,5};

1- Avec un seul thread;


2- Avec 2 threads qui se partagent le travail

le principe de cet algorithme:

Un constructeur qui a pour (entrées): le tableau, indice minimal, et


l'indice maximal, utilisés par les deux threads :

Chaque thread avec comme paramètres, le tableau et les indices min


et max de la partie qu'il va traiter.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 29


Solution 1: avec un seul thread
public class Somme1Thread extends Thread {
static int s = 0; // pour que cette variable qui calcule la somme soit accessible par run()
int y, z;
int[] x;
public Somme1Thread(int[] tab, int min, int max) {
x = tab; y = min; z = max;
}
public void run() {
for (int i = y; i <= z; i++) {
s = s + x[i];
[Link]("la valeur que contient "+ [Link]()+" s"+i+"="+s);
}
[Link]("---> la somme finale = " + Somme1Thread.s);
}
public static void main(String[] args) {
int tableau[]={1,5,6,3,7,8,9,5};
Somme1Thread t = new Somme1Thread (tableau,0 , 7);
[Link]();
}
}
Résultat : ---> la somme finale = 44 , les valeurs sont pris dans l'ordre

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 30


Solution 2: avec 2 threads
public class Somme2Threads extends Thread {
static int s = 0; // pour qu'elle soit accessible par run()
int y, z;
int[] x;
public Somme2Threads(int[] tab, int min, int max) {
x = tab; y = min; z = max;
}
public void run() {
for (int i = y; i <= z; i++) {
s = s + x[i];
[Link]("la valeur que contient "+ [Link]() +" s"+i+" = "+s);
}
}
public static void main(String[] args) {
int tableau[]={1,5,6,3,7,8,9,5};
Somme2Threads a = new Somme2Threads (tableau, 0, 3);
Somme2Threads b = new Somme2Threads (tableau, 4, 7);
[Link](); [Link]();
/* pour que le programme n'affiche pas la somme tant que les deux threads n'ont pas fini */
try {
[Link](); [Link](); // sans join, la somme finale peut être calculée avant
} catch (InterruptedException e) {}
[Link]("---> la somme finale = " + Somme2Threads.s);
}
}
Résultat : ---> la somme finale = 44

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 31


Exemple : mise à jour d'une horloge (1)

Un programme qui affiche un cadre dont la barre de titre affiche


constamment l'heure courante à la seconde près.
Pour cela, il suffit de créer, en même temps que le cadre, un 2ème
thread qui dort la plupart du temps, se réveillant chaque seconde pour mettre
à jour le texte affiché dans le cadre de titre:

import [Link];
import [Link];
import [Link];

import [Link];
public class CadreAvecHeure extends JFrame {
private String titre;

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 32


Exemple : mise à jour d'une horloge (2)

public CadreAvecHeure(String titre) {


super(titre);
[Link] = titre;
new Thread(new Runnable() {
public void run() {
gererAffichageHeure();
}
}).start(); // implémentation de Runnable
setDefaultCloseOperation(3);
setSize(600, 400);
setVisible(true);
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 33


Exemple : mise à jour d'une horloge (3)
public void gererAffichageHeure(){
while (true) {
try {
[Link](1000); // une seconde
} catch(InterruptedException e) {
}
Date h = [Link]().getTime();
String affichage_heure =
[Link]().format(h);
setTitle(titre + " " + affichage_heure);
}
}
public static void main(String[] args){
new CadreAvecHeure("Test affichage heure");
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 34
Format des Dates
import [Link];
import [Link];

public class PrintfExamples {


public static void main(String[] args) {

[Link]("The DATE is %tD\n", new Date() ); // The DATE is 10/31/08


[Link]("The DATE is %tF\n", new Date() ); // The DATE is 2008-10-31
[Link]("The DATE is %tr\n", new Date() ); // The DATE is 04:29:46 PM
[Link]("The DATE is %tR\n", new Date()); // The DATE is 16:29
[Link]("The DATE is %tT\n", new Date()); // The DATE is 16:29:46
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 35


Un chronomètre
Avec les threads:
Considérons le cas d'une répétition d'une certaine tâche à intervalles réguliers.
Une première technique pour le faire est d'utiliser la méthode sleep pour endormir le
thread durant un certain temps. On pourrait par exemple réaliser un Chrono ainsi :
import [Link];
public class SimpleChrono {
public static void main (String[] args) {
try {
boolean fin = false;
while (! fin) {
// Exécution de la tâche
[Link] ("%tT\n", new Date()); // format 16:43:26
[Link] (2000); // en pause pour deux secondes
}
}
catch (InterruptedException exception){}
}
}
Console : l'heure s'affiche chaque 2 secondes

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 36


Les Threads et les Timers (1)
Les threads peuvent gérer le temps:

Exemples:
Un Thread peut repousser une action dans le temps:
- Dans 3 secondes, si l'utilisateur n'a pas bougé sa souris, afficher un
popup disant: "Ce bouton sert à quitter le document".
Un Thread peut répéter une action régulièrement:
- Toutes les 5 secondes, redessine la barre de progression.

 Pour des cas simples, pas besoin d'utiliser des Threads; c'est plus
simple d'utiliser un Timer.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 37


Les Threads et les Timers (2)
Le paquetage [Link] contient une classe Timer pour déclencher
une action périodiquement toutes les n millisecondes.
Nous pouvons l'associer à l'écouteur d'événements ActionListener
pour déclencher périodiquement un traitement associé.

Exemple: Déclencher un traitement à chaque seconde


ActionListener ecouteur = new ActionListener (ActionEvent ev);
Timer periode = new Timer(1000, ecouteur);

Les méthodes associées à un Timer sont :


- start(): démarre le Timer, le traitement associé à l'écouteur est sollicité à
chaque notification du temps écoulé,
- stop(): arrête le Timer, le traitement ne sera pas sollicité.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 38


Les Threads et les Timers (3)
Avec les threads:
public class HorlogeSimple1 extends JFrame {
private JLabel heure = new JLabel();
public HorlogeSimple1() {
setTitle("Horloge avec Thread");
[Link](new Font("Arial", [Link]+[Link], 32));
[Link]([Link]);
add(heure);
[Link]();
setSize(250, 100); setDefaultCloseOperation(3); setVisible(true);
}
private Thread minuteur = new Thread() {
public void run() {
try {
boolean finished = false;
while (! finished) {
[Link] (2000); // En pause pour deux secondes
[Link]([Link]([Link]).format(new Date()));
}
}
catch (InterruptedException exception) {}
}; };
public static void main(String[] args) {new HorlogeSimple1();}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 39
Les Threads et les Timers (4)
Avec les Timers :
Exemple:
public class HorlogeSimple2 extends JFrame implements ActionListener {
Timer minuteur = new Timer(2000, this); //création d'un Timer avec une période de 2s
JLabel heure = new JLabel();
public HorlogeSimple2() {
setTitle("Horloge avec Timer");
[Link](new Font("Arial", [Link]+[Link], 32));
[Link]([Link]);
add(heure);
[Link](); // démarrer le Timer
setSize(300, 100);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public void actionPerformed(ActionEvent ev) {
[Link]([Link]([Link]).format(new Date()));
}
public static void main(String[] args) {
new HorlogeSimple2();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 40
Le modèle de conception MVC (1)
L'origine:
Le modèle de conception MVC [le langage smalltalk, 1981]

Objectif:
séparer le noyau fonctionnel de l’interface;

Principe:
 Le modèle maintient son état et notifie de ses modifications.
 Le contrôleur écoute l’utilisateur et demande des modifications au modèle.
 La vue écoute les notifications et interroge le modèle pour le représenter
correctement.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 41


Le modèle de conception MVC (2)
MVC à la Swing :

Dans Java/Swing, la vue et le contrôleur sont réunis au sein d’une même


classe (UIComponent), ce qui résout le problème du couplage
vue/contrôleur.
Chaque JComponent crée un modèle qui peut être partagé avec un autre
JComponent.

exemple: JSlider et JScrollBar ont pour modèle un BoundedRangeModel

42
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018
Le modèle de conception MVC (3)
Principe:
 Modèle: gère les données et reprend la logique métier.
Le modèle ne prend en compte aucun élément de présentation!

 Vue: elle affiche les données, provenant exclusivement du modèle, pour l'utilisateur et/ou
reçoit ses actions.
Aucun traitement – autre que la gestion de présentation - n'y est réalisé.

 Contrôleur: son rôle est de traiter les événements en provenance de l’interface


utilisateur et les transmet au modèle pour le faire évoluer ou à la vue pour modifier son
aspect visuel (pas de modification des données affichées mais des modifications de
présentation (couleur de fond, affichage ou non de la légende d’un graphique, … )).
ne modifie aucune donnée et n'effectue aucun traitement.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 43


Le modèle de conception MVC (4)

 Le contrôleur connaît la (les) vues qu’il contrôle ainsi que le modèle.


 Le contrôleur pourra appeler des méthodes du modèle pour réagir à des
événements, il pourra faire modifier à la vue son aspect visuel. Il pourra
aussi instancier de nouvelles vues (demande d’affichage de telle ou telle
info). Pour faire cela, le contrôleur sera à l'écoute d'événements survenant
sur les vues.
 La vue observera le modèle qui l'avertira du fait qu'une modification est
survenue. Dans ce cas, la vue interrogera le modèle pour obtenir son
nouvel 'état'.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 44


Le modèle de conception MVC (5)
Le concept de modélisation MVC définit les interactions entre les
trois composants:

Modèle
mettre à jour manipule

Vue Contrôlleur
voir utiliser
Utilisateur
Nous pouvons schématiser cela comme suit en percevant bien que
nous pouvons avoir plusieurs contrôleurs, plusieurs vues mais un seul
modèle.
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 45
Application 1 (1)
Exemple:
Une application simple avec le modèle de conception MVC:

- Une fenêtre avec un bouton "Compteur", si on clique dessus, on incrémente un


compteur et on affiche le résultat sur une étiquette.

Résultat:

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 46


Application 1 (2)
 La classe [Link]
 Ce modèle simple a une valeur privée "x".
 Cette variable est initialisée à 0 par le constructeur du Modèle par défaut, ou modifie sa
valeur par le constructeur Modele(int x).
 Les méthodes incX() et getX() donnent accès à "x",
 La méthode incX() incrémente "x", et la méthode getX retourne juste sa valeur.

 Notez que le Modèle ne connait RIEN sur la Vue et le Controleur.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 47


Application 1 (3)
public class Modele {

private int x;

public Modele(){
x = 0;
}

public Modele(int x){


this.x = x;
}

public void incX(){


x++;
}

public int getX(){


return x;
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 48
Application 1 (4)
 La classe [Link]
 Cette classe crée une fenêtre et y ajoute une étiquette et un bouton.
 La méthode publique setText(String texte) permet de mettre le texte dans l'étiquette,
 La méthode getButton() retourne une référence du bouton.

 Noter que la Vue ne connait rien sur le Modele et le Controleur.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 49


Application 1 (5)
public class Vue extends JFrame {
private JLabel etiquette;
private JButton bouton;
public Vue(String texte){
JPanel p = new JPanel();
[Link](new BorderLayout());
setTitle("MVC simple");
setLayout(new BorderLayout());
setDefaultCloseOperation(3);
setSize(300,150);
etiquette = new JLabel(texte, [Link]);
[Link](new Font("Times Roman", [Link], 20));
[Link](etiquette, [Link]);
bouton = new JButton("Compteur");
[Link](bouton, [Link]);
add(p);
setVisible(true);
}
public JButton getButton(){
return bouton;
}
public void setText(String texte){
[Link](texte);
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 50
Application 1 (6)
 La classe [Link]
 La classe Controleur conserve les références des classes Modele et Vue.
 Ainsi le Controleur voit les interfaces Modele et Vue.
 Le Controleur fournit l'interaction entre le Modele et la Vue.
 La méthode control() donne une référence au bouton de la vue et lui associe
ActionLisener.
 Dans actionPerformed(), la méthode lier() est appelée.
 Dans la méthode lier(), la variable du Modele 'x' est incrémentée et ensuite envoyée à
l'étiquette de la Vue pour afficher le changement.

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 51


Application 1 (7)
public class Controleur {
private Modele modele;
private Vue vue;
private ActionListener actionListener;
public Controleur(Modele modele, Vue vue){
[Link] = modele;
[Link] = vue;
}
public void control(){
actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
lier();
}
};
[Link]().addActionListener(actionListener);
}
private void lier(){
[Link]();
[Link]([Link]([Link]()));
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 52
Application 1 (8)
 La classe principale [Link]
 Cette classe crée des objets des classes: Modele, Vue et Controleur, initialise le
Controleur par le Modele et la Vue et appelle la méthode Control() de la classe
Controleur.

public class GestionMVC {


public static void main(String[] args) {
Modele modele = new Modele(0);
Vue vue = new Vue("0");
[Link](true);
Controleur controleur = new Controleur(modele,vue);
[Link]();
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 53


Application 2 (1)
 1ère version: sans le modèle de conception MVC
 Une interface avec 2 boutons et une étiquette.
 Une classe de boutons
class MonBouton extends JButton {
int incr;
MonBouton(String titre, int incr) {
super(titre);
[Link] = incr;
}
int getIncr() { return incr; }
}
 Une classe d’étiquette avec écouteur,
class Etiquette extends JLabel implements ActionListener {

Etiquette() { super("0", [Link]);}


public void actionPerformed(ActionEvent ev) {
MonBouton b = (MonBouton)[Link]();
int c = [Link](getText());
c += [Link]();
setText([Link](c));
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 54
Application 2 (2)
 1ère version (suite): sans le modèle de conception MVC
 L'interface graphique

public class PlusOuMoins extends JFrame {


public PlusOuMoins() {
super("+ ou -");
JButton plus = new MonBouton("Plus", +1);
JButton moins = new MonBouton("Moins", -1);
JLabel etiquette = new Etiquette();
add(plus, "North");
add(etiquette,"Center");
add(moins,"South");
[Link]((ActionListener) etiquette);
[Link]((ActionListener) etiquette);
};
public static void main (String[] argv) {
JFrame f = new PlusOuMoins();
[Link](200, 150);
[Link](true);
[Link](3);
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 55


Application 2 (3)
 2ème version: avec le modèle de conception MVC
 le modèle gère les données
 la vue affiche les données
 le contrôleur gère la communication et les mises-à-jour
 La classe principale
class PlusOuMoinsMVC {
Modele modele;
Vue vue;
Controleur control;
public PlusOuMoinsMVC() {
modele = new Modele();
control = new Controleur(); Console
vue = new Vue(control); Vue à Contrôleur : bouton Plus
[Link](modele); Contrôleur à Modèle : changer compteur de 1
[Link](vue); Contrôleur à Modèle : que vaut compteur ? réponse = 1
[Link](true); Contrôleur à Vue : afficher compteur dans étiquette
[Link](3);
}
public static void main (String[] argv) {
PlusOuMoinsMVC f = new PlusOuMoinsMVC();
}
}
Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 56
Application 2 (4)
 2ème version: avec le modèle de conception MVC (model -view -controller)
Echange de messages ?
Vue à contrôleur : bouton Plus
Contrôleur à modèle : changer compteur de 1
Contrôleur à modèle : que vaut compteur? réponse = 1
Contrôleur à vue : afficher compteur dans étiquette
Vue à contrôleur : bouton Plus
Contrôleur à modèle : changer compteur de 1
Contrôleur à modèle : que vaut compteur? réponse = 2
Contrôleur à vue : afficher compteur dans étiquette
Vue à contrôleur : bouton Moins
Contrôleur à modèle : changer compteur de -1
Contrôleur à modèle : que vaut compteur ? réponse = 1
Contrôleur à vue : afficher compteur dans étiquette
...

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 57


Application 2 (5)

 Le Modèle class Modele {


int compteur;
 Le modèle contient la donnée
Modele() {
 La mise-à-jour par mettreAjour() compteur = 0;
 Le renseignement par getValue() }
void mettreAjour(int incr) {
compteur += incr;
}
int getValue() {
return compteur;
}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 58


Application 2 (6)
 La Vue class Vue extends JFrame {
JButton plus = new JButton("Plus");
JButton moins = new JButton("Moins");
 La vue affiche les composants et JLabel etiquette=new JLabel("0",[Link]);
les données public View(Controleur c) {
super("+ ou -");
 La mise-à-jour (du texte de add(plus,[Link]);
add(moins,[Link]);
l’étiquette est faite par add(etiquette,[Link]);
mettreAjour() [Link](c);
[Link](c);
 La notification de modifications ssetSize(250, 150);
}
au contrôleur. C’est le contrôleur void mettreAjour()(int compte) {
qui écoute ! }
[Link]([Link](compte));

int getValue(ActionEvent ev) {


 Les renseignements sont pris par JButton b = (JButton)[Link]();
getValue(). }
return (b == plus) ? 1 : -1;

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 59


Application 2 (7)
class Controleur implements ActionListener {
private Modele m;
private Vue v;
 Le Contrôleur: public void actionPerformed(ActionEvent ev) {
JButton b = (JButton)[Link]();
 Alerté par les actions String message = "Vue à Contrôleur: bouton "+
produites dans la Vue [Link]();
[Link](message);
int incr = [Link](ev);
 Récupère des informations [Link](incr);
dans la Vue message="Contrôleur à Modèle: changer compteur de"+ incr;
[Link](message);
 Met à jour dans le modèle [Link]([Link]());
message = "Contrôleur à Modèle : "+"que vaut compteur?
 Récupère la nouvelle valeur réponse= " + [Link]();
dans le modèle [Link](message);
message = "Contrôleur à Vue: afficher compteur dans
étiquette";
 La transmet pour affichage [Link](message);
à la vue }
void setModele(Modele m) {this.m = m;}
void setVue(Vue v) {this.v = v;}
}

Prof M.D. RAHMANI Interface Homme-Machine SMI - S6 Année 2017-2018 60

Vous aimerez peut-être aussi