← (précédent) D.6 Evènements sur les champs de texte
D.8 Evènements sur les boites combo
Accueil S O M M A I R E

D.7 Evènements sur les boites de liste

Les boites de liste peuvent être exploitées de 2 façons différentes.

1. Vous sélectionnez un ou plusieurs objets de la boite. Puis vous cliquez sur un bouton et il se produit une réaction qui tient compte du ou des objets sélectionnés.
La méthode getSelectedValue() permet d'accéder à la valeur sélectionnée. Et la méthode getSelectedValues() ( Remarquez le s à la fin ) permet d'accéder aux informations des valeurs sélectionnées.

2. Vous cliquez sur un seul objet de la boîte. Aussitôt, il se produit une réaction qui tient compte du seul objet sélectionné.
L' action consistant à choisir l'une des valeurs est traitée par la méthode valueChanged(). Cette méthode est ainsi déclarée dans l'interface ListSelectionListener du package javax.swing.event

public void valueChanged(ListSelectionEvent l)

Et c'est la seule méthode de cette interface. Il n'ya donc pas de classe adaptatrice.
 Exemple 1 : 

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 ActionListener
7.     {
8.            
9.          private JList listeNoms; private JButton bouton;
10.         private String [] noms = { "De GAULLE", "POMPIDOU", "GISCARD", "MITTERAND", "CHIRAC"};
11.         private JLabel etiket;
12.          public Fenetre(String titre)
13.          {
14.               setTitle(titre);
15.               setSize(300, 300);
16.               Container c = getContentPane();
17.               c.setLayout(new FlowLayout() );
18.               setLocationRelativeTo(this.getParent()); 
19.               
20.               listeNoms = new JList(noms);               
21.               c.add(listeNoms);
22.               
23.               bouton = new JButton("validez votre choix");
24.               c.add(bouton); bouton.setBackground(new Color(255, 208, 208) );
25.               bouton.addActionListener(this);
26.                 
27.               etiket = new JLabel(); 
28.               c.add(etiket);
29.               setDefaultCloseOperation(3);
30.         }
31.                   
32.           
33.         public void actionPerformed(ActionEvent a)
34.         {
35.              String choix = (String) listeNoms.getSelectedValue();
36.              etiket.setText("Votre choix est : " + choix);
37.         }
38.      }  
39.           
40.    public class TesterListe
41.    {
42.          public static void main(String [] args)
43.          {
44.               JFrame f = new Fenetre("essais sur les listes");
45.               f.setVisible(true);
46.          }
47.    
48.   }

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

Une fenêtre avec 3 composants : la liste de noms, un bouton nommé "validez votre choix" et une étiquette non visible. Et pour cause, elle a la même couleur que la fenêtre et elle ne contient aucun texte. Un objet Jlabel ne peut pas être coloré.
Choisissez l'un des noms en cliquant dessus. Le nom est alors sélectionné. Puis cliquez sur le bouton. Aussitôt, apparaît le texte : "Votre choix est : " suivi du nom que vous aurez sélectionné.


Explications :

Ligne 20 : création d'une boite de liste (listeNoms) grâce à la classe JList. Le contstructeur requiert un argument de type tableau de String. Et justement, en ligne 10, on a créé un tableau de String appelé noms. Ligne 21, on ajoute la boite de liste dans le conteneur.
Ligne 23 : on crée un bouton nommé "validation de votre choix". Ligne 24 : on ajoute le bouton dans le conteneur. Puis on lui donne une couleur.
Ligne 25 : on associe au bouton l'objet écouteur qui est la fenêtre elle-même (this). C'est pourquoi c'est la classe Fenetre qui implémente l'interface ActionListener (ligne 6). Lignes 27 et 28 : on crée une étiquette, qu'on ajoute au conteneur.
Dans la méthode actionPerformed(), on crée une variable de type String appelée choix à qui on affecte le nom de la chaine de caractères sélectionnée dans la boîte de liste. Mais la méthode getSelectValue() retourne en fait une variable de type Object. On transforme alors le type Object en type String en faisant une conversion explicite. D'où (String) devant listeNoms.getSelectedValue(). Puis en ligne 36, on on donne à l'étiquette, la chaine de caractères "Votre choix est : " ajouté à cela, la chaine de caractères contenue dans la variable choix. C'est pourquoi, en cliquant sur le bouton, après avoir choisi, on obtient Votre choix : suivi du nom sélectionné.

Si vous n'avez pas choisi un nom dans la liste, alors, la réponse sur l'étiquette sera : Votre choix est : null
null représente l'objet vide.

Vous pouvez faire une multi-sélection des noms de la liste. C'est possible en appuyant sur la touche Ctrl de votre clavier azerty en même temps que vous utilisez votre souris pour sélectionner plusieurs noms. Dans ce cas, le nom qui s'affichera dans l'étiquette, sera toujours le premier dans la liste. J'entends par là, le premier parmi ceux sélectionnés. Par exemple, si vous sélectionnez "CHIRAC", puis "POMPIDOU". C'est POMPIDOU qui s'affichera. Parce que POMPIDOU est placé avant CHIRAC dans la liste.

Autre chose : Le constructeur est doté d'un argument de type String. C'est le titre que je donne à ma fenêtre. Voir ligne 14. Ce n'est pas utile ici de donner un titre à une fenêtre au moment de sa création (ligne 44). Mais s'il vous arrive d'avoir à créer plusieurs fenêtre dans un même programme, et que toutes les fenêtres ne doivent pas avoir le même titre, il est intéressant de donner un titre à sa fenêtre au moment de sa création en procédant comme ci-dessus.

Ce qui est vrai pour le titre l'est aussi pour les dimensions ou la couleur de la fenêtre. Vrai pour n'importe quelle caractéristique de la fenêtre. Dans le chapitre EXERCICES CORRIGES partie 1 : les composants graphiques , On verra comment on peut manipuler les caractéristiques d'une fenêtre dans un programme.
Lorsqu'on crée une boîte de liste, aucun élément n'est pré-sélectionné. Vous pouvez faire en sorte qu'un élément de la liste soit déjà sélectionné au moment de son affichage. Pour cela, on utilise la méthode setSelectedIndex().

Dans le programme ci-dessus, en ligne 20, ajoutez l'instruction suivante : listeNoms.setSelectdeIndex(1); Puis recompilez et exécutez. Il sera affiché la même fenêtre avec le nom POMPIDOU déjà sélectionné. En effet, la méthode setSelectedIndex() requiert un argument de type int. Ce nombre est la position de l'élément à présélectionner. Ici, la position 1 est celle de POMPIDOU. La position 0 étant toujours celle du premier élément.

Lorsqu'on crée une boîte de liste, par défaut, on peut sélectionner un nombre quelconque d'éléments. On peut faire en sorte que l'utilisateur ne puisse sélectionner qu'un seul élément. On peut même faire en sorte que l'utilisateur puisse sélectionner un nombre d'éléments qui suivent forcément. Par exemple, vous ne pourrez pas sélectionner POMPIDOU et CHIRAC. Parce que ces deux noms ne se suivent pas. Mais vous pourrez sélectionner GISCARD et MITTERAND

Pour cela, on utilise la méthode setSelectionMode().

listeNoms.setSelctionMode(SINGLE_SELECTION) : pour une liste à sélection unique

listeNoms.setSelctionMode(SINGLE_INTERVAL_SELECTION) : pour une liste à sélection multiple. Mais les éléments sélectionnés seront forcément adjacents. Autrement dit, entre le premier et le dernier éléments sélectionné, il n'y aura pas d'élément non sélectionné.

listeNoms.setSelctionMode(MULTIPLE_INTERVAL_SELECTION) : pour une liste à sélection multiple. Ici, pas de contrainte sur les éléments sélectionnés.

Par défaut, une boite de liste ne contient pas de barre de défilement. Vous pouvez changer cela grâce à la classe JScrollPane.

JScrollPane defiler = new JScrollPane(listeNoms);

Ainsi, la boîte de liste listeNoms apparaîtra dans une barre de défilement. ATTENTION !!! Dans ce cas, on n'ajoute pas la boite dans le conteneur. Mais plutôt la barre de défilement. Au lieu de : c.add(listeNoms); vous remplacerez par c.add(defiler);

Par défaut, la barre de défilement affiche 8 éléments. Si la liste contient moins de 8 valeurs, la barre de défilement n'apparaîtra pas. Vous pourrez changer ce nombre 8 par un autre. Par exemple : l'instruction listeNoms.setVisibleRowCount(4); fera en sorte que la barre de défilement apparaîsse dès que la boite contiendra au moins 4 éléments.

 Exemple 2 : 

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 ActionListener
7.     {
8.            
9.          private JList listeNoms; private JButton bouton;
10.         private String [] noms = { "De GAULLE", "POMPIDOU", "GISCARD", "MITTERAND", "CHIRAC"};
11.         
12.          public Fenetre(String titre)
13.          {
14.               setTitle(titre);
15.               setSize(300, 300);
16.               Container c = getContentPane();
17.               c.setLayout(new FlowLayout() );
18.               setLocationRelativeTo(this.getParent()); 
19.               
20.               listeNoms = new JList(noms);               
21.               c.add(listeNoms);
22.               
23.               bouton = new JButton("validez votre choix");
24.               c.add(bouton); bouton.setBackground(new Color(255, 208, 208) );
25.               bouton.addActionListener(this);
26.                 
27.               setDefaultCloseOperation(3);
28.         }
29.                   
30.           
31.         public void actionPerformed(ActionEvent a)
32.         {
33.              Object [] elements = listeNoms.getSelectedValues();
34.              
35.              for(int i = 0; i < elements.length; i++)
36.              System.out.println( (String) elements[i] );
37.         }
38.     }   
39.           
40.    public class TesterListe2
41.    {
42.          public static void main(String [] args)
43.          {
44.               JFrame f = new Fenetre("essais sur les boites de listes");
45.               f.setVisible(true);
46.          }
47.    }

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

Une fenêtre avec 2 composants : la liste de noms et un bouton nommé "validez votre choix".
Choisissez un des noms en cliquant dessus. Le nom est alors sélectionné. Puis cliquez sur le bouton. Aussitôt, il s'affiche sur la fenêtre console, le nom sélectionné.
Sélectionnez un ensemble de noms. Les noms peuvent se suivent ou pas. Ce n'est pas important. Ensuite, cliquez sur le bouton. Aussitôt, il s'affiche sur la fenêtre console, la liste des noms. Ces noms apparaissent dans le même ordre que dans la boite. Quelque soit l'ordre dans lequel ils ont été sélectionnés.


Explications :

Ce qu'il y a de nouveau ici se trouve dans la méthode actionPerformed().

La méthode getSelectedValue() retourne l'élément sélectionné dont le type est Object.
La méthode getSelectedValues() retourne un tableau d'éléments sélectionnés dont le type est Object.
C'est pourquoi, en ligne 33, on crée un tableau de type Object, dans lequel on met la référence du tableau correspondant à la liste des éléments sélectionnés dans la boite de liste.
En lignes 35 et 36, on parcours ce tableau, en affichant chacun des éléments. Mais auparavant, on transforme chaque élément Object en variable de type String.
Je rappelle que System.out.println() permet d'afficher dans la fenêtre console et pas dans la fenêtre graphique.
 Exemple 3 : 

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 ListSelectionListener
7.     {
8.            
9.          private JList listeNoms; 
10.         private String [] noms = { "De GAULLE", "POMPIDOU", "GISCARD", "MITTERAND", "CHIRAC"};
11.         
12.          public Fenetre(String titre)
13.          {
14.               setTitle(titre);
15.               setSize(300, 300);
16.               Container c = getContentPane();
17.               c.setLayout(new FlowLayout() );
18.               setLocationRelativeTo(this.getParent()); 
19.               
20.               listeNoms = new JList(noms);               
21.               c.add(listeNoms);
22.               listeNoms.addListSelectionListener(this);
23.               
24.               setDefaultCloseOperation(3);
25.         }
26.                   
27.           
28.         public void valueChanged(ListSelectionEvent L)
29.         {
30.              
31.              String choix = (String) listeNoms.getSelectedValue();
32.              
33.              System.out.println( "Votre choix est : " + choix );
34.         }
35.     }   
36.           
37.    public class TesterListe3
38.    {
39.          public static void main(String [] args)
40.          {
41.               JFrame f = new Fenetre("essais sur évènements de type List");
42.               f.setVisible(true);
43.          }
44.    }

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

Une fenêtre avec un seul composant : la liste de noms.
Choisissez par exemple le nom De GAULLE en cliquant dessus. Le nom est alors sélectionné et, aussitôt, il s'affiche sur la fenêtre console, la phrase Votre choix est : De GAULLE. Mais l'affichage se fait 2 fois de suite.

Pourquoi ? ... voir explications.


Explications :

Avant d'expliquer le problème, sachez qu'ici, on exploite l'évènement qui consiste à sélectionner un élément de la liste. D' où l'impléméntation de l'interface ListSelectionListener par la classe Ecouteur qui est la classe Fenetre (ligne 6).
L' objet écouteur ici est donc la fenêtre. D'où le mot clé this dans la méthode addListSelectionListener() en ligne 22. La méthode addListSelectionListener est appliquée à l'objet source de l'évènement qui est naturellement la boite de liste.

On redéfinit alors la seule méthode de cette interface qui est valueChanged(). Voir lignes 28 à 34.
En ligne 28 : on crée une variable de type String appelée choix à qui on affecte le nom de la chaine de caractères sélectionnée dans la boîte de liste. Mais la méthode getSelectValue() retourne en fait une variable de type Object. On transforme alors le type Object en type String en faisant une conversion explicite. D'où (String) devant listeNoms.getSelectedValue().
En ligne 29 : affichage dans la fenêtre console, du nom sélectionné, précédé de "Votre choix est : ".
Seulement voilà, cette affichage se fait 2 fois. Pourquoi ? ...

Parce qu'en fait, la méthode valueChanged() s'applique dans 2 cas. D'abord, lorsque vous appuyez sur le bouton de la souris. Ensuite, lorsque vous le relâchez.
Si vous trouvez cette double réaction stupide, sachez que vous nêtes pas le seul. Moi aussi. J'ai néanmoins trouvé une tentative d'explication dans un site. L'appui sur le bouton de la souris correspondrait à une désélection d'un élément précédement sélectionné. Et le relachement du bouton de la souris correspondrait à la sélection d'un nouvel élément. Personnellement, ça ne m'a pas trop convaincu.
Quoi qu'il en soit, les choses sont comme elles sont et ce sont les créateurs du langage Java qui ont voulu que les choses soient ainsi et pas autrement. Il paraît que dans certains problèmes, cette double réaction s'avère utile.
Cela dit, et fort heureusement, il y existe une solution à ce problème. Il existe une méthode qui permet de résoudre le problème. C'est la méthode getValueIsAdjusting() de la classe ListSelectionEvent.

De manière générale, on exploite la méthode valueChanged() en commençant par écrire ceci :
if( !L.getValueIsAdjusting() ) { }
A l'intérieur des accolades, on met alors la redéfinition de la méthode valueChanged().

if( !L.getValueIsAdjusting() ) veut dire : Si l'évènement de type ListSelectionEvent n'est pas en phase de transition, c'est à dire appui sur le bouton de la souris au moment de la sélection dans la liste, autrement dit, si on a déjà relaché le bouton de la souris au moment de la sélection, Ou encore, si on a déjà terminé la phase de sélection d'un élément de la liste.

L est l'objet évènement de type ListSelectionEvent. C'est l'argument de la méthode valueChanged(). Voir ligne 28. Rappelons que ! est l'opérateur qui qui marque la différence d'une situation booléenne. Autrement dit, c'est le non logique.
Ainsi, le code de la méthode valueChanged() sera exécutée seulement après la sélection d'un ou des éléments d'une liste.
 Exemple 4 : 

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 ListSelectionListener
7.     {
8.            
9.          private JList listeNoms; 
10.         private String [] noms = { "De GAULLE", "POMPIDOU", "GISCARD", "MITTERAND", "CHIRAC"};
11.         
12.          public Fenetre(String titre)
13.          {
14.               setTitle(titre);
15.               setSize(300, 300);
16.               Container c = getContentPane();
17.               c.setLayout(new FlowLayout() );
18.               setLocationRelativeTo(this.getParent()); 
19.               
20.               listeNoms = new JList(noms);               
21.               c.add(listeNoms);
22.               listeNoms.addListSelectionListener(this);
23.               
24.               setDefaultCloseOperation(3);
25.         }
26.                   
27.           
28.         public void valueChanged(ListSelectionEvent L)
29.         {
30.              if( !L.getValueIsAdjusting() )
31.              {
32.                   String choix = (String) listeNoms.getSelectedValue();
33.                    System.out.println( "Votre choix est : " + choix );
34.              }
35.         }   
36.    }       
37.    public class TesterListe4
38.    {
39.          public static void main(String [] args)
40.          {
41.               JFrame f = new Fenetre("essais sur évènements de type List");
42.               f.setVisible(true);
43.          }
44.    }

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

Une fenêtre avec un seul composant : la liste de noms.
Choisissez par exemple le nom De GAULLE en cliquant dessus. Le nom est alors sélectionné et, aussitôt, il s'affiche sur la fenêtre console, la phrase Votre choix est : De GAULLE. Une seule fois.


Et voilà le travail. Pas besoin d'explications il me semble.
 Exemple 5 : 

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 ListSelectionListener
7.     {
8.            
9.          private JList listeNoms; 
10.         private String [] noms = { "De GAULLE", "POMPIDOU", "GISCARD", "MITTERAND", "CHIRAC"};
11.         
12.          public Fenetre(String titre)
13.          {
14.               setTitle(titre);
15.               setSize(300, 300);
16.               Container c = getContentPane();
17.               c.setLayout(new FlowLayout() );
18.               setLocationRelativeTo(this.getParent()); 
19.               
20.               listeNoms = new JList(noms);               
21.               c.add(listeNoms);
22.               listeNoms.addListSelectionListener(this);
23.               
24.               setDefaultCloseOperation(3);
25.         }
26.                   
27.           
28.         public void valueChanged(ListSelectionEvent L)
29.         {
30.              if( !L.getValueIsAdjusting() )
31.              {
32.                   Object [] elements =  listeNoms.getSelectedValues();
33.                   for(int i = 0; i < elements.length; i++)
34.                   {
35.                        System.out.println( (String) elements[i] );
36.                   }
37.                   System.out.println("*** Fin du clic ***");
38.              }
39.         }   
40.    }      
41.
42.    public class TesterListe5
43.    {
44.          public static void main(String [] args)
45.          {
46.               JFrame f = new Fenetre("essais sur évènements de type List");
47.               f.setVisible(true);
48.          }
49.    }

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

Une fenêtre avec un seul composant : la liste de noms.

Choisissez par exemple le nom De GAULLE en cliquant dessus. Le nom est alors sélectionné et, aussitôt, il s'affiche sur la fenêtre console ceci:

De GAULLE
*** Fin du clic ***

Le nom De GAULLE reste sélectionné. Si vous appuyez sur la touche majuscule de votre clavier, puis vous cliquez en même temps sur GISCARD, il sera affiché sur la fenêtre console :

De GAULLE
POMPIDOU
GISCARD
*** Fin du clic ***

Ces 3 noms restent sélectionnés. Si vous appuyez maintenant sur la touche controle (Ctrl) de votre clavier, puis vous cliquez en même temps sur CHIRAC, il sera affiché sur la fenêtre console :

De GAULLE
POMPIDOU
GISCARD
CHIRAC
*** Fin du clic ***


Explications :

Ligne 32 : La méthode getSelectedValues() permet de renvoyer un tableau d'éléments sélectionnés dans la boite de liste. Chaque élément renvoyé est de type Object. C'est pourquoi on crée un tableau de type Object appelé elements dans laquelle on met la référence du tableau d'éléments renvoyés par la méthode getSelectedValues().
EN ligne 33, on parcours le tableau d'éléments renvoyés.
En ligne 35, on affiche sur la fenêtre console, chaque élément du tableau. Mais après avoir tranformé le type Object en type String. Puis en 37, on affiche aussi ceci : *** Fin du clic ***

En cliquant sur De GAULLE, il s'affiche De GAULLE. C'est le seul élément du tableau.

En cliquant ensuite sur GISCARD en même temps qu'on appuie sur la touche majuscule du clavier, tous les noms compris entre De GAULLE et GISCARD sont sélectionnés. Donc, De GAULLE, POMPIDOU et GISCARD sont sélectionnés. D'où leur affichage.

En cliquant ensuite sur CHIRAC en même temps qu'on appuie sur la touche Ctrl du clavier, les 3 noms ci-dessus étant déjà sélection, il est aussi sélectionné le nom CHIRAC. MITTERAND n'est pas sélectionné parce que ce n'est pas sur la touche majuscule qu'on a appuyé. D'où l'affichage des 4 noms sélectionnés.
Conseil :

Je vous conseillerais, vous les débutants en programmation, d'utiliser plutôt un bouton de validation pour exploiter les éléments sélectionnés dans une boite de liste. L'utilisateur de votre programme sélectionne d'abord un ou plusieurs éléments de la boite. Puis Grâce à la méthode getSelectedValue() ou getSelectedValues(), vous traitez le problème à résoudre.

Si vous voulez forcément que la sélection d'un élément entraine une réaction immédiate, préférez alors la boite de liste à sélection unique. Dès que l'utilisateur choisit un seul élément de la liste, la réaction se produit aussitôt.

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.6 Evènements sur les champs de texte
D.8 Evènements sur les boites combo
Accueil S O M M A I R E

D.7 Evènements sur les boites de liste