Files
TD3_DEV51_DUCREUX_JANNAIRE/Jeu_pendu/Front/GameUI.java

156 lines
4.9 KiB
Java
Raw Normal View History

2025-10-08 11:57:29 +02:00
package front;
import back.*;
2025-10-08 15:26:45 +02:00
2025-10-08 11:57:29 +02:00
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
/**
2025-10-08 15:26:45 +02:00
* Interface graphique du jeu du pendu.
* (Toutes les méthodes 50 lignes)
2025-10-08 11:57:29 +02:00
*/
public class GameUI {
private JFrame frame;
2025-10-08 15:26:45 +02:00
private JLabel imgLabel, wordLabel, triedLabel, scoreLabel, timeLabel;
2025-10-08 11:57:29 +02:00
private JTextField input;
2025-10-08 15:26:45 +02:00
private JButton tryBtn, newGameBtn;
2025-10-08 11:57:29 +02:00
private Game game;
private String currentWord;
2025-10-08 15:26:45 +02:00
private Timer timer;
2025-10-08 11:57:29 +02:00
2025-10-08 15:26:45 +02:00
/** Lance la fenêtre et démarre une partie */
2025-10-08 11:57:29 +02:00
public void show() {
2025-10-08 15:26:45 +02:00
setupWindow();
setupLayout();
setupActions();
2025-10-08 11:57:29 +02:00
startNewGame();
frame.setVisible(true);
}
2025-10-08 15:26:45 +02:00
/** Crée la fenêtre principale */
private void setupWindow() {
2025-10-08 11:57:29 +02:00
frame = new JFrame("Jeu du Pendu");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
2025-10-08 15:26:45 +02:00
frame.setSize(560, 560);
2025-10-08 11:57:29 +02:00
frame.setLocationRelativeTo(null);
frame.setLayout(new BorderLayout(12, 12));
2025-10-08 15:26:45 +02:00
}
2025-10-08 11:57:29 +02:00
2025-10-08 15:26:45 +02:00
/** Construit les composants et le layout */
private void setupLayout() {
2025-10-08 11:57:29 +02:00
imgLabel = new JLabel("", SwingConstants.CENTER);
frame.add(imgLabel, BorderLayout.CENTER);
2025-10-08 15:26:45 +02:00
wordLabel = new JLabel("Mot : ");
triedLabel = new JLabel("Lettres essayées : ");
scoreLabel = new JLabel("Score : 0");
timeLabel = new JLabel("Temps : 0s");
JPanel top = new JPanel(new GridLayout(2, 1));
top.add(buildTopLine(wordLabel, scoreLabel));
top.add(buildTopLine(triedLabel, timeLabel));
frame.add(top, BorderLayout.NORTH);
2025-10-08 11:57:29 +02:00
JPanel bottom = new JPanel(new BorderLayout(8, 8));
JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
input = new JTextField(5);
tryBtn = new JButton("Essayer");
2025-10-08 15:26:45 +02:00
newGameBtn = new JButton("Nouvelle partie");
2025-10-08 11:57:29 +02:00
inputPanel.add(new JLabel("Lettre :"));
inputPanel.add(input);
inputPanel.add(tryBtn);
bottom.add(inputPanel, BorderLayout.WEST);
bottom.add(newGameBtn, BorderLayout.EAST);
frame.add(bottom, BorderLayout.SOUTH);
2025-10-08 15:26:45 +02:00
}
2025-10-08 11:57:29 +02:00
2025-10-08 15:26:45 +02:00
/** Crée une ligne du haut avec 2 labels */
private JPanel buildTopLine(JLabel left, JLabel right) {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
panel.add(left);
panel.add(Box.createHorizontalStrut(24));
panel.add(right);
return panel;
}
2025-10-08 11:57:29 +02:00
2025-10-08 15:26:45 +02:00
/** Ajoute les actions et le timer */
private void setupActions() {
2025-10-08 11:57:29 +02:00
tryBtn.addActionListener(this::onTry);
input.addActionListener(this::onTry);
newGameBtn.addActionListener(e -> startNewGame());
2025-10-08 15:26:45 +02:00
timer = new Timer(1000, e -> refreshStatsOnly());
2025-10-08 11:57:29 +02:00
}
/** Démarre une nouvelle partie */
private void startNewGame() {
currentWord = Words.random();
game = new Game(currentWord, 7);
input.setText("");
input.requestFocusInWindow();
2025-10-08 15:26:45 +02:00
if (!timer.isRunning()) timer.start();
2025-10-08 11:57:29 +02:00
refreshUI();
}
2025-10-08 15:26:45 +02:00
/** Gère le clic ou l'appui sur Entrée */
2025-10-08 11:57:29 +02:00
private void onTry(ActionEvent e) {
String text = input.getText();
if (!Check.isLetter(text)) {
2025-10-08 15:26:45 +02:00
showMsg("Tape une seule lettre (A-Z).");
2025-10-08 11:57:29 +02:00
input.requestFocusInWindow();
input.selectAll();
return;
}
2025-10-08 15:26:45 +02:00
Result res = game.play(Character.toLowerCase(text.charAt(0)));
handleResult(res);
input.setText("");
refreshUI();
checkEnd();
}
2025-10-08 11:57:29 +02:00
2025-10-08 15:26:45 +02:00
/** Réagit selon le résultat d'une tentative */
private void handleResult(Result res) {
2025-10-08 11:57:29 +02:00
switch (res) {
2025-10-08 15:26:45 +02:00
case ALREADY:
showMsg("Lettre déjà utilisée.");
break;
2025-10-08 12:11:52 +02:00
case HIT:
case MISS:
2025-10-08 15:26:45 +02:00
break; // rien, juste refresh
2025-10-08 11:57:29 +02:00
}
2025-10-08 15:26:45 +02:00
}
2025-10-08 11:57:29 +02:00
2025-10-08 15:26:45 +02:00
/** Vérifie si la partie est finie */
private void checkEnd() {
if (game.isWin() || game.isLose()) {
timer.stop();
game.end(game.isWin());
String msg = (game.isWin() ? "Bravo !" : "Perdu !")
+ " Le mot était : " + currentWord
+ "\nScore final : " + game.getScore()
+ "\nTemps : " + game.getElapsedSeconds() + "s";
showMsg(msg);
2025-10-08 11:57:29 +02:00
}
}
2025-10-08 15:26:45 +02:00
/** Met à jour tout l'affichage */
2025-10-08 11:57:29 +02:00
private void refreshUI() {
imgLabel.setIcon(Gallows.icon(game.getErrors()));
wordLabel.setText("Mot : " + game.maskedWord());
triedLabel.setText("Lettres essayées : " + String.join(", ", game.triedLetters()));
2025-10-08 15:26:45 +02:00
refreshStatsOnly();
2025-10-08 11:57:29 +02:00
frame.repaint();
}
2025-10-08 15:26:45 +02:00
/** Met à jour uniquement score + chrono */
private void refreshStatsOnly() {
scoreLabel.setText("Score : " + game.getScore());
timeLabel.setText("Temps : " + game.getElapsedSeconds() + "s");
}
/** Affiche une boîte de message */
private void showMsg(String msg) {
JOptionPane.showMessageDialog(frame, msg);
}
}