(Microsoft PowerPoint - Java 2007-awt.ppt [Mode de compatibilit\351])

publicité
Java – Conception d’interface
graphique (IHM
)(GUI
Jean-Pierre Fournier
http://www.iut-orsay.fr/~fournier
)
Une application informatique comporte :
une partie visible (front office)
interface homme-machine graphique interactif
présenté par l’application
interface homme-machine graphique interactif
présenté par un navigateur Web (avec formulaire et
applet)
une partie invisible (back office)
effectue les calculs, fournit et stocke les données
jeudi 15 novembre 2007
Java - AWT
2
Une application interactive comporte
Un modèle
Récupère et stocke les données, fournit des informations
Une vue
Présente les données que gère le modèle
Un contrôleur
Réagit aux actions de l'utilisateur
Ces trois éléments respectent le mode d'organisation
MVC (préconisé depuis 1979) [Trygve Reenskaug]
jeudi 15 novembre 2007
Java - AWT
3
MVC
Modèle
Vue
jeudi 15 novembre 2007
IHM
Java - AWT
Contrôleur
4
L’interface homme-machine
doit absolument rester réactive
=> jamais de traitement long
est sensible aux événements
clics souris
touches clavier
présence, gestes, sourires ?
des événements peuvent provenir d’autres
applications (fenêtres masquées, démasquées…)
jeudi 15 novembre 2007
Java - AWT
5
Les éléments nécessaires
des composants élémentaires (boutons, labels, listes de choix, zones
textuelles, zones de dessin…),
Button, Label, Choice, TextField, Canvas…
des conteneurs (cadres, panneaux…) : pour assembler des composants
élémentaires constituant un groupe,
Frame, Panel, JPanel…
des organiseurs de présentation qui définissent comment les
composants élémentaires seront placés les uns par rapport aux autres,
GridLayout, FlowLayout, CardLayout…
des réacteurs : petits traitements destinés à être déclenchés par les
événements
spécifiés par WindowListener, Actionlistener, KeyListener…
jeudi 15 novembre 2007
Java - AWT
6
Java propose
plusieurs familles de composants
AWT (Abstract Window Toolkit) : package java.awt,
les composants simples (depuis 1.0), s’appuient sur
les outils natifs, rapides et généralement suffisants
Swing (JFC) : package javax.swing, composants
complexes donnant le même aspect partout, plus
riche et (beaucoup) plus lent
SWT : variante « IBM » de l’AWT, employée
notamment pour Eclipse
jeudi 15 novembre 2007
Java - AWT
7
Exemple d'une application complète : le jeu du
pendu
Il comprendra 3 composants (M V C)
Le modèle saura quel mot doit être deviné
Le modèle saura, à chaque instant, quelles lettres ont
été proposées par le joueur
Le modèle saura si la partie est terminée, etc…
La vue présentera l'état du jeu en temps réel
Le contrôleur réagira aux actions de l'utilisateur
(proposition de lettre, etc…), en informera le modèle
et préviendra la vue de la nécessité éventuelle de
rafraîchir ce qu'elle présente
jeudi 15 novembre 2007
Java - AWT
8
Exemple d’une application complète : le jeu de
affichage
pendu
permanent du
Nous voudrions ce type
titre
bouton pour:
d’interface
quitter
temps écoulé
zone
de
saisie
jeudi 15 novembre 2007
zone de
dessin
bouton pour
quitter
Java - AWT
9
Etape 0 : M
Le jeu du pendu est un jeu dans lequel le joueur
doit deviner un mot en proposant des lettres
D'autres jeux : mots croisés, sudoku, superPendu,
etc. ont le même fondement
Donc : définition d'une interface qui sera
commune aux modèles de tous ces jeux (si elle
n'existe pas encore)
Puis : implémentation de cette interface dans le
cas particulier du pendu simple
jeudi 15 novembre 2007
Java - AWT
10
L'interface des modèles
public void proposition(char
lettre, int x, int y);
public String phraseAAfficher();
public int nombrePropositions();
public int nombreErreurs();
public boolean gagne();
public boolean perdu();
jeudi 15 novembre 2007
Java - AWT
11
Fin de l'étape 0
Écriture de notre modèle du jeu de pendu
Réalisation des tests unitaires qui permettront de garantir
son bon fonctionnement
Écriture de la classe qui lancera l'application :
Elle instancie la classe Modèle
Elle instancie la ou les classes Contrôleur
Elle instancie la classe Vue
Elle transmet à la vue les références du modèle et des
contrôleurs
Elle transmet aux contrôleurs les références de la vue et
du modèle
jeudi 15 novembre 2007
Java - AWT
12
Etape 1 : V
créer une classe dérivant de Frame
ici : class VueJeuDeLettres extends
Frame{
// définition des composants
// constructeur
// méthodes diverses
jeudi 15 novembre 2007
Java - AWT
13
Etape1 : décider quels composants graphiques
seront employés
un Canvas pour la zone de
dessin
un Label pour l’affichage du
temps écoulé
un TextField pour la zone de
saisie de lettres
un Button pour quitter
jeudi 15 novembre 2007
Java - AWT
14
Etape 2 : décider comment ils se placeront
si on ne fait rien :
FlowLayout par défaut
décision :
un BorderLayout pour la fenêtre
principale,
un GridLayout pour répartir également
les composants à droite (impose de les
rassembler dans un conteneur)
autres possibilités : CardLayout,
GridbagLayout…
ou aussi : null => les objets doivent alors
être tous placés et replacés en absolu
jeudi 15 novembre 2007
Java - AWT
15
Etape 3 : se préoccuper des dimensions et de
la place de la fenêtre
deux solutions :
décider de la taille extérieure de la fenêtre et adapter tous les
composants pour obtenir l’effet désiré : compliqué
un Label ou un Button dont la taille est figée ne pourra pas
nécessairement bien présenter son texte
décider la taille minimale de chaque composant et laisser java en
déduire la taille de la fenêtre (méthode pack())
attention : certains composants (Canvas) ont une taille initiale 0
x0
dans tous les cas : l’application doit s’attendre à ce que sa
fenêtre soit redimensionnée par l’utilisateur
=> dessins proportionnels et non absolus !
jeudi 15 novembre 2007
Java - AWT
16
Etape 4 : préparer les réactions aux
événements (liaison V <-> C)
en associant à chaque composant un ou plusieurs bouts de codes
destinés à être déclenchés par le gestionnaire de fenêtres si l’utilisateur
produit des événements dans cette fenêtre
Attention : ces méthodes sont
appelées très fréquemment, leur
clic sur un bouton,
traitement doit être ultrarapide
déplacement de la souris sur un objet
action au clavier
et même s’il produit des événements dans d’autres applications,
masquant ou démasquant :
méthodes public void update(Graphics cg) et
public void paint(Graphics cg)
Ces deux méthodes ne sont jamais appelées par votre programme, qui
ne peut appeler que repaint()
jeudi 15 novembre 2007
Java - AWT
17
Examen du code du jeu de Pendu…
jeudi 15 novembre 2007
Java - AWT
18
Les réacteurs (au sein du contrôleur)
sont des petits bouts de
code préparés dans
l’application alors qu’elle
n’est pas encore visible
pour être activés par les
gestionnaire de fenêtres à
la suite d’événements
ils doivent absolument
respecter les interfaces
prévus (package
java.awt.event)
jeudi 15 novembre 2007
Java - AWT
ActionListener
AdjustmentListener
AWTEventListener
ComponentListener
ContainerListener
FocusListener
HierarchyBoundsListener
HierarchyListener
InputMethodListener
ItemListener
KeyListener
MouseListener
MouseMotionListener
MouseWheelListener
TextListener
WindowFocusListener
WindowListener
WindowStateListener
19
Dans notre cas
Une réaction à prévoir quand l'utilisateur ferme la fenêtre
(action sur la croix Windows)
Un contrôleur devra donc implémenter la méthode
windowClosing() de WindowListener,
Une réaction à prévoir s'il clique sur le bouton "Quitter"
Un contrôleur devra donc implémenter la méthode
actionPerformed(…) de ActionListener,
Une réaction à prévoir s'il propose une lettre dans la
zone de saisie
Un contrôleur devra donc implémenter la méthode
keyTyped(…) de KeyListener.
jeudi 15 novembre 2007
Java - AWT
20
Trois manières de les placer
cas d’une réaction unique associée à un
événement unique dans une seule fenêtre
cas d’une réaction unique à des événements
multiples d’une même fenêtre
cas d’une réaction unique à des événements
multiples dans diverses fenêtres de l’application
jeudi 15 novembre 2007
Java - AWT
21
Placement de réacteur (1)
quitter.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
((Window) ((Component) arg0.getSource()).getParent().getParent()).dispose();
}
});
Le contrôleur ne reçoit que l'événement qui s'est
produit, il doit essayer de retrouver la fenêtre
principale : compliqué !
Dans ce cas, le contrôleur est caché à l'intérieur de la
vue : interdit dans le modèle MVC
jeudi 15 novembre 2007
Java - AWT
22
Placement de réacteur (2)
class Pendu extends Frame implements ActionListener{
…
dans le constructeur
quitter.addActionListener(this);
…
public void actionPerformed(ActionEvent e){…} parmi les méthodes de la
classe Pendu
Dans ce cas, le contrôleur et la vue ne font qu'un
: interdit dans le modèle MVC
jeudi 15 novembre 2007
Java - AWT
23
Placement de réacteur (3)
dans le constructeur
…
quitter.addActionListener(new Controleur());
…
une autre classe, dans
public class Controleur
un autre fichier
implements ActionListener{…}
Il pourra y avoir plusieurs contrôleurs…
jeudi 15 novembre 2007
Java - AWT
24
Cas de contrôleurs multiples
Ils ont en
commun
la vue et
le modèle
Attributs privés :
références de la
vue et du modèle
abstract class ControleurBase
Class ControleurBouton
extends
ControleurBase
implements
ActionListener
jeudi 15 novembre 2007
Accesseurs protégés
Class ControleurFenetre
extends
ControleurBase
implements WindowListener
Java - AWT
Class ControleurClavier
extends
ControleurBase
implements KeyListener
25
Le réacteur
reçoit un objet « événement » qui sait quel événement s’est produit,
quel composant est concerné (getSource()), où il s’est produit (x, y)…
on peut alors préciser de quel composant il s’agit
Soit parce qu'un seul composant est lié à ce contrôleur
soit parce qu’on le sait :
Button leBouton = (Button) arg.getSource();
soit en demandant :
if (arg0.getSource() instanceof java.awt.Button){…}
on peut alors remonter dans l’arborescence des composants attachés
succession de getParent()
Mais il vaut mieux que le contrôleur sache pour quelle
application il travaille
jeudi 15 novembre 2007
Java - AWT
26
Le réacteur doit être ultrarapide
tant qu’il travaille, le gestionnaire d’application qui l’a
appelé ne peut plus réagir aux événements
donc tout doit être fait avant l’apparition de la fenêtre pour
qu’il ne reste plus que des traitements rapides dans les réacteurs
ex : si un événement entraîne l’apparition d’une nouvelle
fenêtre, la construction de cette fenêtre a été anticipée, et le
réacteur fait seulement un setVisible(true)
ex : si un événement entraîne une recherche dans une base de
données, toute sa préparation doit avoir été faite avant
un traitement long ou répétitif peut toujours être placé dans un
autre processus, le réacteur se contente alors de le lancer…
jeudi 15 novembre 2007
Java - AWT
27
Listener vs Adapter
les interfaces de certains réacteurs sont riches
ex : WindowListener a 6 méthodes (extrait de la doc Java)
void windowActivated(WindowEvent e)
Invoked when the Window is set to be the active Window.
void windowClosed(WindowEvent e)
Invoked when a window has been closed as the result of calling dispose on the window.
void windowClosing(WindowEvent e)
Invoked when the user attempts to close the window from the window's system menu.
void windowDeactivated(WindowEvent e)
Invoked when a Window is no longer the active Window.
void windowDeiconified(WindowEvent e)
Invoked when a window is changed from a minimized to a normal state.
void windowIconified(WindowEvent e)
Invoked when a window is changed from a normal to a minimized state.
void windowOpened(WindowEvent e)
Invoked the first time a window is made visible.
pour éviter d’avoir à écrire des méthodes avec des corps vides, des classes java le font
pour vous :
exemple : abstract class WindowAdapter implements WindowListener
jeudi 15 novembre 2007
Java - AWT
28
Délégation de travaux longs ou répétés
Les Threads permettent de lancer des tâches
indépendantes
le traitement à réaliser est placé dans la méthode
public void run()
le processus est lancé par start()
il s’arrête de lui-même quand il a fini
jeudi 15 novembre 2007
Java - AWT
29
Exemple dans le jeu de Pendu à la fin du
constructeur :
dort pendant 0.5 seconde
new Thread(){
public synchronized void run(){
long initial = System.currentTimeMillis()/1000;
while (!modele.gagne() && !modele.perdu() && laVue.isVisible()){
try {
wait(500);
} catch (InterruptedException e) {/* */}
tempsEcoule.setText((System.currentTimeMillis()/1000-initial)+"
s.");
}
tempsEcoule.setText(((modele.gagne())?"gagné en ":"perdu en
")+(System.currentTimeMillis()/1000-initial)+" s.");
}
}.start();
modifie le texte du label
jeudi 15 novembre 2007
Java - AWT
30
Cette présentation
et le source du jeu du Pendu sont sur le wiki et
sur http://www.iut-orsay.fr/~fournier
jeudi 15 novembre 2007
Java - AWT
31
Téléchargement