Programmation événementielle
& interfaces graphiques Java Swing
Eric Lecolinet
Télécom Paris
[Link]/~elc Janvier 2021
Page 1 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Toolkits graphiques Java
Pour le Desktop
• JavaFX
nouveau, inspiré du Web
• Swing
• AWT Components
obsolète
• SWT
Eclipse Foundation
Swing
• est multi-plateformes
• repose sur AWT Components mais pas la même chose !
– attention : JButton != Button !
Page 2 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Composants Swing
Source: documentation IBM
Page 3 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Interacteurs
Page 4 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Boutons
JButton JCheckbox : JRadioButton :
choix idépendants choix exclusif : cf. ButtonGroup
Source: documentation Java Oracle
Page 5 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Texte
JTextField
JPasswordField
JTextArea :
texte simple multilignes
Ascenseurs :
JScrollPane JEditorPane : texte avec styles
compatible HTML et RTF
Page 6 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Conteneurs
JPanel: conteneur générique
... JScrollPane:
avec ascenseurs intégrés
JSplitPane:
avec « diviseur » intégré
Page 7 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Conteneurs
JToolBar: barre d’outils
(sous la barre de menus)
JTabbedPane:
onglets
JTree
JTable
Page 8 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Fenêtres
JFrame : fenêtre principale de l’application
JDialog : fenêtre secondaire
– normalement dépendante de la JFrame :
• pas d’iconification séparée, toujours au dessus de la JFrame
– souvent temporaire et modale :
• bloque l’interaction, impose à l’utilisateur de répondre
Page 10 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Fenêtres
Créent des paneaux intermédiaires
• ContentPane : conteneur où on ajoute
les composants graphiques
• GlassPane : conteneur transparent superposé
(pour usages avancés)
Page 11 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Boîtes de dialogue prédéfinies
JFileChooser JColorChooser
Particularité
Peuvent être créés :
• comme composants internes
• ou comme boîtes de dialogue
JOptionPane (multiples variantes)
Page 12 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Menus
raccourci
clavier
(accelerator)
mnémonique
Page 13 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Arbre d’instanciation
Arbre d’instanciation
• arbre de filiation des instances de composants graphiques
Page 14 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Arbre d’instanciation
Chaque objet graphique « contient » ses enfants
• superposition : enfants affichés au dessus des parents
• clipping : enfants « découpés » : ne dépassent pas des parents
Page 15 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Arbre d’instanciation
Attention : ne pas confondre avec l’arbre d’héritage !
• arbre d’instanciation = arbre de filiation des instances
• arbre d’héritage = hiérarchie des classes
Page 16 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Arbre d’instanciation
Objet de plus haut niveau de l’arbre :
• JFrame
Les conteneurs peuvent être emboîtés
• en particulier les JPanels
Les layout managers assurent la disposition spatiale
• un layout manager par conteneur
• défaut pour JPanel : FlowLayout, pour JWindow : BorderLayout, etc.
Ne pas oublier d’appeler :
• [Link]( ) // calcul récursif des positions et des tailles
• [Link](true) // fait apparaître la fenêtre
Page 17 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Exemple : version 0
import [Link].*;
public class BipBip extends JFrame { // fenêtre principale
JButton button = null;
public static void main(String argv[ ]) {
BipBip toplevel = new BipBip(); // en gris : optionnel
}
public BipBip() {
button = new JButton ("Please Click Me !");
getContentPane().add(button); // en gris : avant version 5
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Bib Bip");
pack(); // calcule la disposition spatiale
setVisible(true); // rend l’interface visible
}
}
Page 18 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Exemple : version 0
Notes et rappels
• package [Link]
• une seule classe public par fichier, le fichier doit avoir le même nom
• button est une variable d’instance (on peut l’initialiser contrairement à C++)
• toplevel est une variable locale
• main() est une méthode de classe (cf. static)
• les méthodes d’instance ont automatiquement accès aux variables d’instance
elles ont un paramètre caché this qui pointe sur l’instance
• getContentPane() nécesaire avant la version 5 à cause du JRootPane
[Link]() a été redéfini dans les versions ultérieure de Java
Page 19 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Evénements
Evénements
• envoyés à l’application ciblée
• à chaque action élémentaire de l’utilisateur
Page 20 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Boucle de gestion des événements
Boucle infinie qui
• récupère les événements
• notifie les composants graphiques
Lancée automatiquement
• à la fin de la méthode main() dans le cas de Java
Page 21 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Evénements Java
Evénements AWT et Swing
• objets correspondant à des catégories d’évenements
• les principaux héritent de [Link]
Evénements de “bas niveau”
• MouseEvent appuyer, relacher, bouger la souris ...
• KeyEvent appuyer, relacher une touche clavier...
• WindowEvent fermeture des fenêtres ....
• FocusEvent focus clavier (= où vont les caractères tapés au clavier)
etc.
Evénements de “haut niveau”
• ActionEvent activer un bouton, un champ textuel ...
abstraction des événements de bas niveau
• TextEvent modification du texte entré
etc.
Page 22 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Evénements Java
Méthodes communes aux AWTEvent
• getSource() objet producteur (Object)
• getID() type d’événement (int)
Exemple: méthodes de MouseEvent
• getX(), getY()
• getClickCount()
• getModifiers()
• getWhen()
• etc.
Page 23 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Détecter les événements
Principe : patron Observateur / Observé
• Associer un ou des observateurs aux objets observés
• Les observateurs sont notifié(s) automatiquement
• quand une certaine condition se produit sur un observé
source: Wikipedia
Page 24 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Event listeners
A chaque classe d’événement correspond une classe d’Event Listener
(sauf cas particuliers)
Exemple : ActionEvent
• Evénement : ActionEvent
• Listener : ActionListener
• Méthode : actionPerformed(ActionEvent)
Page 25 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Event listeners
Exemple : MouseEvent
• Evénement : MouseEvent
• Listener : MouseListener
• Méthodes : • Listener : MouseMotionListener
• mouseClicked(MouseEvent) • Méthodes :
• mouseEntered(MouseEvent) • mouseDragged(MouseEvent)
• mouseExited(MouseEvent) • mouseMoved(MouseEvent)
• mousePressed(MouseEvent)
• mouseReleased(MouseEvent)
Remarque
• toutes les méthodes doivent être implémentées
• car les Listeners sont des interfaces (au sens du langage Java)
Page 26 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Rendre les composants réactifs
Associer des Listeners aux composants graphiques
• un composant peut avoir plusieurs listeners
• un même listener peut être associé à plusieurs composants
Page 27 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Exemple : version 1
import [Link].*;
import [Link].*;
public class BipBip extends JFrame {
JButton button;
public static void main(String argv[ ]) {
new BipBip(); class Ecoute implements ActionListener {
} // méthode appelée quand on active le bouton
public BipBip() { public void actionPerformed(ActionEvent e) {
button = new JButton ("Do It!"); [Link]("Done!");
}
add(button);
}
// créer et associer un ActionListener
Ecoute elc = new Ecoute();
[Link](elc);
setDefaultCloseOperation(EXIT_ON_CLOSE); Inconvénients ?
pack();
setVisible(true);
}
}
Page 28 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
import [Link].*;
import [Link].*;
public class BipBip extends JFrame {
JButton button;
JLabel label = new JLabel();
public static void main(String argv[ ]) { class Ecoute implements ActionListener {
new BipBip(); public void actionPerformed(ActionEvent e) {
}
[Link]("Done!");
public BipBip() { [Link]("Done!"); // ne compile pas !
button = new JButton ("Do It!"); }
add(button); }
Ecoute elc = new Ecoute();
[Link](elc);
Communication entre objets
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack(); comment le Listener peut-il agir
setVisible(true); sur les composants graphiques ?
}
}
Page 29 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
class Ecoute implements ActionListener {
import [Link].*;
import [Link].*; BipBip bipbip;
public class BipBip extends JFrame { public Ecoute (BipBip mainWin) {
JButton button; [Link] = mainWin;
JLabel label = new JLabel(); }
public static void main(String argv[ ]) {
new BipBip(); public void actionPerformed(ActionEvent e) {
} [Link]("Done!");
[Link]("Done!");
public BipBip() { }
button = new JButton ("Do It!"); }
add(button);
Ecoute elc = new Ecoute();
[Link](elc); Solution
setDefaultCloseOperation(EXIT_ON_CLOSE); • le Listener a une référence
pack(); vers la partie graphique
setVisible(true);
} • solution flexible mais lourde
}
Page 30 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Objets hybrides
A la fois composant graphique et Listener
• un seul objet => plus de problème de communication entre objets !
• principe de l’héritage multiple
• restreint avec Java : on peut « hériter » de plusieurs interfaces
• (mais pas de plusieurs classes)
Page 31 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Exemple : version 2
import [Link].*;
import [Link].*;
public class BipBip extends JFrame implements ActionListener {
JButton button;
JLabel label = new JLabel();
public static void main(String argv[ ]) {
new BipBip();
}
public BipBip() {
add(button = new JButton ("Do It"));
// BibBip est à la fois un JFrame et un Listener
[Link](this);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack(); actionPerformed() à accès à label
setVisible(true); car c’est une méthode d’instance
} de BibBip
public void actionPerformed(ActionEvent e) {
[Link]("Done!"); Inconvénients ?
}
}
Page 32 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
import [Link].*;
import [Link].*;
public class BipBip extends JFrame implements ActionListener {
JButton button;
JLabel label = new JLabel();
public static void main(String argv[ ]) {
new BipBip();
}
public BipBip() {
add(button = new JButton ("Do It"));
// BibBip est à la fois un JFrame et un Listener
[Link](this);
setDefaultCloseOperation(EXIT_ON_CLOSE); Plusieurs boutons ?
pack();
setVisible(true); comment avoir plusieurs comportements
} avec un seul Listener ?
public void actionPerformed(ActionEvent e) {
[Link]("Done!");
}
}
Page 33 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
import [Link].*; // suite de la classe BipBip
import [Link].*;
public void actionPerformed(ActionEvent e) {
public class BipBip extends JFrame if ([Link]() == doIt)
implements ActionListener { [Link]("Done!");
JButton doIt, close;
else if ([Link]() == close)
JLabel label = new JLabel();
[Link](0);
public static void main(String argv[ ]) { }
new BipBip(); } // fin de la classe !
}
public BipBip() {
add(doIt = new JButton("Do It"));
add(close = new JButton("Close")); On peut distinguer les boutons
[Link](this); via getSource()
[Link](this);
Autre solution getActionCommand()
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack(); (moins sûre car elle dépend des noms)
setVisible(true);
}
Page 34 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Avantages et inconvénients
Version 1 Version 2
• plus souple : • plus simple mais limitée :
autant de listeners que l'on veut on ne peut avoir qu'une seule
méthode actionPerformed()
• mais peu concise :
on multiplie les objets et les lignes de code • peu adaptée
si beaucoup de commandes
Page 35 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Classes imbriquées
Classes définies à l’intérieur d’une autre classe
• ont accès aux variables d’instance
des classes qui les contiennent
(forme de capture de variables)
• attention : pas en C++ !
Avantages des 2 solutions précédentes
• souplesse sans la lourdeur !
Page 36 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Exemple : version 3
import [Link].*; class DoItListener implements ActionListener {
import [Link].*; public void actionPerformed(ActionEvent e){
[Link]("Done!");
BipBip extends JFrame {
}
JButton doIt, close;
}
JLabel label = new JLabel();
public static void main(String argv[ ]) { class CloseListener implements ActionListener {
new BipBip(); public void actionPerformed(ActionEvent e){
} [Link](0);
}
public BipBip() {
}
add( doIt = new JButton("Do It") );
add( close = new JButton("Close") ); } // fin de la classe BibBip
[Link](new DoItListener( ));
[Link](new CloseListener( ));
actionPerformed() à accès à label
setDefaultCloseOperation(EXIT_ON_CLOSE); car DoItListener est une classe
pack();
setVisible(true); imbriquée de BibBip
}
Page 37 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Synthèse
Page 38 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Remarques
Remarques
• les classes imbriquées peuvent également servir à encapsuler
l’implémentation
• le terme exact est classes internes (inner classes en Anglais)
• il existe aussi des classes imbriquées statiques = nested classes
• pour structurer en sous-parties
Page 39 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Classes imbriquées anonymes
public class BipBip extends JFrame {
JLabel label = new JLabel(); // label doit être une variable d’instance (pas une variable locale)
...... // car elle est référencée dans une méthode d’instance
public BipBip() {
JButton doIt = new JButton("Do It");
add(doIt);
[Link](new ActionListener( ) { // sous-classe anonyme de ActionListener
public void actionPerformed(ActionEvent e) {
[Link]("Done!");
}
});
• ressemblent un peu
......
aux lambdas du C++11
}
• qui existent aussi depuis Java 8
Page 40 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Mélanger les plaisirs !
abstract class MyButton extends JButton implements ActionListener {
MyButton(String name) {
super(name);
addActionListener(this);
}
}
public class BipBip extends JFrame {
JLabel label = new JLabel();
......
public BipBip() {
add(new MyButton("Do It")) {
public void actionPerformed(ActionEvent e) {
[Link]("Done!");
}
});
......
Page 41 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Conflits
public class BipBip extends JFrame {
JButton close = new JButton("Close");
class CloseListener implements ActionListener {
boolean close = false
public void actionPerformed(ActionEvent e) {
setVisible(close); // OK
setVisible([Link]); // FAUX : pas le bon « close »
[Link](close); // ERREUR : pas le bon « this »
[Link](close); // OK
}
}
Même nom de variable dans classe imbriquante et classe imbriquée
Þ 1) à éviter !
Þ 2) préfixer par le nom de la classe
Page 42 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Compléments sur les constructeurs
abstract class MyButton extends JButton implements ActionListener {
public MyButton(String name, Icon icon) {
super(name, icon);
........
}
public MyButton (String name) { Un constructeur peut en appeler un autre !
this(name, null);
}
Note : en C++11:
• MyButton(string name) : MyButton(name, nullptr) {}
} • on pourrait aussi utiliser les paramètres par défaut
abstract class Toto { Constructeur de classe
static { • Pour initaliser des variables de classes
.......
• Pas d'équivalent direct en C++
}
Page 43 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Dessin
import [Link].*;
import [Link].*;
import [Link].*;
public class Scribble extends JApplet {
private int last_x, last_y;
public void init( ) {
setBackground([Link]);
// définir, instancier et enregistrer le Listener si on u4lisait MouseListener
addMouseListener( il faudrait implémenter :
new MouseAdapter ( ) {
public void mouseReleased (MouseEvent e) { }
public void mousePressed(MouseEvent e) { public void mouseClicked (MouseEvent e) { }
last_x = [Link]( ); public void mouseEntered (MouseEvent e) { }
last_y = [Link]( ); public void mouseExited(MouseEvent e) { }
}
} );
Page 44 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
addMouseMotionListener(
new MouseMotionAdapter ( ) {
public void mouseDragged(MouseEvent e) {
Graphics g = getGraphics( );
int x = [Link]( );
int y = [Link]( );
[Link](last_x, last_y, x, y);
last_x = x;
last_y = y;
}
} );
JButton b = new JButton("Clear"); // bouton qui efface tout
add(b);
[Link](
new ActionListener ( ) {
public void actionPerformed(ActionEvent e) {
Graphics g = getGraphics( );
[Link](getBackground( ));
[Link](0, 0, getSize( ).width, getSize( ).height);
}
} );
Page 45 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Persistance de l’affichage
Problèmes de l’exemple précédent
1) l’affichage du dessin n’est pas persistant
• effacé si on déplace une fenêtre dessus, si on iconifie...
• (en fait ça dépend des plateformes)
2) normalement les méthodes des listeners ne doivent pas dessiner
Page 46 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Modèle "damaged / repaint"
Principes à suivre
• Les listeners
• sauvegardent les opérations à faire dans une « display list »
• notifient le toolkit qu'il faut réafficher
• Le toolkit appelle la methode qui réaffiche le composant graphique
• qui doit afficher le composant, puis le dessin
Page 47 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Modèle "damaged / repaint"
repaint()
paintComponent()
class Dessin extends JPanel {
public void paintComponent(Graphics g) {
[Link](g); // ne pas oublier cette ligne !
// ...etc...
}
}
Page 48 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Notes
Swing vs. AWT
• avec AWT redéfinir la méthode paint()
• avec Swing, paint() appelle paintComponent() puis paintBorder() puis paintChildren()
Divers
• Appeler revalidate() dans certains cas de changements de taille
• Taille des bords : getInsets()
• Opacité des widgets
• certains composants sont opaques, d’autres sont transparents
• setOpaque() rend le composant opaque
Page 49 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
JFileChooser
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter
= new FileNameExtensionFilter ("JPG & GIF Images", "jpg", "gif"););
[Link](filter);
Ouvre la boîte de dialogue et bloque l’interaction (dialogue modal) :
int returnVal = [Link](parent);
if (returnVal == JFileChooser.APPROVE_OPTION) {
[Link]("You chose to open this file: "
+ [Link]().getName());
}
Page 50 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Disposition spatiale
Les LayoutManagers
• calculent automatiquement la disposition spatiale
des enfants des Containers
A chaque conteneur est associé un LayoutManager
• qui dépend du type de conteneur
• qui peut être changé par la méthode setLayout() :
[Link]( unAutreLayoutManager )
Pour faire le calcul "à la main" (à éviter sauf cas particuliers) :
[Link](null)
Page 51 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Avantages des LayoutManagers
C'est plus simple
• pas de calculs compliqués à programmer !
Configurabilité
• accessibilité : indépendance par rapport aux tailles des polices
• internationalisation : indépendance par rapport à la longueur du texte
• langues orientales : texte ~1/3 plus petit que l'anglais
• français, allemand : texte ~1/3 plus grand que l'anglais
Adaptativité des interfaces
• les composants graphiques se retaillent automatiquement
• quand l'utilisateur retaille les fenêtres
Page 52 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Principaux LayoutManagers
FlowLayout
• défaut des JPanel
• met les objets à la suite comme un "flux textuel" dans une page
• de gauche à droite puis à la ligne
Page 53 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Principaux LayoutManagers
BorderLayout
• défaut des JFrame et JDialog
• retaille automatiquement les enfants du conteneur
• disposition de type points cardinaux
• via constantes: [Link], EAST, NORTH, SOUTH, WEST
Page 54 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Principaux LayoutManagers (2)
GridLayout
• divise le conteneur en cellules de même taille (grille virtuelle)
• de gauche à droite et de haut en bas
• retaille automatiquement les enfants
Page 55 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Principaux LayoutManagers (2)
GridBagLayout
• grille + contraintes spatiales
• les enfants n'ont pas tous la même taille
• spécification par des GridBagConstraints
Page 56 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Principaux LayoutManagers (3)
CardLayout
• empile les enfants (et les met à la même taille)
• usage typique: pour les onglets
BoxLayout
• disposition verticale ou horizontale
• exemple :
[Link](new BoxLayout(panel, BoxLayout.Y_AXIS));
SpringLayout
• contraintes entre les bords des enfants
Page 57 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Architecture Swing
Swing est inspiré du modèle MVC
• Model : données de l'application
• View : représentation visuelle
• Controller : gestion des entrées
source: [Link]
Page 58 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Architecture Swing
Swing est inspiré du modèle MVC
• Model : données de l'application
• View : représentation visuelle
• Controller : gestion des entrées
But de MVC
• mieux structurer les applications
• représentations multi-vues
• un modèle peut être associé à plusieurs vues source: [Link]
• la synchronisation est implicite
En pratique
• V fortement lié à C
• plusieurs variantes de MVC !
Page 59 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Architecture Swing (2)
"Separable Model Architecture"
• View et Controller regroupés dans un UIComponent
• Model : reste séparé
"Pluggable Look and Feel"
• chaque JComponent Swing encapsule un UIComponent
• les UIComponent peuvent être changés dynamiquement par le UIManager
Page 60 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Architecture Swing (3)
Modèles et multi-vues
• (la plupart des) JComponent Swing créent implicitement un Modèle
• qui peut être "exporté" et partagé avec un autre JComponent
Exemple
• JSlider et JScrollbar : même modèle BoundedRangeModel
• mise commun du modèle => synchronisation automatique
Page 61 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Exemple
Dans l’API de JSlider et JScrollBar :
public BoundedRangeModel getModel();
public void setModel(BoundedRangeModel);
Changer le modèle du slider et du scrollbar :
JSlider slider = new JSlider();
BoundedRangeModel myModel = new DefaultBoundedRangeModel( ) {
public void setValue(int n) {
[Link](“SetValue: “+ n);
[Link](n);
}
});
[Link](myModel);
[Link](myModel);
On peut aussi ignorer l’existence des modèles :
JSlider slider = new JSlider();
int value = [Link]();
// cohérent car dans l’API de JSlider :
public int getValue() {return getModel().getValue(); }
Page 62 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Pluggable Look and Feel
Java Metal
public static void main(String[ ] args) {
try {
[Link](
[Link]());
} catch (Exception e) { }
//Create and show the GUI...
.....
}
Windows
[Link](
“[Link]”
);
Page 63 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Une variante de MVC
source: Sun
Page 64 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Graphics2D
Couche graphique évoluée
• plus sophistiquée que Graphics
Quelques caractéristiques
• système de coordonnées indépendant du type de sortie (écran, imprimante)
• et transformations affines : translations, rotations, homothéties
• package [Link]
• transparence
• AlphaComposite, BITMASK , OPAQUE, TRANSLUCENT ...
• Composition
• Paths et Shapes
• Fonts et Glyphs
• etc... (voir démo Java2D de Sun)
Page 65 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech
Pour en savoir plus
Site pédagogique de l’UE INF224
• [Link]
UEs liées à INF224
• IGR201: Développement d'applications interactives 2D, 3D, Mobile et Web
• IGR203: Interaction Homme-Machine
Page 66 Programmation événementielle et interfaces graphiques - Eric Lecolinet – Telecom ParisTech