Tout est dans le titre !

Afin de gérer les différentes actions à effectuer selon le bouton sur lequel on clique, nous allons utiliser l'interface
ActionListener.
Cependant, nous n'allons pas implémenter cette dernière dans notre classe
Bouton, mais dans notre classe
Fenetre... Le but étant de faire en sorte que lorsque nous cliquons sur notre bouton, il se passe quelque chose dans notre application comme changer un état, une variable, faire une incrémentation... Enfin n'importe quelle action !
Comme je vous l'ai expliqué dans la partie précédente, lorsque nous faisons
addMouseListener, nous prévenons l'objet observé qu'un objet doit être mis au courant ! Ici, nous voulons que ce soit notre application, notre
Fenetre, qui écoute notre
Bouton, le but final étant de pouvoir lancer ou d'arrêter l'animation de notre
Panneau.
Avant d'en arriver là, nous allons faire plus simple. Nous allons voir dans un premier temps l'implémentation de l'interface
ActionListener. Afin de vous montrer toute la puissance de cette interface, nous allons utiliser un nouvel objet présent dans le package
javax.swing : le
JLabel.
Cet objet est en fait comme une étiquette, il est spécialisé dans l'affichage de texte ou d'image... Il est donc parfait pour notre premier exemple !
Pour l'instanciation ou l'initialisation, il fonctionne un peu comme le
JButton, voyez plutôt :
Code : Java1
2
3
4 | JLabel label1 = new JLabel();
label1.setText("mon premier JLabel");
//Ou encore
JLabel label2 = new JLabel("Mon deuxième JLabel");
|
Créez une variable d'instance de type
JLabel - appelons-la
label - initialisez-la avec le texte qui vous plaît, puis ajoutez-la avec votre
contentPane en
BorderLayout.NORTH.
Voici le résultat :
Et le 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 | public class Fenetre extends JFrame {
private Panneau pan = new Panneau();
private Bouton bouton = new Bouton("mon bouton");
private JPanel container = new JPanel();
private JLabel label = new JLabel("Le JLabel");
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());
container.add(pan, BorderLayout.CENTER);
container.add(bouton, BorderLayout.SOUTH);
container.add(label, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
go();
}
//...
}
|
Vous pouvez voir le texte en haut à gauche... L'alignement par défaut de cet objet est à gauche mais vous pouvez changer quelques paramètres, comme :
- l'alignement
- la police à utiliser
- la couleur de police
- ...
Voilà un code qui met tout ceci en pratique, et son aperçu.
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 | 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());
container.add(pan, BorderLayout.CENTER);
container.add(bouton, BorderLayout.SOUTH);
//Définition d'une police d'écriture
Font police = new Font("Tahoma", Font.BOLD, 16 );
//On applique celle-ci aux JLabel
label.setFont(police);
//On change la couleur de police
label.setForeground(Color.blue);
//Et on change l'alignement du texte grâce aux attributs static de la classe JLabel
label.setHorizontalAlignment(JLabel.CENTER);
container.add(label, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
go();
}
|
Aperçu :
Maintenant que notre étiquette est exactement comme nous le voulons, nous allons pouvoir implémenter l'interface
ActionListener.
Lorsque vous avez implémenté les méthodes de l'interface, vous vous apercevez que celle-ci n'en contient qu'une seule !
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 | import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Fenetre extends JFrame implements ActionListener{
private Panneau pan = new Panneau();
private Bouton bouton = new Bouton("mon bouton");
private JPanel container = new JPanel();
private JLabel label = new JLabel("Le JLabel");
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());
container.add(pan, BorderLayout.CENTER);
container.add(bouton, BorderLayout.SOUTH);
//Définition d'une police d'écriture
Font police = new Font("Tahoma", Font.BOLD, 16 );
//On applique celle-ci aux JLabel
label.setFont(police);
//On change la couleur de police
label.setForeground(Color.blue);
//Et on change l'alignement du texte grâce aux attributs static de la classe JLabel
label.setHorizontalAlignment(JLabel.CENTER);
container.add(label, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
go();
}
//...
//*******************************************************************************
// LA VOILAAAAAAAAAAAAAA
//*******************************************************************************
/**
* C'est la méthode qui sera appelée lors d'un clic sur notre bouton
*/
public void actionPerformed(ActionEvent arg0) {
}
}
|
Nous allons maintenant prévenir notre objet
Bouton que notre objet
Fenetre l'écoute ! Vous l'avez deviné, nous ajoutons notre objet
Fenetre à la liste des objets qui écoutent notre
Bouton grâce à la méthode
addActionListener(ActionListener obj) invoquée sur la variable
bouton. Ajoutez cette instruction dans le constructeur, en passant
this en paramètre (c'est notre
Fenetre qui écoute notre bouton...).
Une fois ceci fait, nous allons changer le texte de notre
JLabel dans la méthode
actionPerformed ; en fait, nous allons compter combien de fois on clique sur notre bouton... Pour cela, nous ajoutons une variable d'instance de type
int dans notre classe : appelons-la
compteur. Dans la méthode
actionPerformed, nous allons incrémenter ce compteur et afficher son contenu dans notre étiquette.
Voici le code de notre objet mis à jour :
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 | import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Fenetre extends JFrame implements ActionListener{
private Panneau pan = new Panneau();
private Bouton bouton = new Bouton("mon bouton");
private JPanel container = new JPanel();
private JLabel label = new JLabel("Le JLabel");
/**
* Compteur de clics !
*/
private int compteur = 0;
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());
container.add(pan, BorderLayout.CENTER);
//On ajoute notre Fenetre à la liste des auditeurs de notre Bouton
bouton.addActionListener(this);
container.add(bouton, BorderLayout.SOUTH);
//Définition d'une police d'écriture
Font police = new Font("Tahoma", Font.BOLD, 16 );
//On applique celle-ci aux JLabel
label.setFont(police);
//On change la couleur de police
label.setForeground(Color.blue);
//Et on change l'alignement du texte grâce aux attributs static de la classe JLabel
label.setHorizontalAlignment(JLabel.CENTER);
container.add(label, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
go();
}
private void go(){
//Les coordonnées de départ de notre rond
int x = pan.getPosX(), y = pan.getPosY();
//Le booléen pour savoir si on recule ou non sur l'axe X
boolean backX = false;
//Le booléen pour savoir si on recule ou non sur l'axe Y
boolean backY = false;
//Pour cet exemple, j'utilise une boucle while
//Vous verrez qu'elle fonctionne très bien
while(true){
//Si la coordonnée x est inférieure à 1, on avance
if(x < 1)backX = false;
//Si la coordonnée x est supérieure à la taille du Panneau
//moins la taille du rond on avance
if(x > pan.getWidth()-50)backX = true;
//idem pour l'axe Y
if(y < 1)backY = false;
if(y > pan.getHeight()-50)backY = true;
//Si on avance, on incrémente la coordonnée
if(!backX)
pan.setPosX(++x);
//Sinon on décrémente
else
pan.setPosX(--x);
//Idem pour l'axe Y
if(!backY)
pan.setPosY(++y);
else
pan.setPosY(--y);
//On redessine notre Panneau
pan.repaint();
//Comme on dit : la pause s'impose ! Ici, 3 centièmes de secondes
try {
Thread.sleep(3);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//*******************************************************************************
// LA VOILAAAAAAAAAAAAAA
//*******************************************************************************
/**
* C'est la méthode qui sera appelée lors d'un clic sur notre bouton
*/
public void actionPerformed(ActionEvent arg0) {
//Lorsque nous cliquons sur notre bouton, on met à jour le JLabel
this.compteur++;
label.setText("Vous avez cliqué " + this.compteur + " fois");
}
}
|
Et le résultat :
On commence à faire du sérieux, là ! !

Mais attendez, on ne fait que commencer... Eh oui ! Nous allons maintenant ajouter un deuxième bouton à notre
Fenetre, à côté de notre premier bouton (vous êtes libres d'utiliser la classe personnalisée ou un
JButton) ! Personnellement, je vais utiliser des boutons normaux maintenant ; en effet, la façon dont on écrit le nom de notre bouton, dans notre classe personnalisée, n'est pas assez souple et donc l'affichage peut être décevant...
Bref, nous avons maintenant deux boutons écoutés par notre objet
Fenetre.
Vous devez créer un deuxième JPanel qui va contenir nos deux boutons et insérer celui-ci dans le contentPane en BorderLayout.SOUTH.
Si vous tentez de mettre deux composants au même endroit avec un BorderLayout, seul le dernier composant ajouté apparaîtra ! Eh oui, le composant prend toute la place dans un BorderLayout !
Voilà notre 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
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
67
68
69
70
71
72
73
74
75
76 | import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Fenetre extends JFrame implements ActionListener{
private Panneau pan = new Panneau();
private JButton bouton = new JButton("bouton 1");
private JButton bouton2 = new JButton("bouton 2");
private JPanel container = new JPanel();
private JLabel label = new JLabel("Le JLabel");
/**
* Compteur de clics !
*/
private int compteur = 0;
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());
container.add(pan, BorderLayout.CENTER);
//On ajoute notre Fenetre à la liste des auditeurs de notre Bouton
bouton.addActionListener(this);
bouton2.addActionListener(this);
JPanel south = new JPanel();
south.add(bouton);
south.add(bouton2);
container.add(south, BorderLayout.SOUTH);
//Définition d'une police d'écriture
Font police = new Font("Tahoma", Font.BOLD, 16 );
//On applique celle-ci aux JLabel
label.setFont(police);
//On change la couleur de police
label.setForeground(Color.blue);
//Et on change l'alignement du texte grâce aux attributs static de la classe JLabel
label.setHorizontalAlignment(JLabel.CENTER);
container.add(label, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
go();
}
//...
//*******************************************************************************
// LA VOILAAAAAAAAAAAAAA
//*******************************************************************************
/**
* C'est la méthode qui sera appelée lors d'un clic sur notre bouton
*/
public void actionPerformed(ActionEvent arg0) {
//Lorsque nous cliquons sur notre bouton, on met à jour le JLabel
this.compteur++;
label.setText("Vous avez cliqué " + this.compteur + " fois");
}
}
|
Et le résultat :
Le problème maintenant est :
comment faire faire deux choses différentes dans la méthode actionPerformed ?
En effet ! Si nous laissons la méthode
actionPerformed telle qu'elle est, les deux boutons auront la même action lorsque nous cliquerons dessus. Essayez, et vous verrez !
Il existe un moyen de savoir qui a déclenché l'événement, en utilisant l'objet passé en paramètre dans la méthode
actionPerformed. Nous allons utiliser la méthode
getSource() de cet objet pour connaître le nom de l'instance qui a généré l'événement.
Testez la méthode
actionPerformed suivante, et voyez le résultat :
Code : Java1
2
3
4
5
6
7
8 | public void actionPerformed(ActionEvent arg0) {
if(arg0.getSource() == bouton)
label.setText("Vous avez cliqué sur le bouton 1");
if(arg0.getSource() == bouton2)
label.setText("Vous avez cliqué sur le bouton 2");
}
|
Résultat :
Vous pouvez constater que notre code fonctionne très bien ! Mais cette approche n'est pas très orientée objet... Si vous avez une multitude de boutons sur votre IHM... vous allez avoir une méthode
actionPerformed très chargée !
Nous pourrions créer deux objets à part, chacun écoutant un bouton, dont le rôle serait de faire un traitement précis par bouton... Cependant, si dans nos traitements nous avons besoin de modifier des données internes à la classe contenant nos boutons, il faudrait passer ces données (ou objets) à cet objet... Pas terrible non plus.
On commence à te connaître, maintenant ! Tu as une idée derrière la tête...
Je suis démasqué !
Il existe en Java un type de classe particulière. Voyons ça tout de suite !