Interface et classes internes Introduction à la gestion d’événements Classe Interface (p. 494) Interface: définit un ensemble de services Définition: classe purement abstraite • aucun attribut sauf public static final • aucune implantation de méthodes donc que des méthodes abstraites // Figure 9.27 : Forme.java - Définition de l'interface Forme. P. 495 public interface Forme { public abstract double aire(); // Calculer l'aire. public abstract double volume(); // Calculer le volume public abstract String getNom(); // Obtenir le nom de la forme } Utilisation d’une classe Interface z z z z z z (p. 494) Spécification de l’« implémentation » Définition de toutes les méthodes déclarées dans l’interface (mêmes arguments, mêmes types de retour) L’implémentation est une relation « est un » comme dans l’héritage Une classe peut implémenter plusieurs interfaces (forme d’héritage multiple) Les interfaces interviennent grandement dans la gestion des événements d’une interface graphique Autre utilisation : définition de constantes utilisables dans de nombreuses classes (ex. p.501) public interface Constantes{ } public static final int UN = 1; public static final int DEUX = 2; public static final int TROIS = 3; Exemple (p.495) // Figure 9.28: Point.java - // Définition de la classe Point. public class Point extends Object implements Forme { protected int x, y; // coordonnées du Point public Point() { // Constructeur sans argument. setPoint( 0, 0 ); } public Point( int coordonneeX, int coordonneeY ) { // Constructeur. setPoint( coordonneeX, coordonneeY ); } // Ajuster les coordonnées en x et y du Point. public void setPoint( int coordonneeX, int coordonneeY ){ x = coordonneeX; y = coordonneeY; } Exemple - suite (p.495) public int getX() { // Obtenir la coordonnée en x. return x; } public int getY() { // Obtenir la coordonnée en y. return y; } public String toString() {// Convertir le point en une chaîne return "[" + x + ", " + y + "]"; } public double aire() { // Calculer l'aire. return 0.0; } public double volume() { // Calculer le volume return 0.0; } public String getNom() { // Obtenir le nom de la forme return "Point"; } } // fin classe Point Object + Object( ) + clone( ) : Object + equals(Object ) : boolean + finalize( ) + getClass( ) : Class … Super-classe hérite de Représentation graphique de l’utilisation d’interface avec des classes en UML <<interface>> Forme Interface avec uniquement des : -attributs: public static final -méthodes: public abstract + calculerAire( ) : double + calculerVolume( ) : double + getNom( ) : String Sous-classe Point x : int y : int + Point( ) + setPoint(unX: int, unY: int ) + getX( ) : int + getY( ) : int + calculerAire( ) : double + calculerVolume( ) : double + getNom( ) : String implémente LÉGENDE héritage implémente Classes internes (inner classes) (p. 501) z Classe imbriquée dans une autre classe Définition complète (nom, attributs, méthodes) Aussi classe interne anonyme (sans nom) Principale utilité: dans la gestion d’événements z Exemple: p.501 – 506, figures 9.32 et 9.33 z z z Interface utilisateur graphique Chapitre 12 (GUI) Packages: AWT et SWING z AWT: (Abstract Windowing Toolkit) les composants originaux, plus lourds, ils sont liés à la plate-forme locale z SWING: plus récents, composants allégés, totalement écrits en Java, ne sont pas liés à la plate-forme utilisée. (quelques composants restent lourds tels Jframe qui affiche des fenêtres et JApplet.) Héritage de la classe principale de SWING: JComponent (p. 650) java.lang.Object java.awt.Component java.awt.Container javax.swing.JComponent Composants de base (p.648) z z z z z z z z z Fenêtres Cadres Panneaux JWindow JFrame JPanel Étiquettes Zones de texte Boutons Cases à cocher Boutons d’option Zones de liste JLabel JTextField JButton JCheckBox JRadioButton JComboBox p. 651 p. 656 p. 662 p. 665 p. 665 p. 671 Les conteneurs z Pour utiliser des composants (étiquettes, boutons…) il faut prévoir un « conteneur » dans lequel ces composants ou contrôles seront placés. Un conteneur pour des composants public class Boutons extends JFrame { private JButton arret = new JButton("Interruption"); private JButton nouveau = new JButton("Nouvel essai"); private JButton fin = new JButton("Fin"); public Boutons() { //constructeur super("Boutons"); // Lire le panneau de contenu et définir ses paramètres. Container conteneur = getContentPane(); //Récupère le contenant de la fenêtre c'est à dire, la zone active sans la barre de menu, la barre d'état et la barre de titre conteneur.setLayout(new FlowLayout(); ); //FlowLayout p.693 // placer les boutons dans le conteneur conteneur.add(arret); conteneur.add(nouveau); conteneur.add(fin); setSize(300, 150); // dimension de la fenêtre setVisible( true ); //affichage de la fenêtre } public static void main(String[] arguments) { Boutons rb = new Boutons(); // action au moment de la fermeture de la fenêtre rb.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } Gestionnaires de canevas (p. 692 à 701) Un gestionnaire de canevas permet d’intégrer des composants GUI dans un conteneur à des fins de présentation z FlowLayout (de gauche à droite dans l’ordre d’introduction) z BorderLayout (NORTH, SOUTH, EAST, WEST, CENTER) z GridLayout (selon une grille, débute à la cellule supérieure gauche et parcourt de gauche à droite) z Utilisation des panneaux – – – On peut définir des canevas pour des panneaux On peut intégrer des panneaux selon un canevas déjà défini Un panneau peut contenir un autre panneau Exercices z Exercices: p. 716 #12.8, #12.9 et #12.10 z À remettre : mercredi 19 avril Note: Utiliser les 3 gestionnaires de canevas Gestion des événements (p. 654) z z Un événement est le résultat d’une action de l’utilisateur sur un composant. (clic de la souris sur un bouton, entrée de texte dans une zone de texte….). Un événement provoque normalement une réaction (un clic sur un bouton met fin à un programme, suscite un calcul, un affichage etc..) Gestion des événements (suite) z Implique 3 éléments z z z z Pour le programmeur z z z La source de l’événement – l’envoi d’un message L’objet de l’événement – le message L’écouteur de l’événement – la réception du message et réponse au message Inscription d’un écouteur d’événements Mise en place d’un gestionnaire d’événements Un gestionnaire d’événements z Méthode appelée en réponse à un type d’événement donné Événement Écouteur Réponse Comment fonctionne la gestion des événements (p. 660) z Écouteurs: (classes « interface ») z z z z z ActionListener MouseListener KeyListener ItemListener Les écouteurs sont « implémentés » par une classe interne qui devient le gestionnaire d’événements. exemple : private class TextFieldHandler implements ActionListener z Les composants qui doivent être « écoutés » sont inscrits dans le gestionnaire d’événements. exemple : TextFieldHandler gestionnaire = new TextFieldHandler(); texte1.addActionListener ( gestionnaire ); L’interface ActionListener et la méthode actionPerformed Exemple p. 656 - JTextField // Packages de noyau Java. import java.awt.*; import java.awt.event.*; // Packages d'extension Java. import javax.swing.*; public class ZoneTexteTest extends JFrame { private JTextField texte1, texte2, texte3; private JPasswordField motDePasse; Définition de l’interface // Définir la GUI. public ZoneTexteTest() //Constructeur { super( "Test de JTextField et JPasswordField" ); Container conteneur = getContentPane(); conteneur.setLayout( new FlowLayout() ); // Construire les zones de texte avec une taille prédéfinie. texte1 = new JTextField( 10 ); conteneur.add( texte1 ); texte2 = new JTextField( "Entrez du texte ici" ); conteneur.add( texte2 ); // Construire une zone de texte non modifiable aucun événement à gérer texte3 = new JTextField( "Champ de texte non modifiable", 20 ); texte3.setEditable( false ); conteneur.add( texte3 ); // Construire la zone de texte avec une taille prédéfinie. motDePasse = new JPasswordField( "Texte caché" ); conteneur.add( motDePasse ); Inscription d’un écouteur d’événements // Enregistrer les gestionnaires d'événements. TextFieldHandler gestionnaire = new TextFieldHandler(); texte1.addActionListener( gestionnaire ); texte2.addActionListener( gestionnaire ); texte3.addActionListener( gestionnaire ); motDePasse.addActionListener( gestionnaire ); setSize( 325, 100 ); setVisible( true ); } // Exécuter l'application. public static void main( String args[] ) { ZoneTexteTest application = new ZoneTexteTest(); application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); } Classe qui gère les événements // Classe interne privée de gestion d'événements. private class TextFieldHandler implements ActionListener { // Traiter les événements texte. public void actionPerformed( ActionEvent evenement ) { String chaine = ""; if ( evenement.getSource() == texte1 ) // L'utilisateur presse Enter dans le JTextField texte1. chaine = "texte1 : " + evenement.getActionCommand(); //contenu else // L'utilisateur presse Entrée dans le JTextField texte2 if ( evenement.getSource() == texte2 ) chaine = "texte2 : " + evenement.getActionCommand(); else // L'utilisateur presse Entrée dans le JTextField texte3. if ( evenement.getSource() == texte3 ) chaine = "texte3 : " + evenement.getActionCommand(); else // L'utilisateur presse Entrée dans le JTextField motDePasse. if ( evenement.getSource() == motDePasse ) { JPasswordField mdp = ( JPasswordField ) evenement.getSource(); chaine = "Mot de passe : " + new String( motDePasse.getPassword() ); } JOptionPane.showMessageDialog( null, chaine ); } } // fin de la classe interne privée TextFieldHandler } // fin de la classe ZoneTexteTest Exercice z Simuler le jeu de Rochambeaux : le joueur et l'ordinateur choisissent « Roche", "Papier" ou "Ciseaux". "Papier" gagne sur « Roche", « Roche" gagne sur "Ciseaux" et "Ciseaux" gagne sur "Papier". Utiliser des boutons pour faire choisir le joueur et des étiquettes pour faire afficher les messages. Aucune boîte de dialogue ne doit être utilisée. À remettre : jeudi le 20 avril