Ce chapitre présente la création d’interfaces graphiques en Java à l’aide de **Swing**, la bibliothèque standard pour réaliser des fenêtres, des boutons, des zones de dessin ou des interfaces interactives. Swing est largement utilisé en pédagogie pour comprendre : - la **structure d'une fenêtre**, - les **composants graphiques**, - le **dessin personnalisé**, - la **gestion des interactions utilisateur** (événements), - la boucle de **rafraîchissement graphique** # 🟧 1. Créer une fenêtre avec Swing (`JFrame`) Une interface graphique commence par une **fenêtre**, représentée par la classe `JFrame`. ```java import javax.swing.JFrame; public class Fenetre extends JFrame { public Fenetre() { setTitle("Ma première fenêtre"); setSize(600, 400); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true) } } ``` ### ✔ Explications - `setTitle` → nom affiché dans la barre de titre - `setSize` → largeur / hauteur - `setDefaultCloseOperation(EXIT_ON_CLOSE)` → arrêt du programme à la fermeture - `setVisible(true)` → rend la fenêtre visible ### ✔ Lancer l’interface ```java public class Main { public static void main(String[] args) { new Fenetre(); } } ``` # 🟧 2. Les composants graphiques Swing Une interface graphique est constituée de **composants** ajoutés dans la fenêtre (`JFrame`) ou dans des panneaux (`JPanel`). Voici les composants les plus fréquemment utilisés : ## ✔ Boutons (`JButton`) `# 🟧 X. Les composants graphiques Swing Une interface graphique est constituée de **composants** ajoutés dans la fenêtre (`JFrame`) ou dans des panneaux (`JPanel`). Voici les composants les plus fréquemment utilisés : ## ✔ Boutons (`JButton`) ```java JButton b = new JButton("Clique !"); add(b); ``` ## ✔ Labels (`JLabel`) ```java JLabel titre = new JLabel("Bonjour !"); add(titre); ``` ## ✔ Champs texte (`JTextField`) ```java JTextField champ = new JTextField(15); add(champ); ``` ## ✔ Zones de texte (`JTextArea`) ```java JTextArea desc = new JTextArea(5, 20); add(desc); ``` 📌 Tous ces composants doivent être insérés dans un conteneur (fenêtre ou panneau). JButton b = new JButton("Clique !"); # 🟦 3. Ajouter un panneau de dessin (`JPanel`) Un `JPanel` est une zone dans laquelle on peut **dessiner** ou **afficher des éléments graphiques personnalisés**. ```java import javax.swing.JPanel; import java.awt.Graphics; public class Panneau extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("Hello Java !", 20, 20); g.fillRect(50, 50, 100, 60); g.drawOval(200, 100, 80, 80); } } ``` ### ✔ Points importants - `paintComponent()` est appelée **automatiquement** à chaque rafraîchissement - `Graphics g` sert de crayon pour dessiner - Toutes les formes géométriques de base sont disponibles ### ✔ Ajouter ce panneau dans la fenêtre ```java public class Fenetre extends JFrame { public Fenetre() { setTitle("Dessin"); setSize(600, 400); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); add(new Panneau()); setVisible(true); } } ``` # 🟦 4. Organisation des composants : les Layouts Un **layout** définit la manière dont les composants s’organisent dans une fenêtre. → Il s’agit d’un gestionnaire de positionnement. ### 🎯 Pourquoi un layout ? - éviter de positionner les composants manuellement - adapter automatiquement l’interface aux tailles d’écran - gérer les redimensionnements correctement ## ✔ 1. `FlowLayout` (le plus simple) Les composants s’affichent **à la suite**, comme du texte. ```java setLayout(new FlowLayout()); add(new JButton("A")); add(new JButton("B")); add(new JButton("C")); ``` ## ✔ 2. `BorderLayout` Division en 5 zones : - NORTH - SOUTH - EAST - WEST - CENTER ```java setLayout(new BorderLayout()); add(new JButton("Haut"), BorderLayout.NORTH); add(new JButton("Centre"), BorderLayout.CENTER); ``` Très utilisé pour : - menus, barres d’outils, zones de dessin… ## ✔ 3. `GridLayout` Tous les éléments ont la même taille. ```java setLayout(new GridLayout(2, 3)); // 2 lignes, 3 colonnes ``` ## ✔ 4. `BoxLayout` ```java setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); ``` ## ✔ 5. `null layout` ```java setLayout(null); bouton.setBounds(50, 100, 150, 30); ``` # 🟩 Exemple complet ```java public class Fenetre extends JFrame { public Fenetre() { setTitle("Exemple Layout"); setSize(400, 300); setDefaultCloseOperation(EXIT_ON_CLOSE); setLayout(new BorderLayout()); add(new JLabel("Titre", JLabel.CENTER), BorderLayout.NORTH); JPanel centre = new JPanel(); centre.setLayout(new FlowLayout()); centre.add(new JButton("1")); centre.add(new JButton("2")); centre.add(new JButton("3")); add(centre, BorderLayout.CENTER); setVisible(true); } } ``` # 🟪 5. Panneaux personnalisés (`JPanel`) Un **panneau personnalisé** (sous-classe de `JPanel`) permet d’afficher un dessin, une animation, une simulation ou tout élément graphique spécifique. Cette technique est centrale en Java pour créer : - des jeux 2D, - des interfaces avancées, - des visualisations, - des tableaux de bord, - des zones d'affichage interactives. ## ✔ 1. Créer un panneau personnalisé On crée une classe qui **hérite** de `JPanel` et on redéfinit la méthode `paintComponent`. ```java import javax.swing.JPanel; import java.awt.Graphics; public class Panneau extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); // nettoie le fond // Exemple de dessin g.drawString("Bonjour Swing !", 20, 20); g.fillRect(50, 50, 100, 50); g.drawOval(200, 80, 80, 80); } } ``` ### 📝 À retenir - **`paintComponent` est appelée automatiquement** par Swing lorsqu’un rafraîchissement est nécessaire. - Il est essentiel d’appeler `super.paintComponent(g)` pour éviter les artefacts graphiques. - La classe `Graphics` est votre "crayon" pour dessiner. ## ✔ 2. Ajouter le panneau personnalisé à la fenêtre ```java public class Fenetre extends JFrame { public Fenetre() { setTitle("Dessin personnalisé"); setSize(600, 400); Panneau p = new Panneau(); add(p); setVisible(true); } } ``` Le panneau devient le **contenu principal** de la fenêtre. ## ✔ 3. Stocker un état interne dans le panneau Un panneau n’est pas seulement un dessin : c’est un **objet** qui possède un état. ```java public class Panneau extends JPanel { private int x = 50; public void paintComponent(Graphics g) { super.paintComponent(g); g.fillOval(x, 100, 40, 40); } public void avancer() { += 5; } } ``` Au lieu d’un dessin figé, on obtient un composant **vivant**, capable d’évoluer. ## ✔ 4. Relier un `JPanel` personnalisé à un bouton Exemple : déplacer le dessin lorsqu’on clique sur un bouton. ## ✔ 6. Animation continue avec `Timer` Pour une animation automatique (comme un poisson qui nage) : `Timer timer = new Timer(30, e -> { p.avancer(); p.repaint(); }); timer.start();` - 30 ms → environ 33 images par seconde - l’appel régulier de `repaint()` crée l’illusion du mouvement C’est la **boucle de jeu** des projets Java. --- ## ✔ 7. Interaction clavier + panneau personnalisé Pour contrôler un objet avec le clavier : `p.setFocusable(true); p.addKeyListener(new KeyListener() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_RIGHT) p.avancer(); p.repaint(); } });` # 🟩 6. Gestion des événements (clavier, souris) Pour rendre l’interface **interactive**, on utilise des _listeners_ (écouteurs). ## 🔵 6.1. Événements clavier (`KeyListener`) ```java import java.awt.event.KeyEvent; import java.awt.event.KeyListener; public class Clavier implements KeyListener { public void keyPressed(KeyEvent e) { System.out.println("Touche : " + e.getKeyCode()); } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } } ``` ### Lier l’écouteur à un composant : ```java addKeyListener(new Clavier()); ``` ## 🔵 6.2. Événements souris (`MouseListener`) ```java import java.awt.event.MouseEvent; import java.awt.event.MouseListener; public class Souris implements MouseListener { public void mousePressed(MouseEvent e) { System.out.println("Clique à : " + e.getX() + ", " + e.getY()); } public void mouseReleased(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } } ``` # 🟪 7. Rafraîchissement de l’affichage avec un **Thread** Pour animer un dessin, il faut **mettre à jour régulièrement l’état** puis **redessiner** la zone graphique. 👉 En Java, on crée donc **un thread dédié**, chargé de : 1. modifier l’état interne de l’objet, 2. appeler `repaint()`, 3. attendre quelques millisecondes, 4. recommencer ## ✔ Exemple : animation automatique avec un thread Voici la version correcte conforme à ton cours : ```java public class Panneau extends JPanel implements Runnable { private int x = 0; // état interne du panneau public Panneau() { Thread t = new Thread(this); t.start(); // lancement de la boucle d'animation } public void run() { try { while (true) { x++; // mise à jour de l'état repaint(); // redessiner le panneau Thread.sleep(30); // pause 30 ms ≈ 33 FPS } }catch (InterruptedException e) { e.printStackTrace(); } } public void paintComponent(Graphics g) { super.paintComponent(g); g.fillOval(x, 100, 40, 40); // dessin lié à l'état } } ``` ### 🔍 Explications - **`run()` est la boucle d’animation**. - Le thread tourne en continu tant que la fenêtre est ouverte. - `Thread.sleep(30)` règle la **vitesse d’animation**. - `repaint()` demande à Swing de rappeler `paintComponent()`. # 🟫 8. Interface = fenêtre + composants + logique Un programme graphique Java repose sur l’association de trois éléments : ### ✔ 1. La **fenêtre** (`JFrame`) Structure générale de l’interface. ### ✔ 2. Les **composants** (`JPanel`, `JButton`, `JLabel`, etc.) Zones de dessin, boutons, texte, champs… ### ✔ 3. La **logique applicative** - dessin - réaction aux événements - calculs - rafraîchissement Ces trois couches doivent être bien séparées pour obtenir un code clair. --- # 🟧 9. Exemple complet ```java public class Fenetre extends JFrame { public Fenetre() { setTitle("Demo"); setSize(500, 300); setDefaultCloseOperation(EXIT_ON_CLOSE); Panneau p = new Panneau(); add(p); // Animation Timer timer = new Timer(30, e -> p.repaint()); timer.start(); setVisible(true); } } public class Panneau extends JPanel { private int x = 0; public void paintComponent(Graphics g) { super.paintComponent(g); g.fillOval(x, 100, 40, 40); x++; // le cercle se déplace } } ``` Ce mini-programme affiche un cercle qui se déplace à l’écran. # 🗓️ Historique > Dernière mise à jour : 22 novembre 2025 > Rédigé par : [[Julien DUQUENNOY]]