LECON 307


Les listes : l'objet JComboBox
Nous allons continuer à explorer les objets que nous propose swing.
Ici, nous parlerons des listes de choix ou JComboBox, nous pourrons ainsi améliorer notre animation...

Let's go, ZérO boys... and girls !
Sommaire du chapitre :

  • Première utilisation
  • L'interface ItemListener
  • Changer la forme de notre animation
  • Ce qu'il faut retenir

Première utilisation

Comme à l'accoutumée, nous allons d'abord utiliser cet objet dans un contexte vierge de tout code... Alors créez-vous un projet avec une classe contenant la méthode main et une classe qui sera héritée de JFrame.

Dans cet exemple, nous allons bien évidemment utiliser une liste, donc créez en une...
Ce type d'objet ne possède pas de constructeur avec un libellé en paramètre, comme les boutons par exemple ! Il faut donc mettre un JLabel à côté !


Voici un premier code :

Code : Java -
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
 
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
 
 
public class Fenetre extends JFrame {
        
        private JPanel container = new JPanel();
        private JComboBox combo = new JComboBox();
        private JLabel label = new JLabel("Une ComboBox");
        
        public Fenetre(){
        
        this.setTitle("Animation");
        this.setSize(300, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
 
        container.setBackground(Color.white);
        container.setLayout(new BorderLayout());
                        
        JPanel top = new JPanel();
        top.add(label);
        top.add(combo);
        
        container.add(top, BorderLayout.NORTH);
        this.setContentPane(container);
        this.setVisible(true);                   
        }
 
}


Et l'aperçu :


Vous constatez que votre objet est ridiculement petit...
Mais vous connaissez le remède !

Code : Java -
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
 
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
 
 
public class Fenetre extends JFrame {
        
        private JPanel container = new JPanel();
        private JComboBox combo = new JComboBox();
        private JLabel label = new JLabel("Une ComboBox");
        
        public Fenetre(){
        
        this.setTitle("Animation");
        this.setSize(300, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
 
        container.setBackground(Color.white);
        container.setLayout(new BorderLayout());
        
        combo.setPreferredSize(new Dimension(100,20));
                        
        JPanel top = new JPanel();
        top.add(label);
        top.add(combo);
        
        container.add(top, BorderLayout.NORTH);
        this.setContentPane(container);
        this.setVisible(true);            
        }
}


Et voilà :

Et comment on renseigne cette liste ?

Nous y voilà ! Pour ça, il suffit d'utiliser la méthode addItem(Object obj).
Vous devez savoir que lorsque l'objet affiche les éléments ajoutés, celui-ci appelle la méthode toString() des objets ajoutés... Dans cet exemple, nous avons utilisé des objets String, mais essayez avec un autre objet et vous verrez...


Voici le nouveau code :

Code : Java -
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
 
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
 
 
public class Fenetre extends JFrame {
        
        private JPanel container = new JPanel();
        private JComboBox combo = new JComboBox();
        private JLabel label = new JLabel("Une ComboBox");
        
        public Fenetre(){
        
        this.setTitle("Animation");
        this.setSize(300, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
 
        container.setBackground(Color.white);
        container.setLayout(new BorderLayout());
        
        combo.setPreferredSize(new Dimension(100,20));
        combo.addItem("Option 1");
        combo.addItem("Option 2");
        combo.addItem("Option 3");
        combo.addItem("Option 4");
                
        JPanel top = new JPanel();
        top.add(label);
        top.add(combo);
        
        container.add(top, BorderLayout.NORTH);
        this.setContentPane(container);
        this.setVisible(true);            
        }
}


Et le résultat :

Vous pouvez utiliser le constructeur qui prend un tableau d'objets en paramètre afin de renseigner tous les éléments d'un coup !


Ceci est donc équivalent :

Code : Java -
1
2
String[] tab = {"Option 1", "Option 2", "Option 3", "Option 4"};
combo = new JComboBox(tab);


Vous pouvez pré un choix avec la méthode setSelectedIndex(int index). Vous avez aussi la possibilité de changer la couleur d'écriture, la couleur de fond, la police exactement comme un JLabel.

Maintenant que vous voyez comment fonctionne cet objet, nous allons voir comment communiquer avec lui.

L'interface ItemListener

Cette interface à une méthode à redéfinir. Celle-ci est appelée lorsqu'un élément a changé d'état !
Vu qu'un exemple est toujours plus éloquent, voici un code implémentant cette interface :

Code : Java -
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
 
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
 
 
public class Fenetre extends JFrame {
        
        private JPanel container = new JPanel();
        private JComboBox combo = new JComboBox();
        private JLabel label = new JLabel("Une ComboBox");
        
        public Fenetre(){
        
        this.setTitle("Animation");
        this.setSize(300, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
 
        container.setBackground(Color.white);
        container.setLayout(new BorderLayout());
               
        String[] tab = {"Option 1", "Option 2", "Option 3", "Option 4"};
        
        combo = new JComboBox(tab);
        //Ajout du listener
        combo.addItemListener(new ItemState());
        combo.setPreferredSize(new Dimension(100,20));
        combo.setForeground(Color.blue);
       
        JPanel top = new JPanel();
        top.add(label);
        top.add(combo);
        
        container.add(top, BorderLayout.NORTH);
        this.setContentPane(container);
        this.setVisible(true);            
        }
 
        /**
         * Classe interne implémentant l'interface ItemListener
         */
        class ItemState implements ItemListener{
 
                public void itemStateChanged(ItemEvent e) {
                        System.out.println("événement déclenché sur : " + e.getItem());
                }               
        }
        
}


Dans mon exemple, j'ai cliqué sur :
  • Option 2, puis
  • Option 3, puis
  • Option 4.


Ce qui me donne :


Vous voyez bien que lorsque vous cliquez sur une option non sélectionnée, notre objet change d'abord l'état de l'option précédente (l'état passe en DESELECTED) avant de changer l'état de l'option choisie (celle-ci passe à l'état SELECTED).
Vous pouvez donc suivre très facilement l'état de vos éléments grâce à cette interface ; cependant, pour plus de simplicité, nous utiliserons l'interface ActionListener pour récupérer l'option sélectionnée !

Voici un code implémentant cette interface :

Code : Java -
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
 
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
 
 
public class Fenetre extends JFrame {
        
        private JPanel container = new JPanel();
        private JComboBox combo = new JComboBox();
        private JLabel label = new JLabel("Une ComboBox");
        
        public Fenetre(){
        
        this.setTitle("Animation");
        this.setSize(300, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
 
        container.setBackground(Color.white);
        container.setLayout(new BorderLayout());
               
        String[] tab = {"Option 1", "Option 2", "Option 3", "Option 4"};
        
        combo = new JComboBox(tab);
        //Ajout du listener
        combo.addItemListener(new ItemState());
        combo.addActionListener(new ItemAction());
        combo.setPreferredSize(new Dimension(100,20));
        combo.setForeground(Color.blue);
       
        JPanel top = new JPanel();
        top.add(label);
        top.add(combo);
        
        container.add(top, BorderLayout.NORTH);
        this.setContentPane(container);
        this.setVisible(true);            
        }
 
        /**
         * Classe interne implémentant l'interface ItemListener
         */
        class ItemState implements ItemListener{
 
                public void itemStateChanged(ItemEvent e) {
                        System.out.println("ItemListener : événement déclenché sur : " + e.getItem());
                }               
        }
        
        class ItemAction implements ActionListener{
 
                public void actionPerformed(ActionEvent e) {
                        System.out.println("ActionListener : action sur " + combo.getSelectedItem());
                }               
        }
        
}


Et le résultat :



Vous constatez qu'avec une telle implémentation, nous pouvons récupérer l'option sur laquelle l'action a été produite. L'appel de la méthode getSelectedItem() retourne la valeur de l'option sélectionnée ; une fois ceci récupérée, nous allons pouvoir travailler avec notre liste !
Il y a d'autres méthodes pour récupérer le contenu d'une liste... Je vous invite à chercher ce genre d'information.
En effet, une information apprise par nos propres moyens s'oublie beaucoup moins vite que celle qu'on vous sert toute cuite sur un plateau...


Maintenant que nous savons comment récupérer les informations dans une liste, je vous invite à continuer notre animation.

Changer la forme de notre animation

Comme le titre l'indique, nous allons faire en sorte que notre animation ne se contente plus d'afficher un rond... Nous allons pouvoir choisir quelle forme nous voulons afficher !

Bien sûr, je ne vais pas vous faire réaliser toutes les formes possibles et imaginables... Je vous en fournis quelques-unes et, si le coeur vous en dit, ajoutez-en de votre composition !

Très bien : pour arriver à faire ceci, nous allons dynamiser un peu notre classe Panneau, celle-ci devra pouvoir peindre différentes forme selon notre bon vouloir.
Pour y parvenir, nous allons ajouter une variable d'instance de type String qui contiendra l'intitulé de la forme que nous souhaitons dessiner - appelons-la forme - et ajoutons un mutateur afin de pouvoir redéfinir cette variable.
Notre méthode paintComponent doit pouvoir dessiner la forme demandée ; ici, deux cas de figures se profilent :
  • soit nous intégrons les instructions if dans cette méthode et l'objet Graphics dessinera en fonction,
  • soit nous développons une méthode privée, appelée dans la méthode paintComponent, et qui dessinera la forme demandée.


J'ai l'habitude de procéder de la deuxième façon pour éviter les conditions à rallonges dans mes méthodes...
Faites toutefois attention lorsque vous faites ceci ! Il se peut que votre classe devienne énorme et que vous vous y perdiez ! Nous verrons, dans une partie traitant des design patterns, que lorsque votre code a des portions de code contenant beaucoup de conditions, il vaut mieux programmer une implémentation, mais nous n'en sommes pas encore là...


Nous allons donc développer une méthode privée, appelons-la draw(Graphics g), qui aura pour tâche de dessiner la forme voulue. Nous passerons l'objet Graphics utilisé dans la méthode paintComponent afin qu'elle puisse l'utiliser, et c'est dans cette méthode que nous mettrons nos conditions.

Je vous propose les formes suivantes :
  • le rond, forme par défaut,
  • le carré,
  • le triangle,
  • l'étoile (soyons fous).


Ce qui veut dire que notre liste contiendra ces choix, et le rond sera le premier !
Nous créerons aussi une implémentation d'ActionListener dans une classe interne pour gérer les actions sur notre liste ; je l'ai appelée FormeListener, c'est fou ce que je suis original...

Une fois n'est pas coutume, voici ce que vous devez obtenir :




Essayez de trouver comment faire ces formes... Il n'y a rien de compliqué, je vous assure ! Bon, l'étoile est peut-être un peu plus difficile que le reste, mais elle n'est pas insurmontable...



Et voilà le travail !
Vous avez vu qu'il n'y avait rien de sorcier ici. En fait, vu que vous avez l'habitude d'utiliser des objets graphiques et des implémentations d'interfaces, les choses vont s'accélérer car le principe reste le même pour tous les objets graphiques de base !

Bon, j'ai tout de même fait un léger topo et un mini-QCM...

Ce qu'il faut retenir

  • L'objet JComboBox est dans le package javax.swing.
  • Vous pouvez ajouter des éléments dans une liste avec la méthode addItem(Object obj).
  • Vous pouvez aussi instancier une liste avec un tableau de données.
  • L'interface ItemListener vous permet de gérer les états de vos éléments.
  • Vous pouvez aussi utiliser l'interface ActionListener.
  • La méthode getSelectedItem() retourne une variable de type Object, pensez donc à faire un cast ou utiliser la méthode toString() si les éléments sont de ce type.
Rien de bien méchant ici, vous êtes habitués à utiliser les objets swing et les interfaces...
Continuons notre petit tour parmi les objets du package javax.swing, alors ! En route vers : les cases à cocher !


0 comments to "LECON 307"

Post a Comment

Powered by Blogger.

About This Blog

Aller au debut de la page