230 likes | 375 Views
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
E N D
JAVA Interface Graphique SWING
Historique sur les interfaces graphiques Java • Javafournitlesdeuxpaquetagesprincipauxpourlesinterfacesgraphiques : • 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() JPanel JButton Mon Bouton 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
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
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, drawImage myImage = 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 • Objet Ecouteur3 • Contient la méthode à executer • public void actionPerformed(ActionEvent event) • Evenement : clic sur le moins • 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 Ecouteur1 • Contient la méthode à executer • public void actionPerformed(ActionEvent event) • Mettre a jour le compteur • Objet Ecouteur2 • Contient la méthode à executer • public 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 bouton public 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