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...
Voici les codes :
Secret (cliquez pour afficher)
La classe
Panneau
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 | 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 String forme = "ROND";
public void paintComponent(Graphics g){
//On décide d'une couleur de fond pour notre rectangle
g.setColor(Color.white);
//On dessine celui-ci afin qu'il prenne toute la surface
g.fillRect(0, 0, this.getWidth(), this.getHeight());
//On redéfinit une couleur pour notre rond
g.setColor(Color.red);
//On délègue la méthode de dessin à la méthode draw()
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")){
//calcul des sommets
//Le sommet 1 est à la moitié du côté supérieur du carré de 50
int s1X = posX + 25;
int s1Y = posY;
//Le sommet deux est en bas à droite
int s2X = posX + 50;
int s2Y = posY + 50;
//Le sommet Trois en bas à gauche
int s3X = posX;
int s3Y = posY + 50;
// Nous créons deux tableaux de coordonnées
int[] ptsX = {s1X, s2X, s3X};
int[] ptsY = {s1Y, s2Y, s3Y};
//Et nous utilisons la méthode fillPolygon
g.fillPolygon(ptsX, ptsY, 3);
}
if(this.forme.equals("ETOILE")){
//Pour l'étoile, je me contente de tracer des lignes
//dans le carré correspondant à peu près à une étoile...
//Mais ce code peut être amélioré !
int s1X = posX + 25;
int s1Y = posY;
int s2X = posX + 50;
int s2Y = posY + 50;
g.drawLine(s1X, s1Y, s2X, s2Y);
int s3X = posX;
int s3Y = posY + 17;
g.drawLine(s2X, s2Y, s3X, s3Y);
int s4X = posX + 50;
int s4Y = posY + 17;
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);
}
}
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;
}
}
|
La classe
Fenetre
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 | import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JButton;
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();
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());
JPanel top = new JPanel();
top.add(label);
top.add(combo);
container.add(top, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
}
private void go(){
x = pan.getPosX();
y = pan.getPosY();
while(this.animated){
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) {
e.printStackTrace();
}
}
}
/**
* classe qui écoute notre bouton
*/
public class BoutonListener implements ActionListener{
/**
* Redéfinitions de la méthode actionPerformed
*/
public void actionPerformed(ActionEvent arg0) {
animated = true;
t = new Thread(new PlayAnimation());
t.start();
bouton.setEnabled(false);
bouton2.setEnabled(true);
}
}
/**
* classe qui écoute notre bouton2
*/
class Bouton2Listener implements ActionListener{
/**
* Redéfinitions de la méthode actionPerformed
*/
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) {
//la méthode retourne un Object puisque nous passons des Object dans une liste
//Il faut donc utiliser la méthode toString() pour retourner un String (ou utiliser un cast)
pan.setForme(combo.getSelectedItem().toString());
}
}
}
|
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...