Avant de commencer, nous allons nous familiariser avec cet objet dans un environnement vierge... Comme d'habitude

.
Créez donc un projet vide avec une classe contenant une méthode
main et une classe héritée de
JFrame.
Ceci fait, nous allons utiliser notre nouvel objet. Celui-ci peut être instancié avec un String en paramètre, ce paramètre servira de libellé à notre objet. Vu qu'il n'y a rien de compliqué à faire ceci, voici le code et le résultat :
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 | import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Fenetre extends JFrame {
private JPanel container = new JPanel();
private JCheckBox check1 = new JCheckBox("Case 1");
private JCheckBox check2 = new JCheckBox("Case 2");
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(check1);
top.add(check2);
container.add(top, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
}
}
|
Résultat :
Vous pouvez aussi cocher la case en appelant la méthode
setSelected(boolean bool) en lui passant
true.
Cet objet a, comme tous les autres, une multitude de méthodes afin de pouvoir travailler, je vous invite aussi à fouiner un peu...
Créez maintenant une implémentation de l'interface
ActionListener, vous connaissez bien la marche à suivre... Et contrôlez que votre objet est coché ou non avec la méthode
isSelected() qui retourne un booléen ; voici un code mettant en oeuvre cette demande :
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 | import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Fenetre extends JFrame {
private JPanel container = new JPanel();
private JCheckBox check1 = new JCheckBox("Case 1");
private JCheckBox check2 = new JCheckBox("Case 2");
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();
check1.addActionListener(new StateListener());
check2.addActionListener(new StateListener());
top.add(check1);
top.add(check2);
container.add(top, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
}
class StateListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
System.out.println("source : " + ((JCheckBox)e.getSource()).getText() + " - état : " + ((JCheckBox)e.getSource()).isSelected());
}
}
}
|
Résultat :
Ici, je me suis amusé à cocher et décocher mes cases. Rien de bien difficile ici, ça devient la routine...
Nous allons utiliser cet objet afin de faire en sorte que nos formes changent de taille et nous donnent un pseudo-effet de morphing...
Que nous faut-il pour arriver à cela ?
Déjà, la taille de notre forme est fixe, il faut changer ça ! Allez, hop... Une variable de type
int dans notre classe
Panneau, disons
drawSize, initialisée à
50.
Tout comme le déplacement, nous devons savoir quand augmenter ou réduire la taille de notre forme : nous utiliserons la même méthode que pour le déplacement.
Un deuxième booléen sera nécessaire pour savoir si le "
mode morphing" est activé ou non...
En ce qui concerne la taille, si on réduit (ou augmente) celle-ci d'une unité à chaque rafraîchissement, l'effet de morphing sera
ULTRA-RAPIDE. Donc, pour ralentir l'effet, nous allons utiliser une méthode qui va retourner
1 ou
0 selon le nombre de rafraîchissements. Ceci signifie que nous allons avoir besoin d'une variable pour dénombrer ceux-ci. Nous ferons une réduction (ou augmentation) tous les 10 tours !
Pour bien séparer les deux cas de figure, nous allons faire une deuxième méthode de dessin dans la classe
Panneau qui aura pour rôle de dessiner le morphing ; appelons-la
drawMorph(Graphics g).
Lorsque nous cocherons notre case à cocher, le morphing sera lancé, et inversement ! La classe
Panneau devra donc avoir un mutateur pour le booléen de morphing...
Cependant, dans notre classe
Fenetre, nous gérons la collision avec les bords... Mais en "
mode morphing", la taille de notre forme n'est plus la même... Donc, il va falloir gérer ce nouveau cas de figure dans notre méthode
go(). Notre classe
Panneau devra avoir un accesseur pour la taille actuelle de la forme...
Vous avez tous les éléments en main pour réussir ceci.
Voici ce que vous devriez obtenir (je n'ai mis que le rond et le triangle... mais ça fonctionnera avec toutes les formes) :
Voici les codes :
Secret (cliquez pour afficher)
Fichier Panneau.java
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 | import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class Panneau extends JPanel {
private int posX = -50;
private int posY = -50;
private int drawSize = 50;
//boolean pour le mode morphing et pour savoir si la taille doit réduire
private boolean morph = false, reduce = false;;
private String forme = "ROND";
//Le compteur de rafraîchissements
private int increment = 0;
public void paintComponent(Graphics g){
g.setColor(Color.white);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.red);
//Si le mode morphing est activé, on peint le morphing
if(this.morph)
drawMorph(g);
//sinon, mode normal
else
draw(g);
}
private void draw(Graphics g){
if(this.forme.equals("ROND")){
g.fillOval(posX, posY, 50, 50);
}
if(this.forme.equals("CARRE")){
g.fillRect(posX, posY, 50, 50);
}
if(this.forme.equals("TRIANGLE")){
int s1X = posX + 50/2;
int s1Y = posY;
int s2X = posX + 50;
int s2Y = posY + 50;
int s3X = posX;
int s3Y = posY + 50;
int[] ptsX = {s1X, s2X, s3X};
int[] ptsY = {s1Y, s2Y, s3Y};
g.fillPolygon(ptsX, ptsY, 3);
}
if(this.forme.equals("ETOILE")){
int s1X = posX + 50/2;
int s1Y = posY;
int s2X = posX + 50;
int s2Y = posY + 50;
g.drawLine(s1X, s1Y, s2X, s2Y);
int s3X = posX;
int s3Y = posY + 50/3;
g.drawLine(s2X, s2Y, s3X, s3Y);
int s4X = posX + 50;
int s4Y = posY + 50/3;
g.drawLine(s3X, s3Y, s4X, s4Y);
int s5X = posX;
int s5Y = posY + 50;
g.drawLine(s4X, s4Y, s5X, s5Y);
g.drawLine(s5X, s5Y, s1X, s1Y);
}
}
/**
* Méthode qui peint le morphing
* @param g
*/
private void drawMorph(Graphics g){
//On incrémente le tour
increment++;
//On regarde si on doit réduire ou non
if(drawSize >= 50)reduce = true;
if(drawSize <= 10)reduce = false;
if(reduce)
drawSize = drawSize - getUsedSize();
else
drawSize = drawSize + getUsedSize();
if(this.forme.equals("ROND")){
g.fillOval(posX, posY, drawSize, drawSize);
}
if(this.forme.equals("CARRE")){
g.fillRect(posX, posY, drawSize, drawSize);
}
if(this.forme.equals("TRIANGLE")){
int s1X = posX + drawSize/2;
int s1Y = posY;
int s2X = posX + drawSize;
int s2Y = posY + drawSize;
int s3X = posX;
int s3Y = posY + drawSize;
int[] ptsX = {s1X, s2X, s3X};
int[] ptsY = {s1Y, s2Y, s3Y};
g.fillPolygon(ptsX, ptsY, 3);
}
if(this.forme.equals("ETOILE")){
int s1X = posX + drawSize/2;
int s1Y = posY;
int s2X = posX + drawSize;
int s2Y = posY + drawSize;
g.drawLine(s1X, s1Y, s2X, s2Y);
int s3X = posX;
int s3Y = posY + drawSize/3;
g.drawLine(s2X, s2Y, s3X, s3Y);
int s4X = posX + drawSize;
int s4Y = posY + drawSize/3;
g.drawLine(s3X, s3Y, s4X, s4Y);
int s5X = posX;
int s5Y = posY + drawSize;
g.drawLine(s4X, s4Y, s5X, s5Y);
g.drawLine(s5X, s5Y, s1X, s1Y);
}
}
/**
* Méthode qui retourne le nombre à retrancher (ou ajouter) pour le morphing
* @return res
*/
private int getUsedSize(){
int res = 0;
//Si le nombre de tours est de 10
//On réinitialise l'incrément et on retourne 1
if(increment / 10 == 1){
increment = 0;
res = 1;
}
return res;
}
public int getDrawSize(){
return drawSize;
}
public boolean isMorph(){
return morph;
}
public void setMorph(boolean bool){
this.morph = bool;
//On réinitialise la taille
drawSize = 50;
}
public void setForme(String form){
this.forme = form;
}
public int getPosX() {
return posX;
}
public void setPosX(int posX) {
this.posX = posX;
}
public int getPosY() {
return posY;
}
public void setPosY(int posY) {
this.posY = posY;
}
}
|
Fichier Fenetre.java
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 | import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Fenetre extends JFrame{
private Panneau pan = new Panneau();
private JButton bouton = new JButton("Go");
private JButton bouton2 = new JButton("Stop");
private JPanel container = new JPanel();
private JLabel label = new JLabel("Choix de la forme");
private int compteur = 0;
private boolean animated = true;
private boolean backX, backY;
private int x,y ;
private Thread t;
private JComboBox combo = new JComboBox();
private JCheckBox morph = new JCheckBox("Morphing");
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);
bouton.addActionListener(new BoutonListener());
bouton2.addActionListener(new Bouton2Listener());
bouton2.setEnabled(false);
JPanel south = new JPanel();
south.add(bouton);
south.add(bouton2);
container.add(south, BorderLayout.SOUTH);
combo.addItem("ROND");
combo.addItem("CARRE");
combo.addItem("TRIANGLE");
combo.addItem("ETOILE");
combo.addActionListener(new FormeListener());
morph.addActionListener(new MorphListener());
JPanel top = new JPanel();
top.add(label);
top.add(combo);
top.add(morph);
container.add(top, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
}
private void go(){
x = pan.getPosX();
y = pan.getPosY();
while(this.animated){
//Si le mode morphing est activé, on utilise la taille actuelle de la forme
if(pan.isMorph())
{
if(x < 1)backX = false;
if(x > pan.getWidth() - pan.getDrawSize())backX = true;
if(y < 1)backY = false;
if(y > pan.getHeight() - pan.getDrawSize())backY = true;
}
//Sinon, comme d'habitude
else
{
if(x < 1)backX = false;
if(x > pan.getWidth()-50)backX = true;
if(y < 1)backY = false;
if(y > pan.getHeight()-50)backY = true;
}
if(!backX)pan.setPosX(++x);
else pan.setPosX(--x);
if(!backY) pan.setPosY(++y);
else pan.setPosY(--y);
pan.repaint();
try {
Thread.sleep(3);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class BoutonListener implements ActionListener{
public void actionPerformed(ActionEvent arg0) {
animated = true;
t = new Thread(new PlayAnimation());
t.start();
bouton.setEnabled(false);
bouton2.setEnabled(true);
}
}
class Bouton2Listener implements ActionListener{
public void actionPerformed(ActionEvent e) {
animated = false;
bouton.setEnabled(true);
bouton2.setEnabled(false);
}
}
class PlayAnimation implements Runnable{
public void run() {
go();
}
}
class FormeListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
pan.setForme(combo.getSelectedItem().toString());
}
}
class MorphListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
//Si la case est cochée, activation du mode morphing
if(morph.isSelected())pan.setMorph(true);
//Sinon, rien !
else pan.setMorph(false);
}
}
}
|
Alors ? Vous en pensez quoi ?
J'aime bien, moi...
Vous voyez que l'utilisation des
JCheckBox est très simple... Je vous propose maintenant d'aller voir un de ses cousins...
Le voici, le cousin éloigné...
Bon, alors : le principe est de pouvoir avoir deux (ou plus) choix distincts, mais qu'un seul soit sélectionné à la fois... C'est-à-dire que pour un choix
oui / non, le choix
oui étant présélectionné, lorsque nous choisirons
non, l'autre choix se désélectionnera tout seul...
L'instanciation se fait de la même manière que pour un
JCheckBox ; d'ailleurs, nous allons utiliser l'exemple du début de chapitre en remplaçant les cases à cocher par des boutons radio. Voici les codes et le résultat :
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 | import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class Fenetre extends JFrame {
private JPanel container = new JPanel();
private JRadioButton jr1 = new JRadioButton("Radio 1");
private JRadioButton jr2 = new JRadioButton("Radio 2");
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();
jr1.addActionListener(new StateListener());
jr2.addActionListener(new StateListener());
top.add(jr1);
top.add(jr2);
container.add(top, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
}
class StateListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
System.out.println("source : " + ((JRadioButton)e.getSource()).getText() + " - état : " + ((JRadioButton)e.getSource()).isSelected());
}
}
}
|
Résultat :
Vous pouvez voir que ces objets s'utilisent de la même manière.
Euh... Tu nous as dis que seul un choix devrait être sélectionné... Or ici, tes deux radios sont sélectionnés...
Tout à fait... Voilà la différence entre ces deux objets... Pour qu'un seul bouton radio soit sélectionné à la fois, nous devons définir un groupe de boutons,
ButtonGroup. Dans celui-ci, nous ajouterons nos boutons radio et ainsi seul un bouton sera sélectionné à la fois !
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 | import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class Fenetre extends JFrame {
private JPanel container = new JPanel();
private JRadioButton jr1 = new JRadioButton("Radio 1");
private JRadioButton jr2 = new JRadioButton("Radio 2");
private ButtonGroup bg = new ButtonGroup();
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();
jr1.setSelected(true);
jr1.addActionListener(new StateListener());
jr2.addActionListener(new StateListener());
bg.add(jr1);
bg.add(jr2);
top.add(jr1);
top.add(jr2);
container.add(top, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
}
class StateListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
System.out.println("source : " + jr1.getText() + " - état : " + jr1.isSelected());
System.out.println("source : " + jr2.getText() + " - état : " + jr2.isSelected());
}
}
}
|
Résultat :
Une précision, toutefois... Lorsque je vous ai dit que la différence entre ces composants se trouvait dans cette notion de groupe de boutons... Je vous ai un peu induits en erreur

.
En fait, j'ai dit ceci car il est plus fréquent d'avoir ce genre de chose sur des boutons de type radio que sur un autre, mais rien ne vous empêche de faire la même chose pour des cases à cocher...
Effectivement, l'objet
ButtonGroup accepte en paramètre un type
AbstractButton qui est la super-classe de tous les boutons... Vous pouvez donc en tirer les conclusions qui s'imposent !
- Les objets JCheckBox, JRadioButton et ButtonGroup sont dans le package javax.swing
- Vous pouvez savoir si un de ces composants est sélectionné grâce à la méthode isSelected().
- Cette méthode retourne true si l'objet est sélectionné, et false dans le cas contraire.
- Vous pouvez restreindre les choix dans un groupe de réponses en utilisant la classe ButtonGroup.
- Vous pouvez ajouter des boutons à un groupe de boutons grâce à la méthode add(AbstractButton button).
Allez... Pas besoin de QCM ici... Il n'y a rien de compliqué !
Je sens que vous êtes de plus en plus à l'aise avec la programmation événementielle !
Continuons donc avec : les zones de texte.