← (précédent) D.5 Evènements sur les boutons radio
D.7 Evènements sur les boites de liste
Accueil S O M M A I R E

D.6 Evènements sur les champs de texte

D.6.1 Le label est un champ de texte particulier.

Un label, encore appelé une étiquette, permet d'afficher un texte, d'une seule ligne, non modifiable par l'utilisateur, mais modifiable par le programme.
Puisqu'aucune action de l'utilisateur n'a d'effet sur le label, il n'y a donc pas de réaction due à l'action de l'utilisateur. Autrement dit, pas d'évènements sur le label.

Mais voyons comment un programme peut modifier le texte du label.

 Exemple 1 : 

1.     import javax.swing.*;
2.     import javax.swing.event.*;
3.     import java.awt.*;
4.     import java.awt.event.*;
5.     
6.     class Fenetre extends JFrame implements ActionListener
7.     {
8.         private JLabel etiket; private JButton bouton;
9.          public Fenetre()
10.         {
10.              setTitle("Une fenetre dynamique");
11.              Container c = getContentPane();
12.              c.setBackground(new Color(254, 220, 186));
13.              setSize(500, 300);
14.              c.setLayout(new FlowLayout());
15.              etiket = new JLabel("texte initial");
16.              c.add(etiket);
17.              setLocationRelativeTo(this.getParent()); 
18.              bouton = new JButton("Modifier etiket");
19.              c.add(bouton);
20.              bouton.addActionListener(this);
21.              setDefaultCloseOperation(3);
22.          }
23.         
24.          public void actionPerformed(ActionEvent a) 
25.          {
26.               etiket.setText("texte final");
27.                
28.          }     
29.               
30.     }          
31.          
32.    
33.
34.    public class TesterLabel
35.    {
36.          public static void main(String [] args)
37.          {
38.               Fenetre f = new Fenetre();
39.               f.setVisible(true);
40.          }
41.    }

Compilez puis exécutez ce programme. Il sera affiché :

Une fenêtre graphique contenant un label dont le texte initial est "texte initial". Et un bouton appelé "Modifier etiket". Cliquez sur le bouton et le texte initial du label (texte initial) sera transformé en "texte final".

Explications :

La méthode setText() de la classe JLabel permet de modifier le texte du label.


Remarquez une nouvelle instruction dans la série des import. Ligne numéro 2 : import javax.swing.event.*;
C'est parce qu'il faudra traiter les méthodes de l'interface DocumentListener. Et ces dernières sont définies dans ce package. Bien-entendu, je n'en ai pas besoin ici. Mais sa présence ici a un but bien précis. Lorsque en programmation évènementielle, vous ne savez pas quel package importer, mettez les 4 premières instructions.

		import javax.swing.*;
		import javax.swing.event.*;
		import java.awt.*;
		import java.awt.event.*;
		
Et vous n'aurez aucun problème.
Reprenez le programme ci-dessus. Ajoutez la ligne de code suivante :
etiket.setForeground(new Color(255, 0, 0) );
dans la définition de la méthode actionPerformed(). Ce code sera ajouté soit après, soit avant le code en ligne 26. Compilez puis exécutez, c'est le même résultat que là haut. A une exception près. Le texte final est en rouge. Vous l'aurez compris. La méthode setForeground()de la classe JLabel permet de colorer le texte du label. Cette méthode requiert un argument de type Color. Et c'est la couleur du texte du label

Autre exercice. Reprenez à nouveau le programme ci-dessus et faîtes en sorte que le clic sur le bouton affiche sur le label, le nombre total de clics effectué par l'utilisateur.

D.6.2 Evènements sur le champ de texte

Vous avez déjà (probablement) rempli un formulaire sur une page du web. Vous avez des champs de texte par exemple : votre pseudo ou par exemple votre mot de passe. Puis des cases à cocher ou des boutons radio à sélectionner pour faire des choix. Vous savez que vous pouvez parcourir ces éléments graphiques grâce à votre souris. Mais vous savez aussi que vous pouvez les parcourir grâce à la touche tabulation de votre clavier.
Lorsque vous avez sélectionné un élément graphique avec votre souris ou votre clavier, vous voyez des pointillés sur cet élément. On dit alors que l'élément graphique a gagné le focus. Puis si vous quitez cet élément graphique, vous voyez bien que les pointillés qui l'entouraient disparaissent. on dit que l'élément graphique en question a perdu le focus.

Le gain de focus par un élément graphique est un évènement traité par la méthode FocusGained() et la perte est traitée par la méthode FocusLost().
Ces deux méthodes appartiennent à l' interface FocusListener. Dans cette interface, qui ne contient que ces 2 méthodes, ces dernières sont déclarées :

public void FocusGained( FocusEvent f)
public void FocusLost(FocusEvent f)

Il existe une classe adaptatrice appelée FocusAdapter qui vous permet de seulement redéfinir la méthode qui vous intéresse.

Allons-y pour les exemples.
 Exemple 2 : 

1.     import javax.swing.*;
2.     import javax.swing.event.*;
3.     import java.awt.*;
4.     import java.awt.event.*;
5.     
6.     class Fenetre extends JFrame implements FocusListener
7.     {
8.         private JLabel etiket1, etiket2; private JTextField champSaisie1, champSaisie2;
9.          public Fenetre()
10.          {
10.              setTitle("Une fenetre dynamique");
11.              Container c = getContentPane();
12.              c.setBackground(new Color(213, 223, 245));
13.              setSize(500, 300);
14.              c.setLayout(new FlowLayout());
15.              setLocationRelativeTo(this.getParent()); 
16.
17.              etiket1 = new JLabel("texte initial");
18.              c.add(etiket1);
19.              
20.              champSaisie1 = new JTextField("texte initial");
21.              c.add(champSaisie1);
22.              champSaisie1.addFocusListener(this);
23.              
24.              etiket2 = new JLabel("texte initial");
25.              c.add(etiket2);
26.              
27.              champSaisie2 = new JTextField("texte initial");
28.              c.add(champSaisie2);
29.             
30.              setDefaultCloseOperation(3);
31.          }
32.                    
33.             
34.          public void focusGained(FocusEvent f)
35.          {
36.               etiket1.setText("focus gagné");
37.          }
38.          
39.          public void focusLost(FocusEvent f)
40.          {
41.               etiket1.setText("focus perdu");
42.          }
43.           
44.     }
45.     
46.        
47.     public class TesterFocus
48.     {
49.          public static void main(String [] args)
50.          {
51.               Fenetre f = new Fenetre();
52.               f.setVisible(true);
53.          }
54.     }

Compilez puis exécutez ce programme. Il sera affiché :

Une fenêtre graphique dans laquelle on trouve un champ de texte dont le texte associé est "focus gagné" et un autre champs de texte dont le texte associé est "texte initial". En même temps, le premier champ de texte est sélectionné. Si vous sélectionné le 2ème champ de texte en utilisant la touche tabulation ou la souris, le texte "focus gagné" devient "focus perdu".

Explications :

Les objets de type JLabel sont des étiquettes contenant un texte d'une seule ligne et non modifiable par l'utilisateur. Mais modifiables par le programme. On les instanciés ici avec un texte initial appelé "texte initial" (lignes 17 et 24).

Les objets JTextField sont des champs de texte contenant un texte modifiable par l'utilisateur. On les instanciés ici avec un texte initial appelé "texte initial" (lignes 20 et 27).

Parmi les champs de texte champSaisie1 et champSaisie2, seul champSaisie1 est associé à un objet écouteur (ligne 22). Cet objet écouteur est la fenêtre elle-même puisque c'est la classe Fenetre qui implémente l'interface FocusListener.

Mais dès qu'on exécute le programme, la fenêtre apparait avec le premier champ qui a déjà le focus. C'est pourquoi on ne voit pas l'expression "texte initial" dans le premier label. La méthode focusGained() (en ligne 34) permet d'insérer le texte "focus gagné" dans le premier label (etiket1) lorsque le premier champ a le focus.
Puis la perte de focus par le premier champ entraine le changement de texte. La méthode focusLost() (en ligne 39) permet justement ce changement. Le nouveau texte, conséquence de la perte de focus est "focus perdu".

Comme d'habitude, si vous ne comprenez pas du premier coup, relisez. Ce n'est pas difficile à comprendre.

 Exemple 3 : 

1.     import javax.swing.*;
2.     import javax.swing.event.*;
3.     import java.awt.*;
4.     import java.awt.event.*;
5.     
6.     class Fenetre extends JFrame implements FocusListener
7.     {
8.         private JLabel etiket1, etiket2; private JTextField champSaisie1, champSaisie2;
9.          public Fenetre()
10.          {
10.              setTitle("Une fenetre dynamique");
11.              Container c = getContentPane();
12.              c.setBackground(new Color(213, 223, 245));
13.              setSize(500, 300);
14.              c.setLayout(new FlowLayout());
15.              setLocationRelativeTo(this.getParent()); 
16.
17.              etiket1 = new JLabel("adresse E-mail");
18.              c.add(etiket1);
19.              
20.              champSaisie1 = new JTextField("texte initial");
21.              c.add(champSaisie1);
22.              champSaisie1.addFocusListener(this);
23.              
24.              etiket2 = new JLabel("mot de passe");
25.              c.add(etiket2);
26.              
27.              champSaisie2 = new JTextField("texte initial");
28.              c.add(champSaisie2);
29.             
30.              setDefaultCloseOperation(3);
31.          }
32.                    
33.             
34.          public void focusGained(FocusEvent f) {}
35.          
36.          public void focusLost(FocusEvent f)    
37.          {
38.              String email = champSaisie1.getText();
39.              if(email.indexOf('@') < 0 )
40.              JOptionPane.showMessageDialog(this, "Votre adresse e-mail n est pas correcte");
41.               
42.          }
43.           
44.     }
45.     
46.        
47.     public class TesterFocus2
48.     {
49.          public static void main(String [] args)
50.          {
51.               Fenetre f = new Fenetre();
52.               f.setVisible(true);
53.          }
54.     }

Compilez puis exécutez ce programme. Il sera affiché :

Une fenêtre graphique comme celle ci-dessus. Mais le premier label contient l'expression "adresse e-Mail". Le 2ème label contient l'expression "mot de passe".
Dans le premier champ qui a déjà le focus, tapez une adresse e-mail qui ne contient pas le caractère arobase ( @ ). Si vous quitez ce champ (perte de focus), aussitôt, une fenêtre de dialogue apparaît vous informant : "Votre adresse e-mail n est pas correcte". Vous cliquez sur le bouton OK de cette fenêtre, et elle disparait.


Explications :

Cette fois, le premier champ de saisie réagit seulement à la perte de focus. Evidement, seul la méthode focusLost() a été redéfinie. Que dit la définition de cette méthode ? ...
Ligne 38 : Je déclare une chaine de caractères appelée email. Je lui affecte la valeur du premier champ de saisie. En effet, la méthode getText() de la classe JTextField() permet d'obtenir la valeur d'un champ de saisie. C'est à dire, lachaine de caractères qui se trouve dans un champ de saisie.
Ligne 39 : Si la position (indexOf) du caractère @ dans la chaine email est inférieure à zéro, autremant dit, si le caractère @ n'existe pas dans la chaine email, alors,
Ligne 40 : Faire apparaitre la fenêtre de dialogue de type information pour informer l'utilisateur de la non conformité de l'adresse email qu'il a saisi.

Comme vous le savez déjà, on fait apparaitre ce type de fenêtre grâce à la méthode statique showMessageDialog() de la classe JOptionPane. Les 2 arguments de cette méthode sont : 1. la fenêtre sur laquelle doit apparaitre la fenêtre de dialogue. Ici, cette fenêtre appartient à la classe Fenetre. Puisque la méthode showMessageDialog() est définie dans la classe Fenetre, il est évident que le nom de l'objet est forcément this. L'objet qu'on vient de créer.
Le deuxième argument est le message qui doit apparaitre dans la fenêtre de dialogue.
En toute rigueur, une adresse email n'est pas incorrecte seulement par l'absence du caractère @.

Une adresse email est incorrecte pour plusieurs raisons :
  • Absence de @
  • Absence de .
  • Au moins un caractère avant le caractère @
  • Au moins 2 caractères après le caractère .
  • Pas de caractère accentué
  • Pas de caractère -
  • Peut-être autre chose encore ?
En tout cas, je vous invite à créer une méthode qui, requiert un argument de type String, et qui renvoie true si la chaine de caractères est une adresse email correcte. Et false dans le cas contraire.

Vous serez amenés à créer ce genre de méthode dans vos projets (professionnels) ou mini-projets (Etudes).
 Exemple 4 : 

1.     import javax.swing.*;
2.     import javax.swing.event.*;
3.     import java.awt.*;
4.     import java.awt.event.*;
5.     
6.     class Fenetre extends JFrame implements ActionListener
7.     {
8.         private JLabel etiket; private JRadioButton radio1, radio2; 
9.         private JTextField champSaisie1, champSaisie2;
10.         
10.          public Fenetre()
11.          {
12.              setTitle("Une fenetre dynamique");
13.              setSize(600, 400);
14.              Container c = getContentPane();
15.              setLocationRelativeTo(this.getParent()); 
16.              
17.              etiket = new JLabel("Comment voulez-vous recevoir la réponse ?");
18.              c.add(etiket);
19.              
20.              ButtonGroup groupe = new ButtonGroup();
21.              
22.              radio1 = new JRadioButton("Par e-mail     ");
23.              groupe.add(radio1);
24.              c.add(radio1, BorderLayout.WEST);
25.              radio1.addActionListener(this);
26.              
27.              radio2 = new JRadioButton("Par courrier postal");
28.              groupe.add(radio2);
29.              c.add(radio2, BorderLayout.EAST);
30.              radio2.addActionListener(this);
31.                   
32.              champSaisie1 = new JTextField("ici, votre adresse email");
33.              c.add(champSaisie1, BorderLayout.NORTH);
34.              champSaisie1.setEditable(false);
35.             
36.              champSaisie2 = new JTextField("ici, votre adresse postale");
37.              c.add(champSaisie2, BorderLayout.SOUTH);
38.              champSaisie2.setEditable(false);
39.              
40.              setDefaultCloseOperation(3);
41.          }
42.                    
43.             
44.          public void actionPerformed(ActionEvent a) 
45.          {
46.              if(radio1.isSelected() )
47.              {
48.                   champSaisie1.setEditable(true);
49.                   champSaisie2.setEditable(false);
50.              }
51.              else
52.              { 
53.                   champSaisie2.setEditable(true);
54.                   champSaisie1.setEditable(false);
55.              }
56.         }
57.     }
58.       
59.     public class TesterChampNonModifiable
60.     {
61.          public static void main(String [] args)
62.          {
63.               JFrame f = new Fenetre();
64.               f.setVisible(true);
65.          }
66.     }

Voici un petit exercice que je trouve un peu nul. Je vous dirai pourquoi en fin d'explications.
Un peu nul peut-être, mais instructif quand même.

Mais avant, compilez puis exécutez ce programme, il sera affiché :

Une fenêtre graphique avec 5 composants : En haut (au Nord), nous avons un champ de texte non modifiable dont le texte initial est : "adresse email". En bas (au sud), nous avons un autre champ de texte non modifiable ayant un texte initial : "adresse postale". A gauche (à l'Ouest), un bouton radio dont le texte associé est : "Par e-mail". A droite (à l'Est), un autre bouton radio dont le texte associé est : "Par courrier postal". Puis au centre de la fenêtre, on voit une étiquette contenant le texte : "Comment voulez-vous recevoir la réponse ?".

Cliquez sur le bouton de gauche, et le champ de texte adresse email devient modifiable. Et naturellement, vous pouvez alors saisir l'adresse e-mail. Cliquez maintenant sur le bouton de droite, le champ de texte adresse email redevient non modifiable. Maintenant, c'est le champ de texte adresse postale qui est devenue modifiable.



Explications :

Remarquez d'abord que nous n'avons pas traité les évènements gain ou perte de focus. Je veux montrer ici une autre caractéristique des champs de texte. La possibilité de les rendre non modifiable. Pour ce faire, on utilise la méthode setEditable() de la classe JTextField. Cette méthode requiert un argument de type boolean. true si on veut que le champ soit modifiable. Et false dans le cas contraire. Voir Lignes 34, 38, 48, 49, 53 et 24.

Les boutons radio1 et radio2 sont associés à l'objet Ecouteur de boutons. Cet objet est la fenêtre elle-même. D'où le mot clé this dans les parenthèses de la méthode addActionListener(). Lignes 25 et 34.

Dans la méthode actionPerformed(), nous disons que (ligne 46) si le bouton radio1 est sélectionné, alors, le champ de texte champSaisie1 est modifiable (ligne 48) et le champ de texte champSaisie2 est non modifiable (ligne 49). Sinon, c'est plutôt la situation inverse qui se produit (lignes 53 et 54).

Quelque chose de nouveau sur cet exemple. C' est la disposition des composants graphiques sur la fenêtre. On n'a pas utilisé le gestionnaire de mise en forme FlowLayout. Comme je vous l'avais dit dans le chapitre D.1 Création d'une fenêtre statique. (relisez ce chapitres), en l'absence de précision, c'estle gestionnaire de mise en forme BorderLayout qui est utilisé. C'est pourquoi, en ajoutant l'objet etiket de type JLabel (ligne 18) dans le conteneur c, il se place automatique au milieu. Et si c'était le seul composant, il aurait naturellement occupé toute la surface de la fenêtre. Seulement, il ya d'autres composants.
Les 2 boutons radio qu'on met dans un groupe (lignes 23 et 28) pour que la sélection de l'un entraine automatiquement la non sélection de l'autre. Puis on ajoute le bouton radio1 en précisant l'endroit. La ligne 24 signifie : ajouter le bouton radio1 au contenant, du côté gauche. West = Ouest et on sait que l'Ouest se trouve toujours à gauche. La ligne 29 signifie : ajouter le bouton radio2 au contenant, du côté droit. East = Est et on sait que l'Est se trouve toujours à droite. Même raisonnement et on comprend alors pourquoi le champ de texte champSaisie1 est placé en haut et le champ de texte champSaisie2 est placé en bas.
Et voilà !

Je disais que l'exercice est un peu nul pour la simple raison que ce n'est pas une façon élégante de placer ces éléments. Mais parce que nous n'avons pas encore vu le chapitre consacré à la mise en forme des composants graphiques, on se contente de cette disposition. L' important c'était surtout de comprendre commment rendre un champ de texte non modifiable et aussi comprendre le gestionnaire de mise en forme BorderLayout.
Améliorez !

Faîtes en sorte que le champ qui n'est pas modifiable soit vide. En effet, si le programme propose à l'utilisateur le choix d'une adresse email ou d'une adresse postale, et que l'utilisateur rempli d'abord un champ, puis change d'avis en remplissant le deuxième champ, c'est la valeur de ce deuxième champ qui sera traitée. La valeur d'un champ de texte est la chaine de caractères contenue dans ce champ. Du coup, la valeur du premier champ ne sert plus à rien. Si l'utilisateur du logiciel veut revoir tous les champs remplis avant d'envoyer les informations, il vaut mieux que l'une des adresses ne soit pas vue. Pour cela, on utilise la méthode setText() en utilisant comme argument, une chaine de caractères vide. Une chaine avec zéro caractères. Voici vomment améliorer le programme.

Ajoutez l'intruction suivante : champSaisie2.setText(""); sur la ligne 49. On a le droit de mettre plusieurs intructions sur la même ligne. Il faut les séparer par au moins un caractère espace.
Puis ajoutez l'intruction suivante : champSaisie1.setText(""); sur la ligne 54

Recompilez puis exécutez le programme. Il apparaît la même chose que ci-dessus. Sauf que si vous sélectionnez le premier bouton, la chaine de caractères du deuxième champ (en bas) disparaît. Et vous pouvez modifier le champ d'en haut.
Si au contraire, vous remplissez le champ d'en bas après avoir choisi le bouton radio de droite, le deuxième bouton donc, c'est la chaine de caractère du champ d'en haut qui disparaît. Et vous pouvez modifier le champ d'en bas
Cette disparition, on la doit évidement à la méthode setText(), avec une chaine à zéro caractère ("").
Il peut se produire un autre évènement avec les champs de texte. Un évènement qui n'est pas le gain ou la perte de focus. Cet évènement est le suivant :

L'utilisateur appui sur la touche de validation du clavier au moment où le champ possède le focus.

Attention, ce n'est pas le gain de focus. Mais l'appui sur la touche de validation au moment où le champ possède le focus. Cet évènement est traité par la méthode actionPerformed() de l'interface ActionListener qui possède cette seule méthode déclarée ainsi :

public void actionPerformed(ActionEvent a)

Un exemple tout bête !
 Exemple 5 : 

1.     import javax.swing.*;
2.     import javax.swing.event.*;
3.     import java.awt.*;
4.     import java.awt.event.*;
5.     
6.     class Fenetre extends JFrame implements ActionListener
7.     {
8.         
9.         private JTextField champSaisie1, champSaisie2;
10.         
10.          public Fenetre()
11.          {
12.              setTitle("Une fenetre dynamique");
13.              setSize(300, 100);
14.              Container c = getContentPane();
15.              c.setLayout(new FlowLayout() );
16.              setLocationRelativeTo(this.getParent()); 
17.              
18.              champSaisie1 = new JTextField(20);
19.              c.add(champSaisie1);
20.              champSaisie1.addActionListener(this);
21.              
22.              champSaisie2 = new JTextField(20);
23.              c.add(champSaisie2);
24.              champSaisie2.setEditable(false);
25.              
26.             setDefaultCloseOperation(3);
27.        } 
28.         
29.        public void actionPerformed(ActionEvent a)
30.        {
31.             String valeurChamp1 = champSaisie1.getText();
32.             champSaisie2.setText(valeurChamp1);
33.        }
34.         
35.    }
36.         
37.    public class TesterActionSurChampTexte
38.    {
39.          
40.         public static void main(String [] args)
41.         {
42.              JFrame f = new Fenetre();
43.              f.setVisible(true);
44.         }
45.    }


Compilez puis exécutez ce programme, il sera affiché :

Une fenêtre graphique avec 2 champs de texte. Le premier champ est modifiable. Le deuxième ne l'est pas.
Si vous tapez quelques caractères dans ce premier champ, et que vous appuyez sur la touche validation (touche entrée) de votre clavier, aussitôt, la chaine de caractères du premier champ est copiée dans le deuxième champ.


Explications :

Seul le premier champ de texte (modifiable) réagit à l'action de l'utilisateur. Parce que c'est le seul objet associé à un objet écouteur (ligne 20). Le 2ème champ de texte est rendu non modifiable (ligne 24). La réaction du programme face à l'action de l'utilisateur est définie dans la méthode actionPerformed() (ligne 29). Dans la définition de cette méthode, en ligne 31, on déclare une variable de type String appelée valeurChamp1 et on lui affecte la valeur du premier champ. Cette valeur est fournie par la méthode getText(). Puis, grâce à la méthode setTex(), on donne cette valeur au deuxième de texte. C'est pourquoi le fait d'appuyer sur la touche entrée du clavier lorsque le premier champ possède le focus, copie la valeur du premier champ dans le deuxième.
Je n'étais pas obligé de rendre le deuxième champ modifiable. Mais je l'ai fait pour marquer la différence entre les deux champs.

Autre chose : Cette fois, j'ai créé les objets JTextField avec un constructeur qui requiert un argument de type int. Exemple : champSaisie1 = new JTextField(20); Le nombre entier 20 représente le nombre de caractères visibles du champ de texte. C'est en fait la taille du champ de texte. On peut y mettre autant de caractères qu'on veut.
Il existe d'autres évènements liés aux champs de texte.
Il vous est sans doute déjà arrivé de remplir un formulaire. Pendant que vous saisissez un champ de texte, tous les caractères que vous saisissez sont automatiquement copiés dans un autre champ.
Donc, l'action ici, c'est le fait de saisir des caractères dans le champ.
Et la réaction, c'est le fait qu'un autre champ reçoive les mêmes caractères.

Le fait de saisir des caractères s'apparente à l'insertion de données. C'est un évènement qu'on traite grâce à la méthode insertUpdate().
Il peut vous arriver d'effacer des caractères déjà tapés suite à une erreur de saisie.
Le fait d'effacer des caractères s'apparente au retrait de données. C'est un évènement qu'on traite grâce à la méthode removeUpdate().

Ces deux méthodes sont déclarées dans l'interface DocumentListener :

public void insertUpdate(DocumentEvent d)
public void removeUpdate(DocumentEvent d)


Il existe une 3ème méthode de cette interface. Elle est déclarée :

public void changedUpdate(DocumentEvent d)
Mais elle ne correspond pas à une action sur un champ de texte. On en reparlera plus tard. Au bon endroit.

 Exemple 6 : 

1.    import javax.swing.*;
2.    import java.awt.*;
3.    import java.awt.event.*;
4.    import javax.swing.event.*;
5.
6.     class Fenetre extends JFrame implements DocumentListener
7.     {
8.            
9.          private JTextField saisie, copie;
10.          
11.          public Fenetre()
12.          {
13.               setTitle("Une fenetre dynamique");
14.               setSize(300, 100);
15.               Container c = getContentPane();
16.               c.setLayout(new FlowLayout() );
17.               setLocationRelativeTo(this.getParent()); 
18.               
19.               saisie = new JTextField(20);
20.               c.add(saisie);
21.               saisie.getDocument().addDocumentListener(this);
22.                            
23.               copie = new JTextField(20);
24.               c.add(copie);
25.               copie.setEditable(false);
26.               copie.setBackground(new Color(255, 208, 208) );
27.               		  
28.               setDefaultCloseOperation(3);
29.          }
30.          
31.          public void insertUpdate(DocumentEvent d) 
32.          { 
33.               String valeurChamp1 = saisie.getText();
34.               copie.setText(valeurChamp1);
35.          }
36.           
37.          public void removeUpdate(DocumentEvent d)
38.          {
39.               String valeurChamp1 = saisie.getText();
40.               copie.setText(valeurChamp1);
41.          }
42.          
43.          public void changedUpdate(DocumentEvent d) {}
44.    }
45.         
46.    public class TesterCopieAutomatiqueDeChamp
47.    {
48.          
49.         public static void main(String [] args)
50.         {
51.               JFrame f = new Fenetre();
52.               f.setVisible(true);
53.         }
54.    }
Compilez puis exécutez ce programme, il sera affiché :

Une fenêtre graphique avec 2 champs de texte. Le premier champ est modifiable. Le deuxième ne l'est pas et il est coloré en rouge.
Si vous tapez quelques caractères dans ce premier champ, simultanément, le deuxième champ se rempli des mêmes caractères. Si vous supprimez quelques caractères, simultanément, elles disparaissent aussi du deuxième champ.


Explications :

Ligne 19 : On crée un champ de texte appelé saisie dont la taille est de 20 caractères. Ligne 20 : on ajoute ce champ au conteneur. Ligne 21 : on associe à cet objet champ de texte, un objet écouteur qui est la fenêtre elle-même (this). Mais cette fois, les choses ne se passent pas comme d'habitude. Au lieu d'écrire : saisie.addDocumentListener(this);, on écrit plutôt : saisie.getDocument().addDocumentListener(this); Pourquoi ? ...
Parce qu'en réalité, c'est seulement à un objet de type Document qu'on n'associe l'objet écouteur de type DocumentListener. Or, un objet JTextField n'est pas un objet Document. Mais on peut obtenir un objet Document en appliquant sur un objet JTextField, la méthode getDocument().
On aurait alors pu écrire : Document d = saisie.getDocument(); Puis écrire : d.addDocumentListener(this);
Puisque d = saisie.getDocument(), on fait un raccourci en écrivant directement comme en ligne 21.

Ligne 23 : on crée un autre objet de type JTextField de 20 caractères appelé copie. Ligne 24 : on l'ajoute au conteneur. Ligne 25, on rend le champ de texte non modifiable. Puis en ligne 26 : on lui donne une couleur.

Maintenant, la redéfinition des méthodes de l'interface DocumentListener.

Dans la méthode insertUpdate() en ligne 31, on crée une variable de type String (ligne 33)dans laquelle on met la valeur du champ saisie. C'est à dire, ce que vous tapez dans ce champ. En ligne 34 : on donne au champ de texte copie, la valeur du champ de texte saisie. C'est pourquoi, au fur et à mesure que vous tapez des caractères dans le premier champ, le deuxième se rempli des mêmes caractères.

La définition de la méthode insertUpdate() est la même que celle de la méthode removeUpdate(). Ainsi, lorsque vous enlevez des caractères déjà entrés dans le premier champ, les mêmes caractères s'effacent dans le deuxième champ de façon simultanée.

Bien entendu, on doit redéfinir la 3ème méthode ( changedUpdate() ) à vide. Sauf, bien entendu, si on a utilisé la classe adaptatrice DocumentAdapter

Côté pratique, on redéfinit toujours, en général, les deux méthodes insertUpdate() et removeUpdate(). En effet, pourquoi enlever des caractères déjà entrés dans le premier champ sans le faire dans le deuxième. Il est possible qu'on ait une bonne raison à cela. Mais c'est rare.


Une dernière chose. Dans ce programme, une nouvelle instruction en ligne 4 :
import javax.swing.event.*;

Parce que les évènements traités par les méthodes de l'interface DocumentListener sont dans le package javax.swing.event.

Pour être sûr de na pas se tromper, lorsque vous traitez des programmes java basés sur les évènements, écrivez les 4 premières lignes de ce programme.
Essayez ceci.

Reprenez le programme ci-dessus. Redéfinissez la méthode removeUpdate() à vide :
public void removeUpdate(DocumentEvent d) { }
Recompilez puis exécutez à nouveau le programme. Si vous saisissez les caractères dans le premier champ, automatiquement, ces mêmes caractères se remplissent dans le deuxième champ. Normal : La méthode insertUpdate() a été redéfinie pour ça. Mais si vous effacer des caractères du premier champ, aucun caractère du deuxième champ ne s'efface. Normal aussi, la méthode removeUpdate() a été redéfinie à vide. Ceci explique forcément cela.

La connaissance, c'est bien. La partager, c'est mieux
Conseiller ce site à un(e) ami(e):

Son e-mail est :       
Une suggestion à faire pour ce site ? ... Contact : webmaster@debutantprog.com
← (précédent) D.5 Evènements sur les boutons radio
D.7 Evènements boites de liste
Accueil S O M M A I R E

D.6 Evènements sur champs de texte