JAVA Interface Graphique SWING
Jan 03, 2016
JAVA
Interface Graphique SWING
Historique sur les interfaces graphiques Java
Java fournit les deux paquetages principaux pour les interfaces graphiques :
java.awt (Abstract Window Toolkit) :
Utilise les composants graphiques natifs de la plate-forme Peut avoir un comportement différent suivant la plate-forme Limité aux caractéristiques communes à toutes les plates-formes
cibles Exécution assez rapide.
javax.swing, initialement JFC (Java Foundation Classes) :
Bibliothèque écrite en 100% pure Java ; Bibliothèque très riche proposant des composants évolués (arbres,
tables,...) Construite au dessus de la partie portable de AWT ; Look & Feel modifiable (application du patron MVC) ; Exécution assez lente.
SWING
Méthode de construction : Une plaque de base: Jframe, Jwindow, Jdialog, Objets JApplet On ajoute des briques prédéfinies par dessus :composants ou contrôle
boutons, textfield,etc.
Le sous système graphique est objet chaque composant s'affiche chaque composant provoque l'affichage des
composants qu'il contient La fenêtre top level JFrame s'affiche Le contentpane affiche un fond opaque Le JPanel s'affiche (par dessus le précédent) :
• le fond (paintComponent())• les bordures(paintBorder())
Il demande à son contenu de s'afficher(paintChildren())
• Le JButton "Mon bouton" s'affiche par paintComponent()
– le fond– le texte
• Le Jlabel "Du texte" s'affiche par paintComponent()
– le texte
Pour provoquer l'affichage, utiliser repaint() : affiche tout le composant repaint(int,int,int,int) : affiche le rectangle
JFrame
getContentPane()
JButton
Mon Bouton
JPanel
Jlabel
Du Texte
Construire une IG en pratique : patron MVC
Définir le Modèle de données de l’application
Définir l’ergonomie de l’IG : la Vue Construire une fenetre de base (JFrame, JDialog, JApplet…) Construire un composant intermédiaire : Jpanel, JScrollPane, JSplitPane,
… Ajouter des objets graphiques ou d’autres composants intermédiaires
dans le composant intermédiaire : methode add du composant intermédiaire
Ajouter le composant intermédiaire à la fenetre de base : methode add de la fenetre principale
Positionner et dimensionner les composants methode pack() de la fenetre principale
Visualiser la fenetre de base : methode setVisible(true) de la fenetre principale
Définir la réaction aux actions de l’utilisateur sur les éléments de l’ IG : le Contrôleur
Swing : composants de base
Swing : composants de haut niveau
Swing : les composants intermédiaires
Les Gestionnaires de Placement
Principe : Associé à un Container, un gestionnaire de placement (LayoutManager) est chargé de positionner ses composants suivant une politique prédéfinie
FlowLayout Les uns à la suite des autres
BorderLayout Au centre ou à un des quatre coins cardinaux
BoxLayout Sur une même ligne ou sur une même colonne
GridLayout Sur un tableau à 2 dimensions (les composants ont tous la même taille)
GridBagLayoutDans une grille mais les composants peuvent être de tailles différentes en occupant plusieurs lignes et/ou colonnes
CardLayout seulement un seul composant est affiché
Exemples de Gestionnaires de Placement
Créer un nouveau composant pour dessiner
• La classe Graphics est une classe abstraite – permettant de dessiner des formes simples et des chaines de caractères– D’etre indépendant du support réel :carte graphique, imprimante, image en
mémoire– contient des informations sur :
• Les couleurs d’affichage, de fond, le type d’opération de dessin (xor)• Le composant abstrait dans lequel on dessine
• Pour dessiner dans une fenetre: – On crée un nouveau composant d’affichage dérivant de JPanel et on
redéfinit les méthodes• PaintComponent(Graphics g) pour l’affichage• PaintBorder pour les bordures
public void paintComponent(Graphics g) { super.paintComponent(g); //Le fond g.drawRect(10, 20, 99, 199); g.setColor(Color.yellow); // Dessine un rectangle jaune g.fillRect(10+1, 20 + 1,98,198);}
Image
• AWT : getImage, drawImagemyImage = Toolkit.getDefaultToolkit().getImage(filenameOrURL);
g.drawImage(myImage, 0, 0, this);
• SWING : une image est simplement affichée dans un JPanel, un JButton– interface icons– Classe ImageIcon : implemente icons, lit du GIF ou JPEG, mais aussi des
BufferedImage (!= Image)– la fonction paintIcon(Component,Graphics,int,int) personnalise
l'affichage d'une image
Afficher une image dans un composant (1)
class AfficheImage extends JLabel { private ImageIcon icon=null; public AfficheImage(String im) { updateImage(im); } public void updateImage(String im) { icon=new ImageIcon(im); setIcon(icon);} // Creation et affichage de l’image}class AppliAffiche extends JFrame { private AfficheImage affiche =null; public AppliAffiche(String im) { getContentPane().add(affiche=new AfficheImage(im)); pack(); setVisible(true); } public void suite(String im) { affiche.updateImage(im); pack(); }}public class Ex40 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); if (arg==null) {System.out.println("Usage : java Ex40 im1 im2 ...."); } else { AppliAffiche p = new AppliAffiche(arg[0]); System.out.println("Photo suivante"); clavier.nextLine(); for (int i=1; i<arg.length; i++) { p.suite(arg[i]); System.out.println("Photo suivante"); clavier.nextLine(); } } }}
Afficher une image dans un composant (2)
class AfficheImage extends JPanel{ private BufferedImage img = null; public AfficheImage(BufferedImage i) { img=i;} public void updateImage(BufferedImage i) { img=i; repaint();} public void paintComponent(Graphics g) { g.drawImage(img, 0, 0, null); } public Dimension getPreferredSize() { return (img==null) ? new Dimension(100,100): new Dimension(img.getWidth(null), img.getHeight(null)); }}class AppliAffiche extends JFrame { private AfficheImage affiche =null; public AppliAffiche(BufferedImage im) { getContentPane().add(affiche=new AfficheImage(im)); pack(); setVisible(true); } public void suite(BufferedImage im) { affiche.updateImage(im); pack(); }}public class Ex40b { public static void main(String [] arg) {Scanner clavier = new Scanner(System.in); BufferedImage img = null; if (arg==null) {System.out.println("Usage : java Ex40 im1 im2 ...."); } else { try { img = ImageIO.read(new File(arg[0])); } catch (IOException e) {} AppliAffiche p = new AppliAffiche(img); System.out.println("Photo suivante"); clavier.nextLine(); for (int i=1; i<arg.length; i++) { try { img = ImageIO.read(new File(arg[i])); } catch (IOException e) {} p.suite(img); System.out.println("Photo suivante"); clavier.nextLine(); } System.exit(0); } }}
Swing : exemple
Exemple de réalisation ergonomie
JAVA
Gestion des évènements en SWING
Gestion des évenements
Evenement : clic sur le moins
Evenement : clic sur le moins
Objet Ecouteur1
Contient la méthode à executerpublic void actionPerformed(ActionEvent
event)Mettre a jour le compteur
EDT : file des évènements gérée par un thread
Envoi à tous les objets qui ont le droit d’écouter le bouton « moins » cette
information
EDT : file des évènements gérée par un thread
Envoi à tous les objets qui ont le droit d’écouter le bouton « moins » cette
information
Objet Ecouteur2
Contient la méthode à executerpublic void actionPerformed(ActionEvent
event)
Objet Ecouteur3
Contient la méthode à executerpublic void
actionPerformed(ActionEvent event)
Ecouter un bouton
Il faut créer l’interface graphique (IG) : une fenetre de base Trois boutons : moins, plus, reset Une zone de texte : resultat
Deux possibilités pour définir un écouteur : La classe principale (la Vue) réalise ActionListener Définition d’une classe spécifique pour chaque écouteur qui réalise ActionListener
La classe qui réalise l’interface ActionListener permet de gérer les clics sur un bouton, les sélections de menu On définit dans cette classe la méthode actionPerformed(…) qui explicite ce qui doit
être fait quand on clique sur un boutonpublic void actionPerformed(ActionEvent event) { TODO }
Le bouton moins autorise l’objetEcoutant à traiter les evenements en provenance de lui même (le moins), i.e. on enregistre objetEcoutant aupres du bouton par la méthode addActionListener, moins.addActionListener(objetEcoutant);
Ecouter un bouton
Exemple de l’IG compteur :
Patron Modèle-Vue-Contrôleur (MVC)• Modèle de l’application = la classe compteur (les données)• Vue = « Ergonomie » de l’IG• Contrôleur = Réaction aux actions de l’utilisateur sur les
éléments de l’IG Graphique
Fermer la fenetre
Il faut créer une classe (ici MonEcouteurFenetre) qui implémente l’interface windowListener qui permet de gérer les fenetres Il faut définir 7 méthodes, meme si elles sont vides
void windowOpened(WindowEvent e) : ouverture de la fenetre void windowClosed(WindowEvent e) : apres la fermeture de la fenetre void windowClosing(WindowEvent e) : au moment de la fermeture de la fenetre void windowIconified(WindowEvent e) : iconifier la fenetre void windowDeiconified(WindowEvent e) : deiconifier de la fenetre void windowActivated(WindowEvent e) : focus dans la fenetre; Utiliser de préférence
windowGainedFocus de WindowFocusListener void windowDeactivated(WindowEvent e) : perte du focus de la fenetre. Utiliser de
préférence windowLostFocus de WindowFocusListener
On crée et enregistre cet objet aupres de la fenetre par la méthode addWindowListener
Les adapteurs : Fermer la fenetre
Gérer les événements par adaptateur une interface listener toutes les méthodes doivent être écrites, même
vides exemple : windowsListener : 7 méthodes à redéfinir
windowActivated, windowClosed, windowClosing, WindowDeactivated, windowDeiconified, windowIconified, windowOpened
Un adaptateur : une classe contient déjà une version vide on ne surcharge que les fonctionnalités dont on a besoin
Attention : la classe écouteur HERITE de la classe Adapter au lieu de IMPLEMENTE une interface
ComponentAdapter ContainerAdapter FocusAdapter KeyAdapter MouseAdapter MouseMotionAdapter WindowAdapter
Quel écouteur définir pour quelle action ? Interface ActionListener
Utilisée par les clics bouton, choix de menu, et les CR dans un zone de texte (JTextField, JTextArea)
Méthodes à définir void actionPerformed(ActionEvent e) : que faire lors de l'apparition d’un des évènements
Interface MouseListener ou classe MouseAdapter Utilisée pour les actions souris entrant et sortant dans la fenetre, les clics dans la
fenetre Méthodes à définir
void mouseClicked(MouseEvent e) : clic dans la fenetre void mouseEntered(MouseEvent e) : souris entrant dans la fenetre void mouseExited(MouseEvent e) : souris sortant de la fenetre void mousePressed(MouseEvent e) : touche souris appuyée dans la fenetre void mouseRealised(MouseEvent e) : touche souris relachée dans la fenetre
Principales méthodes de la classe MouseEvent boolean isAltDown(), boolean isControlDown(), boolean isMetaDown(), boolean
isShiftDown() int getModifiers(), int getX(), int getY()
Méthodes utiles boolean isLeftMouseButton(MouseEvent e) : vrai si e concerne le bouton gauche de la
souris boolean isMiddleMouseButton(MouseEvent e) : vrai si e concerne le bouton milieu de la
souris boolean isRightMouseButton(MouseEvent e) : vrai si e concerne le bouton droit de la souris
Interface MouseMotionListener ou classe MouseMotionAdapter Utilisée pour les déplacement souris dans la fenetre Méthodes à définir
void mouseDragged(MouseEvent e) : clic dans la fenetre void mouseMovedMouseEvent e) : déplacement souris dans la fenetre
Quel écouteur définir pour quelle action (2) ?
Interface WindowListener ou classe WindowAdapter Utilisée pour les actions sur les fenetres : ouverture, fermeture, iconification,
quitter Méthodes à définir
void windowOpened(WindowEvent e) : ouverture de la fenetre void windowClosed(WindowEvent e) : apres la fermeture de la fenetre void windowClosing(WindowEvent e) : au moment de la fermeture de la fenetre void windowIconified(WindowEvent e) : iconifier la fenetre void windowDeiconified(WindowEvent e) : deiconifier de la fenetre void windowActivated(WindowEvent e) : focus dans la fenetre; Utiliser de préférence
windowGainedFocus de WindowFocusListener void windowDeactivated(WindowEvent e) : perte du focus de la fenetre. Utiliser de
préférence windowLostFocus de WindowFocusListener
La principale action à redéfinir est celle de la fermeture d’une application. Pour cela, il faudrait Soit vos applications graphiques implémentent l’interface WindowListener avec
ses 7 methodes redéfinir systématiquement la fonction windowClosed Ecrire un corps de fonction vide pour les autres
Soit vos applications graphiques héritent de WindowAdapter avec ses 7 methodes redéfinir systématiquement la fonction windowClosed Mais votre application ne peut plus hérité d’une autre classe
Solution : la méthode définit la sortie propre sans redéfinir le listener ou l’adapter
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Exercice
Programmer une Interface Graphique en Java / Swing pour le Zoo2D