forked from menault/TD3_DEV51_Qualite_Algo
Merge pull request 'Fenetre et Dessin v1' (#4) from dick into master
Reviewed-on: #4
This commit is contained in:
@@ -1,23 +1,88 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La classe <code>Dessin</code>
|
* La classe <code>Dessin</code> gère uniquement le dessin du pendu
|
||||||
*
|
*
|
||||||
* @version
|
* @version 1.0
|
||||||
* @author
|
* @author Adrien
|
||||||
* Date :
|
* Date : 08-10-2025
|
||||||
* Licence :
|
* Licence :
|
||||||
*/
|
*/
|
||||||
public class Dessin {
|
public class Dessin extends JPanel {
|
||||||
//Attributs
|
|
||||||
|
|
||||||
//Constructeur
|
// --- Constructeur ---
|
||||||
public Dessin() {
|
public Dessin() {
|
||||||
|
// Taille préférée pour s'intégrer dans Fenetre
|
||||||
|
setPreferredSize(new Dimension(600, 350));
|
||||||
|
setBackground(new Color(245, 245, 245));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
// --- Dessin principal ---
|
||||||
//Méthodes
|
@Override
|
||||||
|
protected void paintComponent(Graphics graphics) {
|
||||||
|
super.paintComponent(graphics);
|
||||||
|
|
||||||
//Affichage
|
// Anti-aliasing pour des traits plus doux
|
||||||
public String toString() {
|
Graphics2D graphics2D = (Graphics2D) graphics.create();
|
||||||
return "" ;
|
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 "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
72
src/Event.java
Normal file
72
src/Event.java
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* La classe <code>Event</code> regroupe et branche tous les listeners liés à Fenetre.
|
||||||
|
* - Validation de la saisie (1 lettre A-Z, majuscule)
|
||||||
|
* - Action sur Entrée ou clic bouton
|
||||||
|
* - Notification du handler externe (fourni au constructeur)
|
||||||
|
* Aucune logique de jeu ici.
|
||||||
|
* @version 1.3
|
||||||
|
* author Adrien
|
||||||
|
* Date : 08-10-2025
|
||||||
|
*/
|
||||||
|
public class Event implements ActionListener {
|
||||||
|
|
||||||
|
private final Fenetre window;
|
||||||
|
private final Consumer<Character> onLetterSubmitted;
|
||||||
|
|
||||||
|
/** Constructeur : conserve les références et branche les événements. */
|
||||||
|
public Event(Fenetre window, Consumer<Character> onLetterSubmitted) {
|
||||||
|
this.window = window;
|
||||||
|
this.onLetterSubmitted = onLetterSubmitted;
|
||||||
|
wireEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Branche les listeners sur les composants de Fenetre.*/
|
||||||
|
private void wireEvents() {
|
||||||
|
JTextField letterInput = window.getLetterInput();
|
||||||
|
JButton sendButton = window.getSendButton();
|
||||||
|
|
||||||
|
// Même listener (this) pour Entrée et clic bouton
|
||||||
|
sendButton.addActionListener(this);
|
||||||
|
letterInput.addActionListener(this);
|
||||||
|
|
||||||
|
// UX : limiter à une seule lettre et forcer la majuscule
|
||||||
|
letterInput.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent keyEvent) {
|
||||||
|
char typedChar = keyEvent.getKeyChar();
|
||||||
|
if (!Character.isLetter(typedChar) || letterInput.getText().length() >= 1) {
|
||||||
|
keyEvent.consume();
|
||||||
|
} else {
|
||||||
|
keyEvent.setKeyChar(Character.toUpperCase(typedChar));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Réagit à Entrée ou au clic bouton : récupère, valide et transmet la lettre. */
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent actionEvent) {
|
||||||
|
JTextField letterInput = window.getLetterInput();
|
||||||
|
|
||||||
|
String inputText = letterInput.getText().trim().toUpperCase();
|
||||||
|
letterInput.setText(""); // reset du champ après tentative
|
||||||
|
|
||||||
|
// Validation : exactement une lettre A–Z
|
||||||
|
if (inputText.length() != 1 || !inputText.matches("[A-Z]")) {
|
||||||
|
JOptionPane.showMessageDialog(window.getWindow(), "Veuillez entrer une seule lettre (A-Z).");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notification du handler externe, sinon placeholder
|
||||||
|
if (onLetterSubmitted != null) {
|
||||||
|
onLetterSubmitted.accept(inputText.charAt(0));
|
||||||
|
} else {
|
||||||
|
JOptionPane.showMessageDialog(window.getWindow(),
|
||||||
|
"Lettre soumise (placeholder) : " + inputText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
101
src/Fenetre.java
101
src/Fenetre.java
@@ -1,23 +1,98 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La classe <code>Fenetre</code>
|
* La classe <code>Fenetre</code> gère uniquement l'interface graphique :
|
||||||
|
* - zone de dessin (assurée par la classe Dessin)
|
||||||
|
* - affichage du mot masqué
|
||||||
|
* - saisie d'une lettre (les événements sont gérés dans Event)
|
||||||
*
|
*
|
||||||
* @version
|
* Aucune logique de jeu ici.
|
||||||
* @author
|
* @version 1.5
|
||||||
* Date :
|
* @author Adrien
|
||||||
|
* Date : 08-10-2025
|
||||||
* Licence :
|
* Licence :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Fenetre {
|
public class Fenetre {
|
||||||
//Attributs
|
|
||||||
|
|
||||||
//Constructeur
|
// --- Composants de l'interface ---
|
||||||
public Fenetre() {
|
private JFrame window;
|
||||||
|
private JLabel wordLabel;
|
||||||
|
private JTextField letterInput;
|
||||||
|
private JButton sendButton;
|
||||||
|
private JPanel drawZone; // instance de Dessin
|
||||||
|
|
||||||
}
|
// --- Constructeur ---
|
||||||
//Méthodes
|
public Fenetre() {
|
||||||
|
setupWindow();
|
||||||
|
|
||||||
//Affichage
|
JPanel root = new JPanel();
|
||||||
public String toString() {
|
root.setLayout(new BoxLayout(root, BoxLayout.Y_AXIS));
|
||||||
return "" ;
|
window.setContentPane(root);
|
||||||
}
|
|
||||||
|
drawZone = new Dessin();
|
||||||
|
root.add(drawZone);
|
||||||
|
|
||||||
|
wordLabel = createWordLabel();
|
||||||
|
root.add(wordLabel);
|
||||||
|
|
||||||
|
JPanel inputPanel = createInputPanel();
|
||||||
|
root.add(inputPanel);
|
||||||
|
|
||||||
|
window.setVisible(true);
|
||||||
|
letterInput.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Initialisation fenêtre ---
|
||||||
|
private void setupWindow() {
|
||||||
|
window = new JFrame("Jeu du Pendu");
|
||||||
|
window.setSize(600, 600);
|
||||||
|
window.setLocationRelativeTo(null);
|
||||||
|
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Sous-composants UI ---
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
inputPanel.add(prompt);
|
||||||
|
inputPanel.add(letterInput);
|
||||||
|
inputPanel.add(sendButton);
|
||||||
|
return inputPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Getters pour Event ---
|
||||||
|
public JFrame getWindow() { return window; }
|
||||||
|
public JTextField getLetterInput() { return letterInput; }
|
||||||
|
public JButton getSendButton() { return sendButton; }
|
||||||
|
public JLabel getWordLabel() { return wordLabel; }
|
||||||
|
public JPanel getDrawZone() { return drawZone; }
|
||||||
|
|
||||||
|
// --- Méthode principale de test ---
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
Fenetre f = new Fenetre();
|
||||||
|
// On passe le handler directement ici (pas de setOnLetterSubmitted)
|
||||||
|
new Event(f, ch ->
|
||||||
|
JOptionPane.showMessageDialog(f.getWindow(), "Lettre reçue : " + ch + " (sans logique de jeu)")
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user