Fenetre et Dessin v1

This commit is contained in:
2025-10-08 12:13:42 +02:00
parent 721543075c
commit ba7e16dc64
2 changed files with 259 additions and 27 deletions

View File

@@ -1,23 +1,94 @@
import javax.swing.*;
import java.awt.*;
/**
* La classe <code>Dessin</code>
* La classe <code>Dessin</code> gère uniquement le dessin du pendu
*
* @version
* @author
* Date :
* @version 0.1
* @author Adrien
* Date : 08-10-2025
* Licence :
*/
public class Dessin {
//Attributs
public class Dessin extends JPanel {
//Constructeur
public Dessin() {
// --- Constructeur ---
public Dessin() {
// Taille préférée pour s'intégrer dans Fenetre
setPreferredSize(new Dimension(600, 350));
setBackground(new Color(245, 245, 245));
}
}
//Méthodes
// --- Dessin principal ---
@Override
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
//Affichage
public String toString() {
return "" ;
}
// Anti-aliasing pour des traits plus doux
Graphics2D graphics2D = (Graphics2D) graphics.create();
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.setStroke(new BasicStroke(3f));
graphics2D.setColor(Color.DARK_GRAY);
// Repères et proportions
int width = getWidth();
int height = getHeight();
int marginPixels = Math.min(width, height) / 12; // marge proportionnelle
// Potence : socle
int baseYCoordinate = height - marginPixels;
graphics2D.drawLine(marginPixels, baseYCoordinate, width / 2, baseYCoordinate);
// Montant vertical
int postXCoordinate = marginPixels + (width / 12);
graphics2D.drawLine(postXCoordinate, baseYCoordinate, postXCoordinate, marginPixels);
// Traverse horizontale
int beamLength = width / 3;
graphics2D.drawLine(postXCoordinate, marginPixels, postXCoordinate + beamLength, marginPixels);
// Renfort diagonal
graphics2D.drawLine(postXCoordinate, marginPixels + height / 10,
postXCoordinate + width / 12, marginPixels);
// Corde
int ropeXCoordinate = postXCoordinate + beamLength;
int ropeTopYCoordinate = marginPixels;
int ropeBottomYCoordinate = marginPixels + height / 12;
graphics2D.drawLine(ropeXCoordinate, ropeTopYCoordinate, ropeXCoordinate, ropeBottomYCoordinate);
// Personnage : tête
int headRadiusPixels = Math.min(width, height) / 16;
int headCenterX = ropeXCoordinate;
int headCenterY = ropeBottomYCoordinate + headRadiusPixels;
graphics2D.drawOval(headCenterX - headRadiusPixels, headCenterY - headRadiusPixels,
headRadiusPixels * 2, headRadiusPixels * 2);
// Corps
int bodyTopYCoordinate = headCenterY + headRadiusPixels;
int bodyBottomYCoordinate = bodyTopYCoordinate + height / 6;
graphics2D.drawLine(headCenterX, bodyTopYCoordinate, headCenterX, bodyBottomYCoordinate);
// Bras
int armSpanPixels = width / 10;
int shouldersYCoordinate = bodyTopYCoordinate + height / 24;
graphics2D.drawLine(headCenterX, shouldersYCoordinate,
headCenterX - armSpanPixels, shouldersYCoordinate + height / 20);
graphics2D.drawLine(headCenterX, shouldersYCoordinate,
headCenterX + armSpanPixels, shouldersYCoordinate + height / 20);
// Jambes
int legSpanPixels = width / 12;
graphics2D.drawLine(headCenterX, bodyBottomYCoordinate,
headCenterX - legSpanPixels, bodyBottomYCoordinate + height / 8);
graphics2D.drawLine(headCenterX, bodyBottomYCoordinate,
headCenterX + legSpanPixels, bodyBottomYCoordinate + height / 8);
graphics2D.dispose();
}
// Affichage
@Override
public String toString() {
return "";
}
}

View File

@@ -1,23 +1,184 @@
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.function.Consumer;
/**
* La classe <code>Fenetre</code>
* La classe <code>Fenetre</code> gère uniquement l'interface graphique :
* - zone de dessin (remplaçable par la classe Dessin)
* - affichage du mot masqué
* - saisie d'une lettre (événement remonté via un handler)
*
* @version
* @author
* Date :
* Licence :
* Aucune logique de jeu (choix/vérification du mot) n'est ici.
*
* * @version 0.3
* @author Adrien
* Date : 08-10-25
* Licence :
*/
public class Fenetre {
//Attributs
//Constructeur
public Fenetre() {
// --- Composants de l'interface (UI only) ---
private JFrame window;
private JLabel wordLabel;
private JTextField letterInput;
private JButton sendButton;
private JPanel drawZone; // remplaçable par la classe Dessin
// Handler externe pour la lettre soumise (fourni par la classe Partie / contrôleur)
private Consumer<Character> onLetterSubmitted;
// --- Constructeur (courte orchestration uniquement) ---
public Fenetre() {
setupWindow();
JPanel root = createRoot();
window.setContentPane(root);
drawZone = createDrawZone();
root.add(drawZone);
wordLabel = createWordLabel();
root.add(wordLabel);
JPanel inputPanel = createInputPanel();
root.add(inputPanel);
window.setVisible(true);
letterInput.requestFocusInWindow();
}
// --- Initialisation fenêtre ---
/** Configure la fenêtre principale (titre, taille, fermeture). */
private void setupWindow() {
window = new JFrame("Jeu du Pendu");
window.setSize(600, 600);
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
/** Crée le conteneur principal vertical. */
private JPanel createRoot() {
JPanel root = new JPanel();
root.setLayout(new BoxLayout(root, BoxLayout.Y_AXIS));
return root;
}
// --- Sous-composants UI ---
/** Crée la zone de dessin placeholder (à remplacer par Dessin). */
private JPanel createDrawZone() {
JPanel panel = new PlaceholderDrawPanel();
panel.setPreferredSize(new Dimension(600, 350));
panel.setBackground(new Color(245, 245, 245));
return panel;
}
/** Crée le label d'affichage du mot (placeholder jusqu'à injection par Partie). */
private JLabel createWordLabel() {
JLabel label = new JLabel("_ _ _ _ _", SwingConstants.CENTER);
label.setFont(new Font("Segoe UI", Font.BOLD, 32));
label.setBorder(BorderFactory.createEmptyBorder(20, 10, 20, 10));
label.setAlignmentX(Component.CENTER_ALIGNMENT);
return label;
}
/** Crée la zone de saisie (champ + bouton) et branche l'action. */
private JPanel createInputPanel() {
JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
JLabel prompt = new JLabel("Entrez une lettre :");
letterInput = new JTextField(2);
letterInput.setHorizontalAlignment(JTextField.CENTER);
letterInput.setFont(new Font("Segoe UI", Font.BOLD, 24));
sendButton = new JButton("Envoyer");
Action sendAction = new AbstractAction() {
@Override public void actionPerformed(ActionEvent e) { submitLetter(); }
};
sendButton.addActionListener(sendAction);
letterInput.addActionListener(sendAction);
letterInput.addKeyListener(new KeyAdapter() {
@Override public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if (!Character.isLetter(c) || letterInput.getText().length() >= 1) e.consume();
else e.setKeyChar(Character.toUpperCase(c));
}
});
inputPanel.add(prompt);
inputPanel.add(letterInput);
inputPanel.add(sendButton);
return inputPanel;
}
// --- Partie et Dessin ---
/** Définit le texte du mot affiché (ex: "_ _ A _ _") fourni par la classe Partie. */
public void setWordDisplay(String maskedWord) {
wordLabel.setText(maskedWord != null ? maskedWord : "");
}
/** Définit le panneau de dessin (remplace le placeholder par la classe Dessin). */
public void setDrawPanel(JPanel dessinPanel) {
if (dessinPanel == null) return;
Container parent = drawZone.getParent();
int index = -1;
for (int i = 0; i < parent.getComponentCount(); i++) {
if (parent.getComponent(i) == drawZone) { index = i; break; }
}
if (index != -1) {
parent.remove(index);
drawZone = dessinPanel;
drawZone.setPreferredSize(new Dimension(600, 350));
parent.add(drawZone, index);
parent.revalidate();
parent.repaint();
}
}
/** Définit le handler appelé quand l'utilisateur soumet une lettre. */
public void setOnLetterSubmitted(Consumer<Character> handler) {
this.onLetterSubmitted = handler;
}
// --- Méthodes privées UI ---
/** Récupère la lettre et notifie le handler externe (aucune logique de jeu ici). */
private void submitLetter() {
String text = letterInput.getText().trim().toUpperCase();
letterInput.setText("");
if (text.length() != 1 || !text.matches("[A-Z]")) {
JOptionPane.showMessageDialog(window, "Veuillez entrer une seule lettre (A-Z).");
return;
}
if (onLetterSubmitted != null) onLetterSubmitted.accept(text.charAt(0));
else JOptionPane.showMessageDialog(window, "Lettre soumise (placeholder) : " + text);
}
// --- Placeholder de dessin (pour tester la fenêtre seule) ---
private static class PlaceholderDrawPanel extends JPanel {
@Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(2f));
g2.drawRect(10, 10, getWidth() - 20, getHeight() - 20);
g2.setFont(getFont().deriveFont(Font.BOLD, 16f));
String txt = "Zone de dessin (remplacer par Dessin)";
FontMetrics fm = g2.getFontMetrics();
int x = (getWidth() - fm.stringWidth(txt)) / 2;
int y = (getHeight() + fm.getAscent()) / 2;
g2.drawString(txt, x, y);
}
}
// --- Méthode principale de test : exécuter Fenetre seule (sans Partie/Dessin) ---
public static void main(String[] args) {
Fenetre f = new Fenetre();
f.setWordDisplay("_ _ _ _ _"); // placeholder
f.setDrawPanel(new Dessin()); // dessin
f.setOnLetterSubmitted(ch -> JOptionPane.showMessageDialog(null,"Lettre reçue : " + ch + " (sans logique de jeu)"));
}
//Méthodes
//Affichage
public String toString() {
return "" ;
}
}