package fr.iut.Projet; import javax.swing.*; import java.awt.*; /** * Classe qui représente l'interface graphique du jeu du pendu. * Elle gère l'affichage du mot caché, des lettres incorrectes, des vies * et permet de saisir des lettres. Un bouton permet de relancer le jeu. */ public class Action { // Fenêtre principale du jeu private JFrame gameFrame; // Labels pour afficher le mot, les lettres incorrectes et les vies private JLabel wordLabel; private JLabel incorrectLettersLabel; private JLabel livesLabel; // Champ de saisie pour entrer une lettre private JTextField letterInputField; // Instance du jeu private Random_word game; /** * Constructeur de la classe Action. * Initialise le jeu, les composants graphiques et affiche la fenêtre. */ public Action() { game = new Random_word(); initializeComponents(); layoutComponents(); letterInputField.addActionListener(e -> handleGuess()); gameFrame.setVisible(true); } // ==================== Initialisation des composants ==================== /** * Initialise tous les composants graphiques : * - Fenêtre principale * - Labels pour le mot, les vies et les lettres incorrectes * - Champ de saisie pour entrer les lettres */ private void initializeComponents() { gameFrame = new JFrame("Hanging Man"); gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); gameFrame.setSize(600, 400); wordLabel = new JLabel(game.getHiddenWord()); wordLabel.setFont(new Font("Arial", Font.BOLD, 32)); wordLabel.setHorizontalAlignment(SwingConstants.CENTER); livesLabel = new JLabel("Lives: " + game.getLives()); livesLabel.setFont(new Font("Arial", Font.BOLD, 20)); livesLabel.setHorizontalAlignment(SwingConstants.CENTER); incorrectLettersLabel = new JLabel("Incorrect letters: " + game.getIncorrectLetters()); incorrectLettersLabel.setFont(new Font("Arial", Font.PLAIN, 20)); incorrectLettersLabel.setHorizontalAlignment(SwingConstants.CENTER); letterInputField = new JTextField(3); letterInputField.setFont(new Font("Arial", Font.PLAIN, 24)); } // ==================== Layout des composants ==================== /** * Dispose les composants dans la fenêtre principale en utilisant GridBagLayout. * Sépare la fenêtre en deux parties : le haut (mot et vies) et le bas (lettres incorrectes, saisie, bouton restart) */ private void layoutComponents() { JPanel mainPanel = new JPanel(new GridBagLayout()); GridBagConstraints mainConstraints = new GridBagConstraints(); mainConstraints.gridx = 0; mainConstraints.fill = GridBagConstraints.BOTH; mainConstraints.insets = new Insets(5, 5, 5, 5); JPanel topPanel = createTopPanel(); mainConstraints.gridy = 0; mainConstraints.weighty = 3.0; mainConstraints.weightx = 1.0; mainPanel.add(topPanel, mainConstraints); JPanel bottomPanel = createBottomPanel(); mainConstraints.gridy = 1; mainConstraints.weighty = 1.0; mainPanel.add(bottomPanel, mainConstraints); gameFrame.add(mainPanel, BorderLayout.CENTER); } /** * Crée le panneau supérieur avec : * - Le label des vies (à gauche) * - Le label du mot caché (à droite) * @return JPanel configuré pour la partie supérieure */ private JPanel createTopPanel() { JPanel topPanel = new JPanel(new GridBagLayout()); // Panel pour les vies JPanel livesPanel = new JPanel(new GridBagLayout()); GridBagConstraints livesConstraints = new GridBagConstraints(); livesConstraints.anchor = GridBagConstraints.CENTER; livesConstraints.fill = GridBagConstraints.NONE; livesPanel.add(livesLabel, livesConstraints); // Panel pour le mot JPanel wordPanel = new JPanel(new GridBagLayout()); GridBagConstraints wordConstraints = new GridBagConstraints(); wordConstraints.anchor = GridBagConstraints.CENTER; wordConstraints.fill = GridBagConstraints.NONE; wordPanel.add(wordLabel, wordConstraints); // Ajout des panels dans topPanel GridBagConstraints leftConstraints = new GridBagConstraints(); leftConstraints.gridx = 0; leftConstraints.weightx = 0.5; leftConstraints.weighty = 1.0; leftConstraints.fill = GridBagConstraints.BOTH; topPanel.add(livesPanel, leftConstraints); GridBagConstraints rightConstraints = new GridBagConstraints(); rightConstraints.gridx = 1; rightConstraints.weightx = 0.5; rightConstraints.weighty = 1.0; rightConstraints.fill = GridBagConstraints.BOTH; topPanel.add(wordPanel, rightConstraints); return topPanel; } /** * Crée le panneau inférieur avec : * - Le label des lettres incorrectes * - Le champ de saisie pour entrer une lettre * - Le bouton "Restart" en bas à droite * @return JPanel configuré pour la partie inférieure */ private JPanel createBottomPanel() { JPanel bottomPanel = new JPanel(); bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS)); // Label des lettres incorrectes incorrectLettersLabel.setAlignmentX(Component.CENTER_ALIGNMENT); bottomPanel.add(incorrectLettersLabel); // Champ de saisie JLabel promptLabel = new JLabel("Enter a letter:"); promptLabel.setFont(new Font("Arial", Font.PLAIN, 16)); promptLabel.setAlignmentX(Component.CENTER_ALIGNMENT); JPanel inputRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5)); inputRow.add(promptLabel); inputRow.add(letterInputField); inputRow.setAlignmentX(Component.CENTER_ALIGNMENT); bottomPanel.add(Box.createVerticalStrut(10)); bottomPanel.add(inputRow); // Bouton "Restart" en bas à droite JButton restartButton = new JButton("Restart"); restartButton.addActionListener(new PlayButtonListener(gameFrame)); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); buttonPanel.add(restartButton); bottomPanel.add(Box.createVerticalStrut(10)); bottomPanel.add(buttonPanel); return bottomPanel; } // ==================== Gestion du jeu ==================== /** * Gère la saisie d'une lettre par le joueur. * Vérifie la validité de la lettre, met à jour l'affichage et termine le jeu si nécessaire. */ private void handleGuess() { String inputText = letterInputField.getText(); letterInputField.setText(""); if (!isValidInput(inputText)) return; char guessedLetter = inputText.charAt(0); String message = game.guessLetter(guessedLetter); updateUI(); if (game.isGameOver()) endGame(message); } /** * Vérifie si la saisie de l'utilisateur est valide : * - Une seule lettre * - Caractère alphabétique * @param inputText texte saisi par l'utilisateur * @return true si la saisie est valide, false sinon */ private boolean isValidInput(String inputText) { if (inputText.length() != 1 || !Character.isLetter(inputText.charAt(0))) { JOptionPane.showMessageDialog(gameFrame, "Please enter a single letter!"); return false; } return true; } /** * Met à jour l'affichage des labels : * - Mot caché * - Lettres incorrectes * - Nombre de vies restantes */ private void updateUI() { wordLabel.setText(game.getHiddenWord()); incorrectLettersLabel.setText("Incorrect letters: " + game.getIncorrectLetters()); livesLabel.setText("Lives: " + game.getLives()); } /** * Termine le jeu et affiche un message. * Désactive le champ de saisie. * @param message Message à afficher (victoire ou défaite) */ private void endGame(String message) { JOptionPane.showMessageDialog(gameFrame, message); letterInputField.setEditable(false); } }