diff --git a/ProjetJava/src/main/java/db/Dao.java b/ProjetJava/src/main/java/dao/Dao.java similarity index 95% rename from ProjetJava/src/main/java/db/Dao.java rename to ProjetJava/src/main/java/dao/Dao.java index 54bb2ce9ac8a5124043738aa1702446a0397e2ad..2ecf68fc84f3366a0224e4c87a349149561fc482 100644 --- a/ProjetJava/src/main/java/db/Dao.java +++ b/ProjetJava/src/main/java/dao/Dao.java @@ -1,11 +1,13 @@ -package db; +package dao; +import db.DbConnection; +import db.DbConnectionException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; -import views.Identifiable; +import models.Identifiable; /** * diff --git a/ProjetJava/src/main/java/db/DaoQuestion.java b/ProjetJava/src/main/java/dao/DaoQuestion.java similarity index 75% rename from ProjetJava/src/main/java/db/DaoQuestion.java rename to ProjetJava/src/main/java/dao/DaoQuestion.java index 736533482ad1519f85d0c1a82d5455c687fbe829..7b7fffab8411104fea31ab3b3bc37dfdf04cab0e 100644 --- a/ProjetJava/src/main/java/db/DaoQuestion.java +++ b/ProjetJava/src/main/java/dao/DaoQuestion.java @@ -1,9 +1,11 @@ -package db; +package dao; +import db.DbConnection; +import db.DbConnectionException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import views.Questions; +import models.Questions; /** * @@ -79,4 +81,28 @@ public class DaoQuestion extends Dao { throw new DbConnectionException(ex); } } + + /** + * + * @param level Permet de récupérer une question de manière aléatoire depuis + * la base de données + * @return + */ + public Questions getRandomQuestion(int level) { + Questions question = null; + + // Fix later (Selectionne aléatoirement une question) + String sql = "SELECT * FROM questions WHERE level <= ? ORDER BY RAND() LIMIT 1"; + + try (PreparedStatement stmt = db.DbConnection.getConnection().prepareStatement(sql)) { + stmt.setInt(1, level); + var rs = stmt.executeQuery(); + if (rs.next()) { + question = createEntity(rs); + } + } catch (SQLException ex) { + throw new db.DbConnectionException(ex); + } + return question; + } } diff --git a/ProjetJava/src/main/java/db/DbConnectionException.java b/ProjetJava/src/main/java/db/DbConnectionException.java index 89a02e295b2071f4aff8b2e9c7ba2b481dcb81ce..02d386d5367d4f9a6c4d8d1eed285d37f510fc22 100644 --- a/ProjetJava/src/main/java/db/DbConnectionException.java +++ b/ProjetJava/src/main/java/db/DbConnectionException.java @@ -4,7 +4,7 @@ package db; * * @author Vincent */ -class DbConnectionException extends RuntimeException { +public class DbConnectionException extends RuntimeException { public DbConnectionException() { } diff --git a/ProjetJava/src/main/java/main/projetjava/ProjetJava.java b/ProjetJava/src/main/java/main/projetjava/ProjetJava.java index 08b37b28597bcf8e008b3ed4f8d6e96cd2c64ae7..0a274f3ed2df6ed733280ce578c404048697f3d4 100644 --- a/ProjetJava/src/main/java/main/projetjava/ProjetJava.java +++ b/ProjetJava/src/main/java/main/projetjava/ProjetJava.java @@ -1,12 +1,11 @@ /* * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license */ - package main.projetjava; -import db.DaoQuestion; +import dao.DaoQuestion; import db.DbConnection; -import views.Questions; +import models.Questions; /** * @@ -16,7 +15,7 @@ public class ProjetJava { public static void main(String[] args) { var daoq = new DaoQuestion(); - + for (Questions question : daoq.list()) { System.out.println("question = " + question); } diff --git a/ProjetJava/src/main/java/views/Identifiable.java b/ProjetJava/src/main/java/models/Identifiable.java similarity index 88% rename from ProjetJava/src/main/java/views/Identifiable.java rename to ProjetJava/src/main/java/models/Identifiable.java index de4056505ad41fbe2a0d7cefcd3e74d4afe6a6ec..814030b01bbfe8c64ae45dd613d5dd27ed589b2d 100644 --- a/ProjetJava/src/main/java/views/Identifiable.java +++ b/ProjetJava/src/main/java/models/Identifiable.java @@ -1,4 +1,4 @@ -package views; +package models; /** * diff --git a/ProjetJava/src/main/java/models/Question.java b/ProjetJava/src/main/java/models/Question.java new file mode 100644 index 0000000000000000000000000000000000000000..0589446e0cc08da80aeec81b564a3cf8ca739636 --- /dev/null +++ b/ProjetJava/src/main/java/models/Question.java @@ -0,0 +1,67 @@ +package models; + +/** + * + * @author Axel L. + */ +public class Question { + + private int id; + private int level; + private String question; + private String answer; + + + // Constructeur sans ID + public Question(int level, String question, String answer) { + this.level = level; + this.question = question; + this.answer = answer; + } + + // Getter / Setter + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public String getQuestion() { + return question; + } + + public void setQuestion(String question) { + this.question = question; + } + + public String getAnswer() { + return answer; + } + + public void setAnswer(String answer) { + this.answer = answer; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Question{"); + sb.append("id=").append(id); + sb.append(", level=").append(level); + sb.append(", question=").append(question); + sb.append(", answer=").append(answer); + sb.append('}'); + return sb.toString(); + } + +} diff --git a/ProjetJava/src/main/java/views/Questions.java b/ProjetJava/src/main/java/models/Questions.java similarity index 98% rename from ProjetJava/src/main/java/views/Questions.java rename to ProjetJava/src/main/java/models/Questions.java index e6f430526e6c08bdba8b5de42cea5be98138401d..d0894a54e81b42a73f0a83c8c492666fb8ef8ce5 100644 --- a/ProjetJava/src/main/java/views/Questions.java +++ b/ProjetJava/src/main/java/models/Questions.java @@ -1,4 +1,4 @@ -package views; +package models; /** * diff --git a/ProjetJava/src/main/java/services/QuestionService.java b/ProjetJava/src/main/java/services/QuestionService.java new file mode 100644 index 0000000000000000000000000000000000000000..2df5d01bf1022f7c575d137e8e20ee2c72e27aa8 --- /dev/null +++ b/ProjetJava/src/main/java/services/QuestionService.java @@ -0,0 +1,46 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ +package services; + +import dao.DaoQuestion; +import java.text.Normalizer; +import models.Questions; + +/** + * + * @author Axel L. + */ +public class QuestionService { + + private final DaoQuestion daoQuestion; + + public QuestionService() { + this.daoQuestion = new DaoQuestion(); + } + + // Retourne une question au hasard + public Questions pickQuestion(int level) { + return daoQuestion.getRandomQuestion(level); + } + + // Vérifie si l'entrée utilisateur matche la réponse de la question + public boolean validateAnswer(String textUser, String textAnswer) { + // Retourne faux sir les champs sont vides + if (textUser == null || textAnswer == null) { + return false; + } + + // Nettoie la valeur de l'utilisateur pour respecter la casse (minucule) + String cleanInputUser = Normalizer.normalize(textUser, Normalizer.Form.NFD) + .toLowerCase(); + + // Nettoie la valeur de la réponse pour respecter la casse (minucule) + String cleanAnswer = Normalizer.normalize(textAnswer, Normalizer.Form.NFD) + .toLowerCase(); + + // Retourne la comparaison + return cleanInputUser.equals(cleanAnswer); + } +} diff --git a/ProjetJava/src/main/java/views/PrimaryWindow.java b/ProjetJava/src/main/java/views/PrimaryWindow.java index dc912b84a62cd1a52753f331e6dadcab0a194eba..01a2298ac3d075b58c7dcbfc0a3092909d1e7d5d 100644 --- a/ProjetJava/src/main/java/views/PrimaryWindow.java +++ b/ProjetJava/src/main/java/views/PrimaryWindow.java @@ -69,9 +69,7 @@ public class PrimaryWindow extends JFrame { panelCalcul.add(new JLabel("Exercices de calcul")); // Question - JPanel panelQuestion = new JPanel(); - panelQuestion.setBackground(new Color(230, 255, 230)); - panelQuestion.add(new JLabel("Questions réponses")); + QuestionPanel panelQuestion = new QuestionPanel(); // Ajout des onglets visibles tabbedPane.addTab("Dessin", panelDessin); diff --git a/ProjetJava/src/main/java/views/QuestionPanel.java b/ProjetJava/src/main/java/views/QuestionPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..220198441d9f421709a9b2b71b30fb9a3ffd7073 --- /dev/null +++ b/ProjetJava/src/main/java/views/QuestionPanel.java @@ -0,0 +1,128 @@ +package views; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import models.Questions; +import services.QuestionService; + +/** + * + * @author Axel L. + */ +public final class QuestionPanel extends JPanel { + + private JLabel title, labelQuestion; + private JTextField textResponse; + private JButton btnCheck, btnSolution, btnNewQuestion; + + // Récupération du service et de la question + private QuestionService service; + private Questions currentQuestion; + + // Niveau par défaut + private int currentLevel = 1; + + public QuestionPanel() { + + // ---- DESIGN ---- \\ + // Layout principal + setLayout(new BorderLayout()); + + // Une grille de 2 lignes et 1 colonne + JPanel container = new JPanel(new GridLayout(2, 1, 0, 30)); + + // Affichage de la question + JPanel panelQuestion = new JPanel(new FlowLayout(FlowLayout.CENTER)); + labelQuestion = new JLabel("Placeholder Question"); + labelQuestion.setFont(new Font("Arial", Font.BOLD, 36)); + panelQuestion.add(labelQuestion); + + // Affichage du label et champ de saisie + JPanel panelResponse = new JPanel(new FlowLayout(FlowLayout.CENTER)); + JLabel labelReponse = new JLabel("Votre réponse : "); + labelReponse.setFont(new Font("Arial", Font.PLAIN, 16)); + textResponse = new JTextField(20); + textResponse.setFont(new Font("Arial", Font.PLAIN, 16)); + + panelResponse.add(labelReponse); + panelResponse.add(textResponse); + + // Ajout des deux lignes dans la grille + container.add(panelQuestion); + container.add(panelResponse); + + // Mettre le container dans un container centré + JPanel containerCenter = new JPanel(new GridBagLayout()); + containerCenter.add(container); + + // Bouton (Partie SUD) + JPanel panelSud = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 20)); + btnCheck = new JButton("Vérifier"); + // Couleur + btnCheck.setBackground(new Color(76, 128, 45)); + // Couleur texte + btnCheck.setForeground(Color.WHITE); + // Taille (horizontal, vertical) + btnCheck.setPreferredSize(new Dimension(200, 30)); + + btnSolution = new JButton("Solution"); + btnSolution.setPreferredSize(new Dimension(200, 30)); + + btnNewQuestion = new JButton("Autre question"); + btnNewQuestion.setPreferredSize(new Dimension(200, 30)); + + panelSud.add(btnCheck); + panelSud.add(btnSolution); + panelSud.add(btnNewQuestion); + + // Assemblage + add(containerCenter, BorderLayout.CENTER); + add(panelSud, BorderLayout.SOUTH); + + // ---- EVENT ---- \\ + // Instance service + this.service = new QuestionService(); + + // Initialise une question au lancement + loadNewQuestion(); + + // ActionListener afin de faire en sorte que le bouton "Autre question" change la question en lançant la fonction loadNewQuestion + btnNewQuestion.addActionListener(e -> loadNewQuestion()); + // ActionListener permet de récupérer la réponse (en base de données) et de l'ajouter dans l'input + btnSolution.addActionListener(e -> { + if (currentQuestion != null) { + textResponse.setText(currentQuestion.getAnswer()); + } + }); + // ActionLister pour comparer la valeur entré par l'utilisateur et la valeur réelle de la question actuelle + btnCheck.addActionListener(e -> { + + }); + } + + /** + * Utilise le service afin de récupérer une question par rapport à son + * niveau et l'affiche dans la fenêtre du jeu + */ + public void loadNewQuestion() { + currentQuestion = service.pickQuestion(currentLevel); + + if (currentQuestion != null) { + labelQuestion.setText(currentQuestion.getQuestion()); + textResponse.setText(""); + textResponse.requestFocusInWindow(); + } else { + labelQuestion.setText("Pas de question récupérée"); + } + } + +}