package front; import back.*; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; /** * Interface graphique (Swing) du jeu du pendu. * - Affiche une image différente à chaque erreur. * - Champ de saisie pour entrer une lettre. * - Texte pour le mot masqué et les lettres essayées. */ public class GameUI { private JFrame frame; private JLabel imgLabel; private JLabel wordLabel; private JLabel triedLabel; private JTextField input; private JButton tryBtn; private JButton newGameBtn; private Game game; private String currentWord; /** Affiche la fenêtre principale */ public void show() { setupUI(); startNewGame(); frame.setVisible(true); } /** Initialise les composants Swing */ private void setupUI() { frame = new JFrame("Jeu du Pendu"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(520, 520); frame.setLocationRelativeTo(null); frame.setLayout(new BorderLayout(12, 12)); // Image du pendu imgLabel = new JLabel("", SwingConstants.CENTER); frame.add(imgLabel, BorderLayout.CENTER); // Panneau bas: saisie + actions JPanel bottom = new JPanel(new BorderLayout(8, 8)); JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); input = new JTextField(5); tryBtn = new JButton("Essayer"); inputPanel.add(new JLabel("Lettre :")); inputPanel.add(input); inputPanel.add(tryBtn); newGameBtn = new JButton("Nouvelle partie"); bottom.add(inputPanel, BorderLayout.WEST); bottom.add(newGameBtn, BorderLayout.EAST); frame.add(bottom, BorderLayout.SOUTH); // Panneau haut: mot + lettres essayées JPanel top = new JPanel(); top.setLayout(new BoxLayout(top, BoxLayout.Y_AXIS)); wordLabel = new JLabel("Mot : "); triedLabel = new JLabel("Lettres essayées : "); wordLabel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); triedLabel.setBorder(BorderFactory.createEmptyBorder(0, 8, 8, 8)); top.add(wordLabel); top.add(triedLabel); frame.add(top, BorderLayout.NORTH); // Actions tryBtn.addActionListener(this::onTry); input.addActionListener(this::onTry); newGameBtn.addActionListener(e -> startNewGame()); } /** Démarre une nouvelle partie */ private void startNewGame() { currentWord = Words.random(); game = new Game(currentWord, 7); input.setText(""); input.requestFocusInWindow(); refreshUI(); } /** Gère le clic sur "Essayer" ou Entrée dans le champ */ private void onTry(ActionEvent e) { String text = input.getText(); if (!Check.isLetter(text)) { JOptionPane.showMessageDialog(frame, "Tape une seule lettre (A-Z)."); input.requestFocusInWindow(); input.selectAll(); return; } char c = Character.toLowerCase(text.charAt(0)); Result res = game.play(c); switch (res) { case ALREADY -> JOptionPane.showMessageDialog(frame, "Lettre déjà utilisée."); case HIT -> {} // rien, rafraîchissement visuel suffit case MISS -> {} // idem } input.setText(""); refreshUI(); if (game.isWin()) { refreshUI(); JOptionPane.showMessageDialog(frame, "Bravo ! Le mot était : " + currentWord); } else if (game.isLose()) { refreshUI(); JOptionPane.showMessageDialog(frame, "Perdu ! Le mot était : " + currentWord); } } /** Met à jour l'image et les textes selon l'état courant */ private void refreshUI() { imgLabel.setIcon(Gallows.icon(game.getErrors())); wordLabel.setText("Mot : " + game.maskedWord()); triedLabel.setText("Lettres essayées : " + String.join(", ", game.triedLetters())); frame.repaint(); } }