IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

 

Développons en Java   2.30  
Copyright (C) 1999-2022 Jean-Michel DOUDOUX    (date de publication : 15/06/2022)

[ Précédent ] [ Sommaire ] [ Suivant ] [Télécharger ]      [Accueil ]

 

43. L'interception des actions de l'utilisateur

 

chapitre    4 3

 

Niveau : niveau 3 Intermédiaire 

 

N'importe quelle interface graphique doit interagir avec l'utilisateur et donc réagir à certains événements. Le modèle de gestion de ces événements à changer entre le JDK 1.0 et 1.1.

Ce chapitre traite de la capture de ces événements pour leur associer des traitements. Il contient plusieurs sections :

 

43.1. L'interception des actions de l'utilisateur avec Java version 1.0

 

 

 

en construction
Cette section sera développée dans une version future de ce document

 

43.2. L'interception des actions de l'utilisateur avec Java version 1.1

Les événements utilisateurs sont gérés par plusieurs interfaces EventListener.

Les interfaces EventListener permettent de définir les traitements en réponse à des événements utilisateurs généré par un composant. Une classe doit contenir une interface auditrice pour chaque type d'événements à traiter :

  • ActionListener : clic de souris ou enfoncement de la touche Enter
  • ItemListener : utilisation d'une liste ou d'une case à cocher
  • MouseMotionListener : événement de souris
  • WindowListener : événement de fenêtre

L'ajout d'une interface EventListener impose plusieurs ajouts dans le code :

  1. importer le groupe de classes java.awt.event

    Exemple ( code Java 1.1 ) :
    import java.awt.event.*;
  2. la classe doit déclarer qu'elle utilisera une ou plusieurs interfaces d'écoute

    Exemple ( code Java 1.1 ) :
    public class AppletAction extends Applet implements ActionListener{

    Pour déclarer plusieurs interfaces, il suffit de les séparer par des virgules

    Exemple ( code Java 1.1 ) :
    public class MonApplet extends Applet implements ActionListener, MouseListener {
  3. Appel à la méthode addXXX() pour enregistrer l'objet qui gérera les événements XXX du composant

    Il faut configurer le composant pour qu'il possède un «écouteur» pour l'événement utilisateur concerné.

    Exemple ( code Java 1.1 ) : création d'un bouton capable de réagir à un événements
    Button b = new Button("boutton");
    b.addActionListener(this);

    Ce code crée l'objet de la classe Button et appelle sa méthode addActionListener(). Cette méthode permet de préciser la classe qui va gérer l'événement utilisateur de type ActionListener du bouton. Cette classe doit impérativement implémenter l'interface de type EventListener correspondante soit dans cet exemple ActionListener. L'instruction this indique que la classe elle même recevra et gérera l'événement utilisateur.

    L'apparition d'un événement utilisateur généré par un composant doté d'un auditeur appelle automatiquement une méthode. Cette dernière doit se trouver dans la classe référencée dans l'instruction qui lie l'auditeur au composant. Dans l'exemple, cette méthode doit être située dans la même classe parce que c'est l'objet lui-même qui est spécifié avec l'instruction this. Une autre classe indépendante peut être utilisée : dans ce cas il faut préciser une instance de cette classe en tant que paramètre.

  4. implémenter les méthodes déclarées dans les interfaces

    Chaque auditeur possède des méthodes différentes qui sont appelées pour traiter leurs événements. Par exemple, l'interface ActionListener envoie des événements à une méthode nommée actionPerformed( ).

    Exemple ( code Java 1.1 ) :
    public void actionPerformed(ActionEvent evt) {
       //insérer ici le code de la méthode 
    
    };

    Pour identifier le composant qui a généré l'événement, il faut utiliser la méthode getActionCommand() de l'objet ActionEvent fourni en paramètre de la méthode :

    Exemple ( code Java 1.1 ) :
    String composant = evt.getActionCommand();

    La méthode getActionCommand() renvoie une chaîne de caractères. Si le composant est un bouton, alors il renvoie le texte du bouton, si le composant est une zone de saisie, c'est le texte saisi qui sera renvoyé (il faut appuyer sur «Entrer» pour générer l'événement), etc ...

    La méthode getSource() renvoie l'objet qui a généré l'événement. Cette méthode est plus sûre que la précédente

    Exemple ( code Java 1.1 ) :
    Button b = new Button(" bouton ");
    
    ...
    
    void public actionPerformed(actionEvent evt) {
       Object source = evt.getSource();
    
       if (source == b) // action a effectuer
    
    }

    La méthode getSource() peut être utilisée avec tous les événements utilisateur.

    Exemple ( code Java 1.1 ) : Exemple complet qui affiche le composant qui a généré l'événement
    package applets;
    
    import java.applet.*;
    import java.awt.*;
    import java.awt.event.*;
    
    public class AppletAction extends Applet implements ActionListener{
    
       public void actionPerformed(ActionEvent evt) {
          String composant = evt.getActionCommand();
          showStatus("Action sur le composant : " + composant);
       }
    
    
       public void init() {
          super.init();
    
          Button b1 = new Button("boutton 1");
          b1.addActionListener(this);
          add(b1);
    
          Button b2 = new Button("boutton 2");
          b2.addActionListener(this);
          add(b2);
    
          Button b3 = new Button("boutton 3");
          b3.addActionListener(this);
          add(b3);
       }
    }

 

43.2.1. L'interface ItemListener

Cette interface permet de réagir à la sélection de cases à cocher et de listes d'options. Pour qu'un composant génère des événements, il faut utiliser la méthode addItemListener().

Exemple ( code Java 1.1 ) :
Checkbox cb = new Checkbox(" choix ",true);
cb.addItemListener(this);

Ces événements sont reçus par la méthode itemStateChanged() qui attend un objet de type ItemEvent en argument

Pour déterminer si une case à cocher est sélectionnée ou inactive, utiliser la méthode getStateChange() avec les constantes ItemEvent.SELECTED ou ItemEvent.DESELECTED.

Exemple ( code Java 1.1 ) :
package applets;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class AppletItem extends Applet implements ItemListener{

   public void init() { 
      super.init();
      Checkbox cb = new Checkbox("choix 1", true);
      cb.addItemListener(this);
      add(cb);
   }

   public void itemStateChanged(ItemEvent item) {
      int status = item.getStateChange();
      if (status == ItemEvent.SELECTED)
         showStatus("choix selectionne");
      else
         showStatus("choix non selectionne");
   }

}

Pour connaitre l'objet qui a généré l'événement, il faut utiliser la méthode getItem().

Pour déterminer la valeur sélectionnée dans une combo box, il faut utiliser la méthode getItem() et convertir la valeur en chaîne de caractères.

Exemple ( code Java 1.1 ) :
Package applets;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class AppletItem extends Applet implements ItemListener{

   public void init() { 
      Choice c = new Choice();
      c.add("choix 1");
      c.add("choix 2");
      c.add("choix 3");
      c.addItemListener(this);
      add(c);
}

   public void itemStateChanged(ItemEvent item) {
      Object obj = item.getItem();
      String selection = (String)obj;
      showStatus("choix : "+selection);
   }
}

 

43.2.2. L'interface TextListener

Cette interface permet de réagir aux modifications de la zone de saisie ou du texte.

La méthode addTextListener() permet à un composant de texte de générer des événements utilisateur. La méthode TextValueChanged() reçoit les événements.

Exemple ( code Java 1.1 ) :
package applets;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class AppletText extends Applet implements TextListener{

   public void init() { 
      super.init();

      TextField t = new TextField("");
      t.addTextListener(this);
      add(t);	
   }

   public void textValueChanged(TextEvent txt) {
      Object source = txt.getSource();
      showStatus("saisi = "+((TextField)source).getText());
   }
}

 

43.2.3. L'interface MouseMotionListener

La méthode addMouseMotionListener() permet de gérer les événements liés à des mouvements de souris. Les méthodes mouseDragged() et mouseMoved() reçoivent les événements.

Exemple ( code Java 1.1 ) :
package applets;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class AppletMotion extends Applet implements MouseMotionListener{
   private int x;
   private int y;

   public void init() { 
      super.init();
      this.addMouseMotionListener(this);
   }

   public void mouseDragged(java.awt.event.MouseEvent e) {}

   public void mouseMoved(MouseEvent e) {
      x = e.getX();
      y = e.getY();
      repaint();
      showStatus("x = "+x+" ; y = "+y);
   }

   public void paint(Graphics g) {
      super.paint(g);
      g.drawString("x = "+x+" ; y = "+y,20,20);
   }
}

 

43.2.4. L'interface MouseListener

Cette interface permet de réagir aux clics de souris. Les méthodes de cette interface sont :

  • public void mouseClicked(MouseEvent e);
  • public void mousePressed(MouseEvent e);
  • public void mouseReleased(MouseEvent e);
  • public void mouseEntered(MouseEvent e);
  • public void mouseExited(MouseEvent e);
Exemple ( code Java 1.1 ) :
package applets;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class AppletMouse extends Applet implements MouseListener {
   int nbClick = 0;

   public void init() {
      super.init();
      addMouseListener(this);
   }

   public void mouseClicked(MouseEvent e) {
      nbClick++;
      repaint();
   }

   public void mouseEntered(MouseEvent e) {}

   public void mouseExited(MouseEvent e) {}

   public void mousePressed(MouseEvent e) {}

   public void mouseReleased(MouseEvent e) {}
   
   public void paint(Graphics g) {
      super.paint(g);
      g.drawString("Nombre de clics : "+nbClick,10,10);
   }
}

Une classe qui implémente cette interface doit définir ces 5 méthodes. Si toutes les méthodes ne doivent pas être utilisées, il est possible de définir une classe qui hérite de MouseAdapter. Cette classe fournit une implémentation par défaut de l'interface MouseListener.

Exemple ( code Java 1.1 ) :
class gestionClics extends MouseAdapter {

   public void mousePressed(MouseEvent e) {
      //traitement

   }
}

Dans le cas d'une classe qui hérite d'une classe Adapter, il suffit de redéfinir la ou les méthodes qui contiendront du code pour traiter les événements concernés. Par défaut, les différentes méthodes définies dans l'Adapter ne font rien.

Cette nouvelle classe ainsi définie doit être passée en paramètre à la méthode addMouseListener() au lieu de this qui indiquait que la classe répondait elle même à l'événement.

 

43.2.5. L'interface WindowListener

La méthode addWindwowListener() permet à un objet Frame de générer des événements. Les méthodes de cette interface sont :

  • public void windowOpened(WindowEvent e)
  • public void windowClosing(WindowEvent e)
  • public void windowClosed(WindowEvent e)
  • public void windowIconified(WindowEvent e)
  • public void windowDeinconified(WindowEvent e)
  • public void windowActivated(WindowEvent e)
  • public void windowDeactivated(WindowEvent e)

windowClosing() est appelée lorsque l'on clique sur la case système de fermeture de la fenêtre. windowClosed() est appelé après la fermeture de la fenêtre : cette méthode n'est utile que si la fermeture de la fenêtre n'entraine pas la fin de l'application.

Exemple ( code Java 1.1 ) :
package test;

import java.awt.event.*;

class GestionnaireFenetre extends WindowAdpter {

   public void windowClosing(WindowEvent e) {
      System.exit(0);
   }
}
Exemple ( code Java 1.1 ) :
package test;

import java.awt.*;
import java.awt.event.*;

public class TestFrame extends Frame {

   private GestionnaireFenetre gf = new GestionnaireFenetre();


   public TestFrame(String title) {
     super(title);
     addWindowListener(gf);
   }
      
   public static void main(java.lang.String[] args) {
      try {
         TestFrame tf = new TestFrame("TestFrame");       
         tf.setVisible(true);
      } catch (Throwable e) {
         System.err.println("Erreur");
         e.printStackTrace(System.out);
      }
   }
}

 

43.2.6. Les différentes implémentations des Listeners

La mise en oeuvre des Listeners peut se faire selon différentes formes : la classe implémentant elle même l'interface, une classe indépendante, une classe interne, une classe interne anonyme.

 

43.2.6.1. Une classe implémentant elle même le listener

Exemple ( code Java 1.1 ) :
package test;

import java.awt.*;
import java.awt.event.*;

public class TestFrame3 extends Frame implements WindowListener {

   public TestFrame3(String title) {
      super(title);
      this.addWindowListener(this);
   }

   public static void main(java.lang.String[] args) {
      try {
         TestFrame3 tf = new TestFrame3("testFrame3");	
         tf.setVisible(true);
      } catch (Throwable e) {
         System.err.println("Erreur");
         e.printStackTrace(System.out);
      }
   }

   public void windowActivated(java.awt.event.WindowEvent e) {}

   public void windowClosed(java.awt.event.WindowEvent e) {}

   public void windowClosing(java.awt.event.WindowEvent e) {
      System.exit(0);
   }

   public void windowDeactivated(java.awt.event.WindowEvent e) {}

   public void windowDeiconified(java.awt.event.WindowEvent e) {}

   public void windowIconified(java.awt.event.WindowEvent e) {}

   public void windowOpened(java.awt.event.WindowEvent e) {}

}

 

43.2.6.2. Une classe indépendante implémentant le listener

Exemple ( code Java 1.1 ) :
package test;

import java.awt.*;
import java.awt.event.*;

public class TestFrame4 extends Frame {

   public TestFrame4(String title) {
      super(title);
      gestEvt ge = new gestEvt();
      addWindowListener(ge);
   }

   public static void main(java.lang.String[] args) {
      try {
         TestFrame4 tf = new TestFrame4("testFrame4");
         tf.setVisible(true);
      } catch (Throwable e) {
         System.err.println("Erreur");
         e.printStackTrace(System.out);
      }
   }
}
Exemple ( code Java 1.1 ) :
package test;

import java.awt.event.*;

public class gestEvt implements WindowListener {
	
   public void windowActivated(WindowEvent e) {}
   public void windowClosed(WindowEvent e) {}
   public void windowClosing(WindowEvent e) {
      System.exit(0);
   }
   public void windowDeactivated(WindowEvent e) {}
   public void windowDeiconified(WindowEvent e) {}
   public void windowIconified(WindowEvent e) {}
   public void windowOpened(WindowEvent e) {}
}

 

43.2.6.3. Une classe interne

Exemple ( code Java 1.1 ) :
package test;

import java.awt.*;
import java.awt.event.*;

public class TestFrame2 extends Frame {

   class gestEvt implements WindowListener {
      public void windowActivated(WindowEvent e) {};
      public void windowClosed(WindowEvent e) {};
      public void windowClosing(WindowEvent e) {
         System.exit(0);
      };
      public void windowDeactivated(WindowEvent e) {};
      public void windowDeiconified(WindowEvent e) {};
      public void windowIconified(WindowEvent e) {};
      public void windowOpened(WindowEvent e) {};
   };

   private gestEvt ge = new TestFrame2.gestEvt();


   public TestFrame2(String title) {
     super(title);
     addWindowListener(ge);
   }
      
   public static void main(java.lang.String[] args) {
      try {
         TestFrame2 tf = new TestFrame2("TestFrame2");       
         tf.setVisible(true);
      } catch (Throwable e) {
         System.err.println("Erreur");
         e.printStackTrace(System.out);
      }
   }
}

 

43.2.6.4. Une classe interne anonyme

Exemple ( code Java 1.1 ) :
package test;

import java.awt.*;
import java.awt.event.*;

public class TestFrame1 extends Frame {

   public TestFrame1(String title) {
      super(title);
      addWindowListener(new WindowAdapter() {
         public void windowClosed(.WindowEvent e) {
            System.exit(0);
         };
      });		
   }
   
   public static void main(java.lang.String[] args) {
      try {
         TestFrame1 tf = new TestFrame1("TestFrame");		
         tf.setVisible(true);
      } catch (Throwable e) {
         System.err.println("Erreur");
         e.printStackTrace(System.out);
      }
   }
}

 

43.2.7. Résumé

Le mécanisme mis en place pour intercepter des événements est le même quel que soit ces événements :

  • associer au composant qui est à l'origine de l'événement un contrôleur adéquat : utilisation des méthodes addXXXListener(). Le paramètre de ces méthodes indique l'objet qui a la charge de répondre au message : cet objet doit implémenter l'interface XXXListener correspondante ou dérivée d'une classe XXXAdapter, ce qui revient à créer une classe qui implémente l'interface associée à l'événement que l'on veut gérer. Cette classe peut être celle du composant qui est à l'origine de l'événement (facilité d'implémentation) ou une classe indépendante qui détermine la frontière entre l'interface graphique (émission d'événements) et celle qui représente la logique de l'application (traitement des événements) .
  • les classes XXXAdapter sont utiles pour créer des classes dédiées au traitement des événements car elles implémentent des méthodes par défaut pour celles définies dans l'interface XXXListener dérivées de EventListener. Il n'existe une classe Adapter que pour les interfaces qui possèdent plusieurs méthodes.
  • implémenter la méthode associée à l'événement qui fournit en paramètre un objet de type AWTEvent (classe mère de tout événement) contenant des informations utiles (position du curseur, état du clavier ...).

 

 


[ Précédent ] [ Sommaire ] [ Suivant ] [Télécharger ]      [Accueil ]

78 commentaires Donner une note à l´article (5)

 

Copyright (C) 1999-2022 Jean-Michel DOUDOUX. Vous pouvez copier, redistribuer et/ou modifier ce document selon les termes de la Licence de Documentation Libre GNU, Version 1.1 ou toute autre version ultérieure publiée par la Free Software Foundation; les Sections Invariantes étant constitués du chapitre Préambule, aucun Texte de Première de Couverture, et aucun Texte de Quatrième de Couverture. Une copie de la licence est incluse dans la section GNU FreeDocumentation Licence. La version la plus récente de cette licence est disponible à l'adresse : GNU Free Documentation Licence.