Amélioration MVC / Responsabilité unique partie 2

This commit is contained in:
Moncef STITI 2024-04-29 13:01:40 +02:00
parent 8ac0415c08
commit 3ab665b70d
7 changed files with 233 additions and 178 deletions

View File

@ -13,7 +13,7 @@ JCFLAGS := -encoding UTF-8 -implicit:none
JVM := java JVM := java
JVMFLAGS := JVMFLAGS :=
SRCDIR := ./src/GridSolver SRCDIR := ./src/GridMaker
OUTDIR := ./out OUTDIR := ./out
DOCDIR := ./doc DOCDIR := ./doc
SRC := $(wildcard $(SRCDIR)/*.java) SRC := $(wildcard $(SRCDIR)/*.java)

View File

@ -28,7 +28,9 @@ public class GridMakeUserInterfaceView {
JMenuItem nouveauItem = createMenuItem("Nouveau", new GridMakerResetGrid(grid)); JMenuItem nouveauItem = createMenuItem("Nouveau", new GridMakerResetGrid(grid));
JMenuItem chargerItem = createMenuItem("Charger", new GridMakerImport(window, grid)); JMenuItem chargerItem = createMenuItem("Charger", new GridMakerImport(window, grid));
JMenuItem sauvegarderItem = createMenuItem("Sauvegarder", new GridMakerSaver(window, grid)); JMenuItem sauvegarderItem = createMenuItem("Sauvegarder", new GridMakerSaver(window, grid));
JMenuItem verifierItem = createMenuItem("Vérifier", new GridMakerChecker(grid)); GridMakerChecker checker = new GridMakerChecker(grid); // Créez une instance de GridMakerChecker
GridMakerCheckerListener checkerListener = new GridMakerCheckerListener(checker); // Créez une instance de GridMakerCheckerListener en passant GridMakerChecker en argument
JMenuItem verifierItem = createMenuItem("Vérifier", checkerListener);
JMenuItem aideGrilleItem = createMenuItem("Comment créer une grille", new GridMakerHowToCreateController()); JMenuItem aideGrilleItem = createMenuItem("Comment créer une grille", new GridMakerHowToCreateController());
JMenuItem reglesSudokuItem = createMenuItem("Règles du Sudoku", new GridMakerRules()); JMenuItem reglesSudokuItem = createMenuItem("Règles du Sudoku", new GridMakerRules());

View File

@ -4,12 +4,12 @@ import javax.swing.*;
/** /**
* GridMakerCase représente une case dans une grille éditable. * GridMakerCase représente une case dans une grille éditable.
* Cette classe étend JPanel et implémente KeyListener pour permettre à l'utilisateur de saisir des valeurs dans la case. * Cette classe étend JPanel et utilise un GridMakerCaseListener pour gérer les événements de touche.
* @version 1.0 * @version 1.0
* @author Moncef STITI * @author Moncef STITI
* @author Marco ORFAO * @author Marco ORFAO
*/ */
public class GridMakerCase extends JPanel implements KeyListener { public class GridMakerCase extends JPanel {
private int cellValue = 0; // Valeur actuelle de la case private int cellValue = 0; // Valeur actuelle de la case
private String displayText = ""; // Texte à afficher dans la case private String displayText = ""; // Texte à afficher dans la case
@ -17,56 +17,23 @@ public class GridMakerCase extends JPanel implements KeyListener {
/** /**
* Constructeur par défaut de GridMakerCase. * Constructeur par défaut de GridMakerCase.
* Initialise le bouton avec les propriétés nécessaires, ajoute un KeyListener et configure le layout. * Initialise le bouton avec les propriétés nécessaires, crée un GridMakerCaseListener et l'ajoute au bouton.
*/ */
public GridMakerCase() { public GridMakerCase() {
actionButton.setOpaque(false); actionButton.setOpaque(false);
actionButton.setContentAreaFilled(false); actionButton.setContentAreaFilled(false);
actionButton.setBorderPainted(false); actionButton.setBorderPainted(false);
actionButton.setPreferredSize(new Dimension(50, 50)); actionButton.setPreferredSize(new Dimension(50, 50));
actionButton.addKeyListener(this); // Ajout du KeyListener au bouton
BorderLayout gestionnaire = new BorderLayout(); BorderLayout gestionnaire = new BorderLayout();
setLayout(gestionnaire); setLayout(gestionnaire);
add(actionButton, BorderLayout.CENTER); add(actionButton, BorderLayout.CENTER);
setPreferredSize(new Dimension(60, 60)); setPreferredSize(new Dimension(60, 60));
}
/** // Crée un GridMakerCaseListener et l'ajoute au bouton
* Méthode appelée lorsqu'une touche est enfoncée. GridMakerCaseListener listener = new GridMakerCaseListener(this);
* Si la touche est un chiffre, met à jour la valeur de la case avec ce chiffre. actionButton.addKeyListener(listener);
* @param e L'événement KeyEvent généré lorsque la touche est enfoncée.
*/
@Override
public void keyPressed(KeyEvent e) {
int keyChar = e.getKeyChar();
if (Character.isDigit(keyChar)) {
int num = Character.getNumericValue(keyChar);
if (num >= 0 && num <= 9) {
setCellValue(num);
}
}
}
/**
* Méthode appelée lorsqu'une touche est relâchée.
* Aucun traitement n'est nécessaire dans ce cas.
* @param e L'événement KeyEvent généré lorsque la touche est relâchée.
*/
@Override
public void keyReleased(KeyEvent e) {
// Pas de traitement nécessaire
}
/**
* Méthode appelée lorsqu'une touche est tapée (enfoncée puis relâchée).
* Aucun traitement n'est nécessaire dans ce cas.
* @param e L'événement KeyEvent généré lorsque la touche est tapée.
*/
@Override
public void keyTyped(KeyEvent e) {
// Pas de traitement nécessaire
} }
/** /**
@ -96,4 +63,3 @@ public class GridMakerCase extends JPanel implements KeyListener {
return this.cellValue; return this.cellValue;
} }
} }

View File

@ -0,0 +1,54 @@
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
/**
* GridMakerCaseListener est un KeyListener utilisé pour écouter les événements de touche dans GridMakerCase.
*/
public class GridMakerCaseListener implements KeyListener {
private GridMakerCase gridMakerCase;
/**
* Constructeur de GridMakerCaseListener.
* @param gridMakerCase La case à écouter.
*/
public GridMakerCaseListener(GridMakerCase gridMakerCase) {
this.gridMakerCase = gridMakerCase;
}
/**
* Méthode appelée lorsqu'une touche est enfoncée.
* Si la touche est un chiffre, met à jour la valeur de la case avec ce chiffre.
* @param e L'événement KeyEvent généré lorsque la touche est enfoncée.
*/
@Override
public void keyPressed(KeyEvent e) {
int keyChar = e.getKeyChar();
if (Character.isDigit(keyChar)) {
int num = Character.getNumericValue(keyChar);
if (num >= 0 && num <= 9) {
gridMakerCase.setCellValue(num);
}
}
}
/**
* Méthode appelée lorsqu'une touche est relâchée.
* Aucun traitement n'est nécessaire dans ce cas.
* @param e L'événement KeyEvent généré lorsque la touche est relâchée.
*/
@Override
public void keyReleased(KeyEvent e) {
// Pas de traitement nécessaire
}
/**
* Méthode appelée lorsqu'une touche est tapée (enfoncée puis relâchée).
* Aucun traitement n'est nécessaire dans ce cas.
* @param e L'événement KeyEvent généré lorsque la touche est tapée.
*/
@Override
public void keyTyped(KeyEvent e) {
// Pas de traitement nécessaire
}
}

View File

@ -1,5 +1,4 @@
import javax.swing.*; import javax.swing.*;
import java.awt.event.*;
/** /**
* La classe GridMakerChecker est utilisée pour vérifier la cohérence de la grille. * La classe GridMakerChecker est utilisée pour vérifier la cohérence de la grille.
@ -8,9 +7,10 @@ import java.awt.event.*;
* @author Moncef STITI * @author Moncef STITI
* @author Marco ORFAO * @author Marco ORFAO
*/ */
public class GridMakerChecker implements ActionListener { public class GridMakerChecker {
private GridMakerGrid grid; private GridMakerGrid grid;
private GridMakerCheckerListener checkerListener;
/** /**
* Constructeur pour créer une instance de GridMakerChecker. * Constructeur pour créer une instance de GridMakerChecker.
@ -18,16 +18,9 @@ public class GridMakerChecker implements ActionListener {
*/ */
public GridMakerChecker(GridMakerGrid grid) { public GridMakerChecker(GridMakerGrid grid) {
this.grid = grid; this.grid = grid;
this.checkerListener = new GridMakerCheckerListener(this);
} }
/**
* Méthode invoquée lorsqu'un bouton est cliqué.
* Lance la vérification de la grille.
* @param e L'événement d'action
*/
public void actionPerformed(ActionEvent e) {
checkGrid();
}
/** /**
* Vérifie si la grille est correcte. * Vérifie si la grille est correcte.

View File

@ -0,0 +1,28 @@
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* La classe GridMakerCheckerListener est utilisée pour gérer les événements liés à la vérification de la grille.
*/
public class GridMakerCheckerListener implements ActionListener {
private GridMakerChecker gridMakerChecker;
/**
* Constructeur de GridMakerCheckerListener.
* @param gridMakerChecker L'instance de GridMakerChecker à utiliser.
*/
public GridMakerCheckerListener(GridMakerChecker gridMakerChecker) {
this.gridMakerChecker = gridMakerChecker;
}
/**
* Méthode invoquée lorsqu'un bouton est cliqué.
* Lance la vérification de la grille.
* @param e L'événement d'action
*/
@Override
public void actionPerformed(ActionEvent e) {
gridMakerChecker.checkGrid();
}
}

View File

@ -2,29 +2,41 @@ import java.awt.Color;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JLabel; import javax.swing.JLabel;
/**
* GSCase représente une case dans une grille de jeu.
* @version 1.0
* @author Moncef STITI
* @author Marco ORFAO
*/
public class GSCase extends JPanel { public class GSCase extends JPanel {
private int primaryValue; private int primaryValue; // Valeur principale de la case
private int secondaryValue = 0; private int secondaryValue = 0; // Deuxième valeur de la case (optionnelle)
private int tertiaryValue = 0; private int tertiaryValue = 0; // Troisième valeur de la case (optionnelle)
private int quaternaryValue = 0; private int quaternaryValue = 0; // Quatrième valeur de la case (optionnelle)
private String text = ""; private String text = ""; // Texte affiché dans la case
protected boolean isInitial = false; protected boolean isInitial = false; // Indique si la valeur de la case est initiale
protected boolean isActive; protected boolean isActive; // Indique si la case est active
private JLabel label = new JLabel(); private JLabel label = new JLabel(); // Étiquette pour afficher le texte
private byte digitCount = 0; private byte digitCount = 0; // Compteur du nombre de valeurs insérées dans la case
protected int positionX; protected int positionX; // Position X de la case dans la grille
protected int positionY; protected int positionY; // Position Y de la case dans la grille
protected GSGrid parentGrid; protected GSGrid parentGrid; // Grille parente de la case
private GSCaseMouseListener mouseListener; // Instance de la classe qui gère les événements de souris private GSCaseMouseListener mouseListener; // Écouteur pour les événements de souris
/**
* Constructeur de la classe GSCase.
* @param grid La grille parente de la case.
* @param x La position X de la case dans la grille.
* @param y La position Y de la case dans la grille.
*/
public GSCase(GSGrid grid, int x, int y) { public GSCase(GSGrid grid, int x, int y) {
this.positionX = x; this.positionX = x;
this.positionY = y; this.positionY = y;
this.primaryValue = 0; this.primaryValue = 0; // Valeur par défaut
this.setBackground(Color.white); this.setBackground(Color.white); // Couleur de fond par défaut
this.parentGrid = grid; this.parentGrid = grid;
this.add(label); this.add(label);
@ -35,126 +47,126 @@ public class GSCase extends JPanel {
this.addMouseListener(this.mouseListener); this.addMouseListener(this.mouseListener);
} }
/** /**
* Configure l'apparence initiale de la case. * Configure l'apparence initiale de la case.
*/ */
public void layoutSetup() { public void layoutSetup() {
this.label.setText(this.primaryValue != 0 ? this.text : ""); this.label.setText(this.primaryValue != 0 ? this.text : "");
this.label.setVisible(true); this.label.setVisible(true);
this.repaint(); this.repaint();
} }
/** /**
* Initialise la case avec une valeur initiale. * Initialise la case avec une valeur initiale.
*/ */
public void initializeCell() { public void initializeCell() {
label.setText(this.text); label.setText(this.text);
this.setBackground(this.isInitial ? Color.lightGray : Color.white); this.setBackground(this.isInitial ? Color.lightGray : Color.white);
layoutSetup(); layoutSetup();
} }
/** /**
* Définit la valeur de la case. * Définit la valeur de la case.
* @param value La valeur à définir pour la case. * @param value La valeur à définir pour la case.
*/ */
public void setValue(int value) { public void setValue(int value) {
this.isInitial = (value != 0); this.isInitial = (value != 0);
this.text = (value != 0) ? String.valueOf(value) : ""; this.text = (value != 0) ? String.valueOf(value) : "";
this.primaryValue = value; this.primaryValue = value;
initializeCell(); initializeCell();
} }
/** /**
* Obtient la valeur de la case. * Obtient la valeur de la case.
* @return La valeur de la case. * @return La valeur de la case.
*/ */
public int getValue(){ public int getValue(){
return this.primaryValue; return this.primaryValue;
} }
/** /**
* Désactive la case. * Désactive la case.
*/ */
public void deactivateCell(){ public void deactivateCell(){
this.isActive = false; this.isActive = false;
this.setBackground(Color.white); this.setBackground(Color.white);
} }
/** /**
* Obtient l'état d'activité de la case. * Obtient l'état d'activité de la case.
* @return True si la case est active, sinon False. * @return True si la case est active, sinon False.
*/ */
public Boolean getActivity(){ public Boolean getActivity(){
return this.isActive; return this.isActive;
} }
/** /**
* Met à jour la valeur de la case. * Met à jour la valeur de la case.
* @param value La nouvelle valeur de la case. * @param value La nouvelle valeur de la case.
*/ */
public void updateValue(int value){ public void updateValue(int value){
if (value == 0) { if (value == 0) {
this.primaryValue = 0; this.primaryValue = 0;
this.digitCount = 0; this.digitCount = 0;
layoutSetup(); layoutSetup();
} else { } else {
if (!checkInputValue(value)) { if (!checkInputValue(value)) {
if (this.primaryValue != value ) { if (this.primaryValue != value ) {
if (this.digitCount == 0) { if (this.digitCount == 0) {
this.digitCount++; this.digitCount++;
this.primaryValue = value; this.primaryValue = value;
this.text = String.valueOf(this.primaryValue); this.text = String.valueOf(this.primaryValue);
} else if (this.digitCount == 1 && value != this.primaryValue) { } else if (this.digitCount == 1 && value != this.primaryValue) {
this.secondaryValue = value; this.secondaryValue = value;
this.digitCount++; this.digitCount++;
this.text = String.valueOf(this.primaryValue + ", " + this.secondaryValue); this.text = String.valueOf(this.primaryValue + ", " + this.secondaryValue);
} else if (this.digitCount == 2 && value != this.primaryValue && value != this.secondaryValue) { } else if (this.digitCount == 2 && value != this.primaryValue && value != this.secondaryValue) {
this.tertiaryValue = value; this.tertiaryValue = value;
this.digitCount++; this.digitCount++;
this.text = String.valueOf(this.primaryValue + ", " + this.secondaryValue + ", " + this.tertiaryValue); this.text = String.valueOf(this.primaryValue + ", " + this.secondaryValue + ", " + this.tertiaryValue);
} else if (this.digitCount == 3 && value != this.primaryValue && value != this.secondaryValue && value != this.tertiaryValue) { } else if (this.digitCount == 3 && value != this.primaryValue && value != this.secondaryValue && value != this.tertiaryValue) {
this.quaternaryValue = value; this.quaternaryValue = value;
this.digitCount++; this.digitCount++;
this.text = String.valueOf(this.primaryValue + ", " + this.secondaryValue + ", " + this.tertiaryValue + ", " + this.quaternaryValue); this.text = String.valueOf(this.primaryValue + ", " + this.secondaryValue + ", " + this.tertiaryValue + ", " + this.quaternaryValue);
}
}
this.setBackground(Color.WHITE);
layoutSetup();
} else if (checkInputValue(value)){
this.setBackground(Color.RED);
} }
} }
this.setBackground(Color.WHITE);
layoutSetup();
} else if (checkInputValue(value)){
this.setBackground(Color.RED);
}
} }
}
/** /**
* Vérifie si la valeur entrée est valide pour la case. * Vérifie si la valeur entrée est valide pour la case.
* @param val La valeur à vérifier. * @param val La valeur à vérifier.
* @return True si la valeur est valide, sinon False. * @return True si la valeur est valide, sinon False.
*/ */
public Boolean checkInputValue(int val){ public Boolean checkInputValue(int val){
int temp = this.primaryValue; int temp = this.primaryValue;
this.primaryValue = val; this.primaryValue = val;
GSTest test = new GSTest(this.parentGrid); GSTest test = new GSTest(this.parentGrid);
Boolean isValid = test.test(); Boolean isValid = test.test();
this.primaryValue = temp; this.primaryValue = temp;
return isValid; return isValid;
} }
/** /**
* Obtient le nombre de valeurs insérées dans la case. * Obtient le nombre de valeurs insérées dans la case.
* @return Le nombre de valeurs insérées. * @return Le nombre de valeurs insérées.
*/ */
public int getDigitCount(){ public int getDigitCount(){
return this.digitCount; return this.digitCount;
} }
/** /**
* Insère une valeur dans la case. * Insère une valeur dans la case.
* @param value La valeur à insérer. * @param value La valeur à insérer.
*/ */
public void insertValue(int value){ public void insertValue(int value){
this.primaryValue = value; this.primaryValue = value;
this.text = String.valueOf(this.primaryValue); this.text = String.valueOf(this.primaryValue);
layoutSetup(); layoutSetup();
} }
} }