Réponses aux questions d'analyse du code :
java.lang.Math. Elle génère un nombre pseudo-aléatoire de type double compris entre 0.0 et 1.0. Elle est utilisée ici pour définir aléatoirement la position et la couleur des confettis.Confettis est définie en "global" (attribut de classe) pour qu'elle soit visible par toutes les méthodes de la classe, notamment la méthode paint(). Si elle était déclarée localement dans le main, la méthode paint ne pourrait pas y accéder pour dessiner l'objet.this fait référence à l'instance courante de l'objet. Il est utilisé pour distinguer l'attribut de la classe (this.nombre) du paramètre du constructeur (nombre) quand ils ont le même nom.decoration(g) est appelée sans préfixe car elle est définie dans la classe LanceConfettis elle-même. À l'inverse, conf1.dessine(g) doit être préfixée par l'objet conf1 car la méthode dessine appartient à la classe Confettis.Question 2 (Surcharge) : Nous avons créé un second constructeur dans la classe Confettis acceptant deux paramètres (nombre et type). Cela permet de créer des objets de différentes manières. La surcharge offre donc plus de souplesse à l'initialisation.
// Second constructeur (Surcharge)
public Confettis(int nombre, int type)
{
this.nombre = nombre;
this.type = type;
}
Question 3 (Affichage console) : Nous avons ajouté des affichages dans la méthode paint. À cette étape, la variable compteur est toujours déclarée en static.
On constate que le compteur est partagé : il cumule les valeurs de toutes les instances.
Question 4 (Retrait du static) : Nous avons retiré le mot-clé static de la variable compteur dans la classe Confettis.
Déduction : Les variables static (de classe) sont partagées par toutes les instances (mémoire commune). En retirant static, la variable devient une variable d'instance : chaque objet possède sa propre copie indépendante.
Modifications finales :
String arg[] du main. Les valeurs sont converties en entiers via Integer.parseInt() pour définir le nombre de confettis au lancement (ex: java LanceConfettis 300 50).Math.random() * 4 casté en int pour attribuer aléatoirement un type (0, 1, 2 ou 3) à l'instance.
import java.awt.*;
import javax.swing.*;
class LanceConfettis extends JFrame
{
// Variables globales
static Confettis conf1, conf2;
public LanceConfettis()
{
super("C'est la joie !");
setSize(500, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void paint(Graphics g)
{
super.paint(g);
decoration(g);
conf1.dessine(g);
conf2.dessine(g);
// Affichage console (Question 3)
System.out.println("Instance 1 -> Type: " + conf1.type + " | Nombre: " + conf1.nombre);
System.out.println("Instance 2 -> Type: " + conf2.type + " | Nombre: " + conf2.nombre);
}
public void decoration(Graphics g)
{
g.setColor(Color.orange);
g.fillArc(-50, -50, 300, 300, 250, 45);
g.setColor(Color.magenta);
g.fillOval(100, 215, 60, 40);
g.fillOval(145, 220, 60, 40);
g.setColor(Color.orange);
g.fillOval(120, 227, 20, 16);
g.setColor(Color.white);
g.fillOval(165, 232, 20, 16);
g.setColor(Color.black);
g.drawOval(56, 185, 24, 6);
}
public static void main (String arg[])
{
// Question 5 : Gestion des arguments
int n1 = 100; // Valeur par défaut
int n2 = 100;
if (arg.length >= 2) {
n1 = Integer.parseInt(arg[0]);
n2 = Integer.parseInt(arg[1]);
}
// Question 6 : Type aléatoire pour le constructeur 1
conf1 = new Confettis(n1);
// Question 2 : Utilisation du constructeur surchargé
conf2 = new Confettis(n2, 1);
new LanceConfettis();
}
}
import java.awt.*;
class Confettis
{
int type = 0, nombre;
// Question 4 : Retrait du static
int compteur = 0;
// Constructeur 1 : Type aléatoire (Question 6)
public Confettis(int nombre)
{
this.nombre = nombre;
// Choix aléatoire du type entre 0 et 3
this.type = (int)(Math.random() * 4);
}
// Constructeur 2 : Surcharge (Question 2)
public Confettis(int nombre, int type)
{
this.nombre = nombre;
this.type = type;
}
public void dessine(Graphics gr)
{
for (int i=0; i < nombre; i++)
{
compteur++;
gr.setColor(new Color((int) (Math.random()*256),
(int) (Math.random()*256),
(int) (Math.random()*256)));
if (type==0) gr.fillOval((int) (Math.random()*500), (int) (Math.random()*300), 5, 5);
else if (type==1) gr.fillRect((int) (Math.random()*500), (int) (Math.random()*300), 5, 5);
else if (type==2) gr.drawArc((int) (Math.random()*500), (int) (Math.random()*300), 10, 10, 0, 45);
else if (type==3) gr.drawArc((int) (Math.random()*500), (int) (Math.random()*300), 10, 50, (int) (Math.random()*360), 135);
try { Thread.sleep(5); } catch(InterruptedException e) { }
}
}
}