Programmation des Interfaces

publicité
Interfaces graphiques (GUIs)
Cours 2a :
Programmation des
interfaces graphiques
[email protected]
l'interaction graphique : les entrées sont spécifiées
directement à partir des sorties.
Le périphérique d’entrée spécifie une commande de
position à l'écran qui désigne un objet
précédemment affiché par le système (pointage).
Elle est familière dans le monde physique.
(partie de la présentation basée sur des transparents d’Anastasia Bezerianos,
Fanis Tsandilas et Michel Beaudouin-Lafon)
Interfaces WIMP
Couches logicielles
WIMP : Window, Icons, Menus and Pointing
Fenêtres, Icones, menus et pointage.
Présentation
Fenêtre, icones et autres objets graphiques
Interaction
Menus, boites de dialogue, texte
Entrée
pointage, sélection, tracé
Boucle action perception
Feedback
Squelette d’application
MacApp
Java Swing, Qt, GTK+, MFC, Cocoa
X Windows
GDI+, Quartz, GTK+/Xlib, OpenGL
Windows, Mac OS X, Linux
Couches logicielles
Dispositifs d’entrée/sortie
Entrée : Saisir des commandes et des données
Sortie : le système affiche de l’information et montre son état
Squelette d’application
MacApp
Java Swing, Qt, GTK+, MFC, Cocoa
X Windows
GDI+, Quartz, GTK+/Xlib, OpenGL
Windows, Mac OS X, Linux
Interactivité vs. Algorithmique
système algorithmique (fermés) :
–  lit des entrées, calcule, produit un
résultat
–  il y a un état final
système interactif (ouverts) :
–  évènements provenant de l’extérieur
–  boucle infinie, non déterministe
Problème
vous avez appris à programmer des algorithmes
(la partie “calcul”)
la plupart des langages de programmation (C, C
++, Java, Lisp, Scheme, Ada, Pascal, Fortran,
Cobol, ...) sont conçus pour écrire des
algorithmes, pas des systèmes interactifs
Problème
Traitement des entrées/sorties pendant le calcul
–  Instructions de sortie (print, put, send,…)
pour envoyer des données aux périphériques
–  Instructions de lecture (read, get, receive,
…) pour lire l’état ou changement d’états de
périphériques d’entrée, du façon bloquante
Problème
obligés d’écrire des SI sous une forme
algorithmique :
afficher deux boutons B1 et B2!
fini <- faux!
tantque non fini faire!
! !bouton <- attendreClic () // attente bloquante!
! !selon bouton!
! ! !B1 : afficher « Bonjour »!
! ! !B2 : fini <- vrai!
! !fin!
fin
Comment gérer les entrées
- 1 pér. à la fois
-  Attente active
-  état des plusieurs pér.
- CPU
Programmation évènementielle
File d’attente (queue)
queue.enqueue(event)
while active!
if queue is not empty!
event <- queue.dequeue()!
source <- findSource(event)!
source.processEvent(event)!
end if!
end while!
!
!
!
!
Programmation évènementielle
Source :
Mouse Click
File d’attente (queue)
queue.enqueue(event)
Cible :
Bouton « Cancel »
while active!
if queue is not empty!
event <- queue.dequeue()!
source <- findSource(event)!
source.processEvent(event)!
end if!
end while!
!
!
!
!
!
processEvent(event)!
target <- FindTarget (event)!
if (target ≠ NULL)!
!target.processEvent(event)!
!
!
!
!
Couches logicielles
Squelette d’application
Exemple : Swing (AWT)
3 processus
•  Initial : main()
•  EDT gères la liste d’évènements :
envoie les évènements aux
listeners et appel la méthode paint
•  Tache de fond : exécute les actions
plus longues
Constructeurs d’interface
MacApp
Java Swing, Qt, GTK+, MFC, Cocoa
X Windows
GDI+, Quartz, GTK+/Xlib, OpenGL
Windows, Mac OS X, Linux
Exemples : MS Visual Studio (C++, C#, etc.), NetBeans (Java),
Interface Builder (ObjectiveC)
Constructeurs d’interface
Utiles pour :
–  Créer des prototypes
–  Tests d’apparence
–  Conception rapide
–  Débutants
Boîte à outils d’interface
Bibliothèques d’objets interactifs (les « widgets »)
que l’on assemble pour construire l’interface
Fonctionnalités pour faciliter la programmation
d’applications graphiques interactives
Attention à la qualité du code généré !
Boîte à outils d’interface
Pourquoi Java Swing
Java (toutes plateformes et beaucoup de librairies)
Beaucoup de ressources en ligne
Pourquoi Java Swing
Java (toutes plateformes et beaucoup de librairies)
Beaucoup de ressources en ligne
les « widgets »
bouton
menu
fenêtre
barre d’outils
onglet
Alternatives
•  JavaFX : s’impose petit à petit pour les interfaces
en Java car permet de travailler avec beaucoup
de matériel différent.
étiquette
zone de texte
bouton radio
liste
barre de
défilement
« slider »
les widgets de Swing
les widgets de Swing
Complexité des widgets
Hiérarchie des widgets
–  un composant ne peut appartenir qu’à un seul « container »
widgets « simples »
Racine (composé)
correspond à une
fenêtre de l’appli
buttons, barres de défilement, …
widgets « composés »
Nœuds (composé)
Structure visuel ou
fonctionnel du contenu
Destinés à contenir d’autres widgets (simples ou
composés)
Boites de dialogue, menus, …
Feuille (simple)
avec lesquels l’utilisateur
peut interagir
Classes des widgets SWING
Une application graphique à un containeur principal qui contient tous les
autres.
3 types différents dans SWING : Jframe, Jdialog et Japplet
Ils contiennent tous des widgets qui sont contenus dans le content pane
JFrame
Public static void main (String[] args) {
JFrame frame = new JFrame (Ma première fenêtre);
frame.setVisible(true);
}
Dialog
Exercice
Public static void main (String[] args) {
JFrame frame = new JFrame (« Ma première fenêtre »);
frame.setVisible(true);
JDialog dialog = new JDialog (frame, « Hello world », true);
Identifier les widgets de cette interface
}
Modale
les « widgets »
bouton
menu
Facettes des widgets
fenêtre
barre d’outils
onglet
étiquette
zone de texte
bouton radio
liste
barre de
défilement
« slider »
Facettes des widgets
Présentation
Facettes des widgets
Exemple : Bouton
apparence graphique
Présentation
Comportement
cadre avec un nom à l’intérieur
réactions aux actions de l’utilisateur
Comportement
Interfaçage avec l’application :
notifications de changement d’état
« enfoncement » ou « relâchement » lorsque l’on clique dessus
Interfaçage avec l’application :
fonction appelée lorsque le bouton est cliqué
Facettes des widgets
Exemple : Slider
Présentation
?
Comportement
?
Interfaçage avec l’application :
?
Facettes d’un widget
Notifications de changement d’état :
–  variables actives (Tcl/Tk)
–  envoi d’évènements(Qt)
–  fonctions de rappel (« callbacks »)
Variables actives
Envoi d’évènements
lien bidirectionnel entre une variable d’état du widget
et une variable de l’application
Les widgets agissent comme des périphériques
d’entrée et envoient des évènements.
Une boucle tant que lit et traite les évènements
Association d’un objet à un widget et de
méthodes de l’objet aux changements d’état
problèmes
–  limité aux types simples
–  lien de retour peut être coûteux
–  Erreurs si les liens sont mis à jour par des développeurs
Envoi d’évènements
Sépare l’envoi et le traitement des évènements
Fonctions de rappel
Enregistrement lors de la création du widget
Meilleure encapsulation
Appel lors l’activation du widget
Fonctions de rappel
Problème : spaghetti des callbacks
Partage d’état entre plusieurs callbacks par :
–  variables globales
•  Trop dans une application réelle
–  arbre des widgets : la fonction de rappel est appelée en lui passant
le widget qui l’a déclenché
•  Fragile si l’on change la structure, insuffisante pour d’autres données
pas associés aux widgets
–  « jeton » (token) : donnée enregistrée avec la callback, passée
automatiquement au moment de l’appel
« event listeners » (Java)
Variante des callbacks adaptée au Java:
fonctions de rappel
/* fonction de rappel */ !
void DoSave (Widget w, void* data) {!
!/* récupérer le nom de fichier */!
! filename = (char**) data; !
!/* appeler la fonction de l’application */ !
!SaveTo (filename); !
!/* fermer la boîte de dialogue */ !
!CloseWinfow (getParent(getParent(w)));!
}!
!
/* programme principal */ !
main () {!
!/* variable contenant le nom du fichier */ !
!char* filename = “”; !
!… !
!/* créer le widgets et lui associer sa callback */ !
!ok = CreateButton (....);!
!RegisterCallback (ok, DoSave, (void*) &filename); !
!…!
!/* boucle de traitement des événements */ !
!MainLoop ();!
}!
« event listeners » (Java)
public class ClickListener implements ActionListener {!
!public void actionPerformed(ActionEvent e){!
Méthodes de type AddListener spécifient non pas
une fonction de callback, mais un objet (le
listener)
!
!JButton button = (JButton)e.getSource();!
!
!…!
!}!
}!
!
Lorsque le widget change d’état, il déclenche une
méthode prédéfinie du listener (par exemple
actionPerformed)
…!
ClickListener listener = new ClickListener();!
JButton button = new JButton(’’Click me’’); !
button.addActionListener(listener);!
…!
« event listeners » (Java)
Anonymous Inner classes
…!
button.addActionListener(new ActionListener(){!
!
!public void actionPerformed(ActionEvent e){!
!
!
!
!}!
!…!
});!
…!
panel.addMouseListener(new MouseAdapter(){!
!
!public void mouseClicked(MouseEvent e){!
!
!
!
!}!
!… !
});!
Fonctions et évènements prédéfinis
!
Evènements et Ecouteurs
Chaque évènement à une source (Jbutton, JRadioButton, Jmenu,
JTextField) à laquelle on accède via la méthode getSource()
« event listeners » (Java)
Anonymous Inner classes
“new <nom-de-classe> () { <corps> }”
cette construction fait deux choses :
!  elle crée une nouvelle classe, sans nom, qui est
une sous-classe de <nom-de-classe> définie par
<corps>
!  elle crée une instance (unique) de cette nouvelle
classe et retourne sa valeur
Cette class a accès aux variables et méthodes de
la classe dans la quelle elle est définie !
Evènements et Ecouteurs
Tous les évènements héritent de la classe EventObject
Tous les listeners héritent de EventListener
Les listeners doivent implémenter l’interface qui correspond aux
évènements.
Ex : ActionEvent => ActionListener
Quelques couple Events – Listener
•  ActionEvent
ActionListener
•  MouseEvent
MouseListener
•  KeyEvent
KeyListener
•  …
Evènements et Ecouteurs
Les listeners doivent être enregistrés (ajoutés) aux widgets.
Exercice
Identifier les listeners de cette interface
Un listener peut être ajouté à plusieurs widgets.
Un listener pour plusieurs boutons par exemple
Un widget peut avoir plusieurs listeners
Un pour le click et un pour la touche entrée sur un bouton
« drag-and-drop »
« drag-and-drop »
Quels sont les « widgets » affectés ?
Quels sont les évènements?
Quels sont les « widgets » affectés ?
Quels sont les évènements?
Exercice : comment décrire cette interaction
avec un « event listener » ?
Exercice : comment décrire cette interaction
avec un « event listener » ?
http://openclassrooms.com/courses/apprenez-a-programmer-en-java/le-drag-n-drop
Téléchargement