Objectif du TD : Réaliser un programme Java capable de générer et d'afficher aléatoirement des poèmes basés sur l'œuvre de Raymond Queneau, Cent mille milliards de poèmes. Le programme doit lire un fichier texte, stocker les vers en mémoire et les afficher graphiquement en respectant la structure du sonnet.
Analyse de la structure du fichier Queneau.txt :
Calcul combinatoire :
Pour chaque ligne du poème, nous avons 10 choix possibles. Comme il y a 14 lignes indépendantes, le nombre total de combinaisons est :
10 × 10 × 10 ... (14 fois) = 1014
Cela correspond exactement au titre de l'œuvre : Cent mille milliards de poèmes.
Stockage en mémoire (Tableau 2D) :
Pour gérer efficacement ces données et permettre un accès aléatoire instantané (nécessaire pour la partie graphique), nous ne pouvons pas relire le fichier à chaque clic. Nous stockons donc tout le texte dans un tableau à deux dimensions de chaînes de caractères :
Déclaration Java : String tableau[][] = new String[14][10];
Ce code lit le fichier, ignore les lignes vides et les titres, et remplit le tableau structuré.
import java.io.*;
class AccesFichier
{
// Tableau pour stocker les 140 vers (14 blocs de 10)
String tableau[][] = new String[14][10];
public AccesFichier()
{
try
{
FileReader fic = new FileReader("Queneau.txt");
BufferedReader buf = new BufferedReader(fic);
String chaine;
int bloc = -1; // Indice du bloc (0-13)
int vers = 0; // Indice du vers dans le bloc (0-9)
while ((chaine = buf.readLine()) != null)
{
// Si la ligne contient "Vers", on change de bloc
if (chaine.startsWith("Vers")) {
bloc++;
vers = 0;
}
// Si c'est un vers valide (contient du texte et on est dans un bloc)
else if (chaine.length() > 5 && bloc >= 0 && bloc < 14) {
// Nettoyage éventuel des numéros (ex: "1. Le roi...")
tableau[bloc][vers] = chaine;
vers++;
}
}
fic.close();
}
catch (IOException e) {
System.out.println("Erreur lecture : " + e);
}
}
// Accesseur pour fournir les données à l'interface graphique
public String[][] getTableau() {
return tableau;
}
public static void main(String argv[]) {
new AccesFichier();
}
}
Logique de l'algorithme :
AccesFichier.actionPerformed qui appelle repaint().i, on tire un nombre aléatoire r entre 0 et 9.tableau[i][r].
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class LancePoeme extends JFrame implements ActionListener
{
JButton bouton;
AccesFichier fichier;
String[][] poemeData; // Référence vers le tableau 2D
public LancePoeme()
{
super("Poésie automatique");
setSize(500, 500);
// 1. Chargement des données
fichier = new AccesFichier();
poemeData = fichier.getTableau();
// 2. Interface
bouton = new JButton("Afficher un nouveau poème");
add(bouton, "North");
bouton.addActionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
// Déclencheur du rafraîchissement
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bouton) {
repaint(); // Force l'appel à paint()
}
}
public void paint(Graphics g)
{
super.paintComponents(g); // Nettoie le fond
// Titre
g.setFont(new Font("Helvetica", Font.BOLD, 20));
g.drawString("Cent mille milliards de poèmes", 60, 90);
// Corps du poème
g.setFont(new Font("Helvetica", Font.PLAIN, 13));
int y = 125; // Ordonnée de départ
// Boucle sur les 14 vers
for (int i = 0; i < 14; i++) {
// Logique aléatoire : choix entre 0 et 9
int choix = (int)(Math.random() * 10);
// Récupération sécurisée
if (poemeData[i][choix] != null) {
// Suppression des numéros "1. " si présents dans le fichier
String vers = poemeData[i][choix].replaceAll("^\\d+\\.\\s*", "");
g.drawString(vers, 60, y);
}
y += 15; // Interligne standard
// Gestion des strophes (4 - 4 - 3 - 3)
// Ajout d'espace après le 4ème, 8ème et 11ème vers
if (i == 3 || i == 7 || i == 10) {
y += 15;
}
}
// Auteur
g.setFont(new Font("Helvetica", Font.BOLD, 20));
g.drawString("Raymond Queneau", 150, 430);
}
public static void main(String argv[])
{
new LancePoeme();
}
}