diff --git a/src/main/java/fr/univlille/sae/classification/controller/DataStageController.java b/src/main/java/fr/univlille/sae/classification/controller/DataStageController.java index acc6a45394c82e88bba20c100a3ee967a80a620c..2f2e7eb62f318718eabba414f051b0be645e94ee 100644 --- a/src/main/java/fr/univlille/sae/classification/controller/DataStageController.java +++ b/src/main/java/fr/univlille/sae/classification/controller/DataStageController.java @@ -30,9 +30,8 @@ public class DataStageController { /** * Ouvrir les paramètres des axes de la vue - * @throws IOException */ - public void openAxesSetting()throws IOException { + public void openAxesSetting(){ AxesSettingsView axesSettingsView = new AxesSettingsView(ClassificationModel.getClassificationModel(), stage, dataStageView); axesSettingsView.show(); } diff --git a/src/main/java/fr/univlille/sae/classification/controller/LoadDataController.java b/src/main/java/fr/univlille/sae/classification/controller/LoadDataController.java index b0009cecf85c5c2900d539b11ffe04ba4a64ff6e..a8b099878bb1e0758fd6ce577e6e2c680087ea82 100644 --- a/src/main/java/fr/univlille/sae/classification/controller/LoadDataController.java +++ b/src/main/java/fr/univlille/sae/classification/controller/LoadDataController.java @@ -43,7 +43,7 @@ public class LoadDataController { /** * Valide le fichier sélectionné au préalable */ - public void validate() throws IOException { + public void validate(){ if (file == null || file.isDirectory() || !file.exists()) { Alert alert = new Alert(Alert.AlertType.ERROR); diff --git a/src/main/java/fr/univlille/sae/classification/controller/MainStageController.java b/src/main/java/fr/univlille/sae/classification/controller/MainStageController.java index 9b468c2296dce5d90765c04ea35bc34f9119532d..2251cee76bdc98d2d9d56c282a777aa2775ca0dd 100644 --- a/src/main/java/fr/univlille/sae/classification/controller/MainStageController.java +++ b/src/main/java/fr/univlille/sae/classification/controller/MainStageController.java @@ -10,15 +10,11 @@ import javafx.stage.Stage; import java.io.IOException; - public class MainStageController { - @FXML Stage stage; - - @FXML Button classifyData; @@ -28,36 +24,38 @@ public class MainStageController { @FXML Label AxesSelected; - private MainStageView mainStageView; /** * Ouvre l'interface de chargement des données. + * Permet à l'utilisateur de sélectionner des données à charger pour la classification. */ - public void openLoadData() throws IOException { + public void openLoadData() { LoadDataView loadDataView = new LoadDataView(ClassificationModel.getClassificationModel(), stage); loadDataView.show(); } /** * Ouvre l'interface d'une nouvelle vue. + * Affiche une nouvelle fenêtre pour visualiser les données après classification. */ - public void openDataView() throws IOException { + public void openDataView() { DataStageView dataStageView = new DataStageView(ClassificationModel.getClassificationModel()); dataStageView.show(); } /** * Ouvre l'interface de la configuration des axes. + * Permet à l'utilisateur de définir les axes du graphique. */ - public void openAxesSetting()throws IOException { + public void openAxesSetting() { AxesSettingsView axesSettingsView = new AxesSettingsView(ClassificationModel.getClassificationModel(), stage, mainStageView); axesSettingsView.show(); } /** - * Associe la mainStageView associer à la classe - * @param mainStageView + * Associe la mainStageView à la classe. + * @param mainStageView Instance de MainStageView à associer. */ public void setMainStageView(MainStageView mainStageView) { this.mainStageView = mainStageView; @@ -65,14 +63,16 @@ public class MainStageController { /** * Ouvre l'interface d'ajout de donnée. + * Permet à l'utilisateur d'ajouter de nouvelles données à classifier. */ - public void openAddData() throws IOException { + public void openAddData() { AddDataView addDataView = new AddDataView(ClassificationModel.getClassificationModel(), stage, mainStageView); addDataView.show(); } /** - * Appelle de la méthode de la classe ClassificationModel afin de classifier les nouvelles données + * Appelle la méthode de la classe ClassificationModel afin de classifier les nouvelles données. + * Désactive le bouton de classification après l'appel de la méthode. */ public void classifyDatas() { ClassificationModel.getClassificationModel().classifierDonnees(); @@ -80,24 +80,24 @@ public class MainStageController { } /** - * Renvoie la grille associé à la classe - * @return grille de la classe + * Renvoie la grille associée à la classe. + * @return grille de type ScatterChart utilisée pour la visualisation des données. */ public ScatterChart getScatterChart() { return this.scatterChart; } /** - * Attribut une valeur à l'axe de la grille - * @param texte Valeur de l'axe + * Attribue une valeur à l'axe de la grille. + * @param texte Valeur de l'axe à afficher sur l'interface. */ public void setAxesSelected(String texte) { this.AxesSelected.setText(texte); } /** - * Renvoie le bouton de classification de données - * @return Bouton de classification + * Renvoie le bouton de classification de données. + * @return Bouton utilisé pour déclencher la classification des données. */ public Button getClassifyData() { return this.classifyData; diff --git a/src/main/java/fr/univlille/sae/classification/model/ClassificationModel.java b/src/main/java/fr/univlille/sae/classification/model/ClassificationModel.java index 86d57ff5db5742371bf80d64c7955af3ec48c46f..4e0b3616ec3476f7608b25dbe31ef210e710659c 100644 --- a/src/main/java/fr/univlille/sae/classification/model/ClassificationModel.java +++ b/src/main/java/fr/univlille/sae/classification/model/ClassificationModel.java @@ -9,10 +9,12 @@ import java.nio.file.Files; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; - +/** + * Modèle de classification des données. + * Gère le chargement, l'ajout et la classification des données. + */ public class ClassificationModel extends Observable { - private List<LoadableData> datas; private List<LoadableData> dataToClass; @@ -20,33 +22,36 @@ public class ClassificationModel extends Observable { private static ClassificationModel model; - /** - * Renvoie une instance unique du model. Par default le type de ce modele est Iris. - * Modifier en .setType(DataType). - * @return l'instance du model + * Renvoie une instance unique du modèle. Par défaut, le type de ce modèle est Iris. + * @return l'instance du modèle */ public static ClassificationModel getClassificationModel() { if(model == null) model = new ClassificationModel(); return model; } - + /** + * Constructeur privé par défaut. + * Initialise le modèle avec le type de données Iris. + */ private ClassificationModel() { this(DataType.IRIS); } + /** + * Constructeur privé avec type de données. + * @param type type de données à utiliser pour la classification. + */ private ClassificationModel(DataType type) { this.datas = new ArrayList<>(); this.dataToClass = new CopyOnWriteArrayList<>(); this.type = type; } - /** - * Ajoute un point au nuage de points avec toutes les données de ce point - * @param coords toutes les données du points - * @throws IllegalArgumentException Exception levée si le nombre de parametres est insuffisant pour creer un point du type du model + * Ajoute un point au nuage de points avec toutes les données de ce point. + * @param coords toutes les données du point. */ public void ajouterDonnee(double... coords) { LoadableData newData = PointFactory.createPoint(type, coords); @@ -54,59 +59,78 @@ public class ClassificationModel extends Observable { notifyObservers(newData); } - /** - * TODO - * @param file + * Charge les données à partir d'un fichier CSV. + * @param file fichier contenant les données à charger. */ - public void loadData(File file) throws IOException { - this.datas = new CsvToBeanBuilder<LoadableData>(Files.newBufferedReader(file.toPath())) - .withSeparator(',') - .withType(Iris.class) - .build().parse(); - - Set<String> types = new HashSet<>(); - for (LoadableData d : datas) { - types.add(d.getClassification()); + public void loadData(File file) { + try { + this.datas = new CsvToBeanBuilder<LoadableData>(Files.newBufferedReader(file.toPath())) + .withSeparator(',') + .withType(Iris.class) + .build().parse(); + + Set<String> types = new HashSet<>(); + for (LoadableData d : datas) { + types.add(d.getClassification()); + } + + LoadableData.setClassificationTypes(types); + notifyObservers(); + } catch (IOException e) { + System.err.println("Erreur lors du chargement des données : " + e.getMessage()); } - - LoadableData.setClassificationTypes(types); - notifyObservers(); } - + /** + * Classifie toutes les données à classifier. + * Parcourt la liste des données à classifier et appelle la méthode pour chaque donnée. + */ public void classifierDonnees() { dataToClass.forEach(this::classifierDonnee); } /** - * TODO - * @param data + * Classifie une donnée spécifique. + * Attribue une classification aléatoire à la donnée fournie et notifie les observateurs. + * @param data donnée à classifier. */ private void classifierDonnee(LoadableData data) { - List<String> classes = new ArrayList<>(LoadableData.getClassificationTypes()); Random rdm = new Random(); data.setClassification(classes.get(rdm.nextInt(classes.size()))); notifyObservers(data); dataToClass.remove(data); - } - + /** + * Définit le type de données à classifier. + * @param type type de données. + */ public void setType(DataType type) { this.type = type; } - + /** + * Renvoie la liste des données chargées. + * @return liste des données chargées. + */ public List<LoadableData> getDatas() { return datas; } + /** + * Renvoie la liste des données à classifier. + * @return liste des données à classifier. + */ public List<LoadableData> getDataToClass() { return dataToClass; } + /** + * Renvoie le type de données actuellement défini. + * @return type de données. + */ public DataType getType() { return type; } diff --git a/src/main/java/fr/univlille/sae/classification/model/Iris.java b/src/main/java/fr/univlille/sae/classification/model/Iris.java index 4e6686907b00d59aacd2c232d209980bf514fe6a..864e82c33ff0257cf6cd1de35dba3fffebc14798 100644 --- a/src/main/java/fr/univlille/sae/classification/model/Iris.java +++ b/src/main/java/fr/univlille/sae/classification/model/Iris.java @@ -3,8 +3,11 @@ package fr.univlille.sae.classification.model; import com.opencsv.bean.CsvBindByName; import javafx.scene.paint.Color; -public class Iris extends LoadableData{ - +/** + * Représente un point Iris. + * Contient des informations sur les dimensions des sépales et des pétales et sur la variété de la fleur. + */ +public class Iris extends LoadableData { @CsvBindByName(column = "sepal.length") private double sepalLength; @@ -17,24 +20,50 @@ public class Iris extends LoadableData{ @CsvBindByName(column = "variety") private String variety; + /** + * Constructeur pour créer une instance de Iris avec les dimensions des sépales et des pétales. + * @param sepalLength longueur du sépale. + * @param sepalWidth largeur du sépale. + * @param petalLength longueur du pétale. + * @param petalWidth largeur du pétale. + */ public Iris(double sepalLength, double sepalWidth, double petalLength, double petalWidth) { this(sepalLength, sepalWidth, petalLength, petalWidth, "undefined"); } + /** + * Constructeur par défaut. + */ public Iris() { // } + /** + * Renvoie la classification (variété) de l'Iris. + * @return variété de l'Iris. + */ @Override public String getClassification() { return variety; } + /** + * Définit la classification (variété) de l'Iris. + * @param classification variété à définir. + */ @Override public void setClassification(String classification) { this.variety = classification; } + /** + * Constructeur pour créer une instance de Iris avec tous les attributs. + * @param sepalLength longueur du sépale. + * @param sepalWidth largeur du sépale. + * @param petalLength longueur du pétale. + * @param petalWidth largeur du pétale. + * @param variety variété de l'Iris. + */ public Iris(double sepalLength, double sepalWidth, double petalLength, double petalWidth, String variety) { super(); this.sepalWidth = sepalWidth; @@ -44,24 +73,45 @@ public class Iris extends LoadableData{ this.variety = variety; } + /** + * Renvoie la largeur du sépale. + * @return largeur du sépale. + */ public double getSepalWidth() { return sepalWidth; } + /** + * Renvoie la longueur du sépale. + * @return longueur du sépale. + */ public double getSepalLength() { return sepalLength; } + /** + * Renvoie la largeur du pétale. + * @return largeur du pétale. + */ public double getPetalWidth() { return petalWidth; } + /** + * Renvoie la longueur du pétale. + * @return longueur du pétale. + */ public double getPetalLength() { return petalLength; } - public double getDataType(String axes){ - switch (axes){ + /** + * Renvoie la valeur des données en fonction de l'axe spécifié. + * @param axes nom de l'axe pour lequel la valeur est requise. + * @return valeur correspondante. + */ + public double getDataType(String axes) { + switch (axes) { case "sepalWidth": return sepalWidth; case "sepalLength": @@ -75,8 +125,12 @@ public class Iris extends LoadableData{ } } - public Color getColor(){ - switch (this.variety){ + /** + * Renvoie la couleur associée à la variété de l'Iris. + * @return couleur correspondant à la variété. + */ + public Color getColor() { + switch (this.variety) { case "Setosa": return Color.RED; case "Versicolor": @@ -84,10 +138,14 @@ public class Iris extends LoadableData{ case "Virginica": return Color.GREEN; default: - return Color.BLACK; + return Color.BLACK; // Couleur par défaut si la variété est inconnue } } + /** + * Renvoie les noms des attributs de l'Iris. + * @return tableau de chaînes contenant les noms des attributs. + */ public String[] getAttributesName() { return new String[]{ "sepalLength", @@ -97,6 +155,10 @@ public class Iris extends LoadableData{ }; } + /** + * Représentation sous forme de chaîne de l'objet Iris. + * @return chaîne contenant les dimensions de l'Iris. + */ @Override public String toString() { return "Iris{" + diff --git a/src/main/java/fr/univlille/sae/classification/model/LoadableData.java b/src/main/java/fr/univlille/sae/classification/model/LoadableData.java index 28b6b9d4675bf85498238dbfd63924f2528b65df..cde0e9aa344bdc518eae900c98c5c226cb64e985 100644 --- a/src/main/java/fr/univlille/sae/classification/model/LoadableData.java +++ b/src/main/java/fr/univlille/sae/classification/model/LoadableData.java @@ -4,30 +4,63 @@ import javafx.scene.paint.Color; import java.util.Set; +/** + * Classe abstraite représentant des données pouvant être chargées. + */ public abstract class LoadableData { private static Set<String> classificationTypes; + /** + * Constructeur par défaut. + */ protected LoadableData() { - } - public abstract String getClassification() ; + /** + * Renvoie la classification de l'objet. + * @return classification sous forme de chaîne. + */ + public abstract String getClassification(); + /** + * Renvoie les types de classification définis. + * @return ensemble de types de classification. + */ public static Set<String> getClassificationTypes() { return classificationTypes; } + /** + * Définit les types de classification disponibles. + * @param classificationTypes ensemble de types de classification à définir. + */ public static void setClassificationTypes(Set<String> classificationTypes) { LoadableData.classificationTypes = classificationTypes; } + /** + * Définit la classification de l'objet. + * @param classification classification à définir. + */ public abstract void setClassification(String classification); + /** + * Renvoie les noms des attributs de l'objet. + * @return tableau de chaînes contenant les noms des attributs. + */ public abstract String[] getAttributesName(); + /** + * Renvoie la couleur associée à l'objet. + * @return couleur correspondant à la classification de l'objet. + */ public abstract Color getColor(); + /** + * Renvoie la valeur des données en fonction de l'axe spécifié. + * @param axes nom de l'axe pour lequel la valeur est requise. + * @return valeur correspondante. + */ public abstract double getDataType(String axes); - } diff --git a/src/main/java/fr/univlille/sae/classification/model/PointFactory.java b/src/main/java/fr/univlille/sae/classification/model/PointFactory.java index 7ee05ec8bb8c6581e49a7b615910af5bb2aa01e1..0a6c59ed4356e4ad67cd5853d694e1a9b941881a 100644 --- a/src/main/java/fr/univlille/sae/classification/model/PointFactory.java +++ b/src/main/java/fr/univlille/sae/classification/model/PointFactory.java @@ -1,19 +1,35 @@ package fr.univlille.sae.classification.model; +/** + * Usine pour créer des objets LoadableData en fonction du type de données. + */ public class PointFactory { - - public static LoadableData createPoint(DataType type, double[] coords) { - + /** + * Crée un point de données en fonction du type spécifié et des coordonnées fournies. + * @param type type de données + * @param coords coordonnées du point à créer. + * @return instance de LoadableData correspondant aux coordonnées, ou null en cas d'erreur. + * @throws IllegalArgumentException si le nombre de coordonnées ne correspond pas au type spécifié. + */ + public static LoadableData createPoint(DataType type, double[] coords) { int size = coords.length; LoadableData data; - switch (type) { - case IRIS: - if(size != 4) throw new IllegalArgumentException(); - data = new Iris(coords[0],coords[1],coords[2],coords[3]); - break; - default: - throw new IllegalArgumentException(); + + try { + switch (type) { + case IRIS: + if (size != 4) { + throw new IllegalArgumentException("Le nombre de coordonnées doit être de 4 pour le type IRIS."); + } + data = new Iris(coords[0], coords[1], coords[2], coords[3]); + break; + default: + throw new IllegalArgumentException("Type de données non supporté : " + type); + } + } catch (IllegalArgumentException e) { + System.err.println("Erreur lors de la création du point : " + e.getMessage()); + return null; } return data; diff --git a/src/main/java/fr/univlille/sae/classification/utils/Observable.java b/src/main/java/fr/univlille/sae/classification/utils/Observable.java index 78a076d96c9ba7fc6afd725bad3ad2e9e8a0d86c..00a0d47c6bd6daaece5cb36a2738d483320b6bbd 100644 --- a/src/main/java/fr/univlille/sae/classification/utils/Observable.java +++ b/src/main/java/fr/univlille/sae/classification/utils/Observable.java @@ -3,20 +3,33 @@ package fr.univlille.sae.classification.utils; import java.util.Collection; import java.util.HashSet; +/** + * Classe abstraite représentant un sujet observable. + */ public abstract class Observable { - protected Collection<Observer> attached = new HashSet<>(); protected Collection<Observer> toDetach = new HashSet<>(); + /** + * Attache un observateur à l'objet observable. + * @param obs observateur à attacher. + */ public void attach(Observer obs) { attached.add(obs); } + /** + * Détache un observateur de l'objet observable. + * @param obs observateur à détacher. + */ public void detach(Observer obs) { this.toDetach.add(obs); } + /** + * Notifie tous les observateurs attachés de tout changement. + */ protected void notifyObservers() { this.updateList(); for (Observer o : attached) { @@ -24,6 +37,10 @@ public abstract class Observable { } } + /** + * Notifie tous les observateurs attachés avec des données supplémentaires. + * @param data données à transmettre aux observateurs. + */ protected void notifyObservers(Object data) { this.updateList(); for (Observer o : attached) { @@ -31,9 +48,11 @@ public abstract class Observable { } } + /** + * Met à jour la liste des observateurs attachés en supprimant ceux à détacher. + */ private void updateList() { this.attached.removeAll(toDetach); this.toDetach.clear(); } - } diff --git a/src/main/java/fr/univlille/sae/classification/utils/ViewUtil.java b/src/main/java/fr/univlille/sae/classification/utils/ViewUtil.java index 79391022a6d6e0b028e6db6ed0c1dc0479aab920..2708d44ea44034a6a9ca88191ac249a14ab5d807 100644 --- a/src/main/java/fr/univlille/sae/classification/utils/ViewUtil.java +++ b/src/main/java/fr/univlille/sae/classification/utils/ViewUtil.java @@ -6,8 +6,18 @@ import javafx.scene.control.MenuItem; import javafx.scene.shape.Shape; import javafx.stage.Stage; +/** + * Classe utilitaire pour la gestion des vues. + */ public class ViewUtil { + /** + * Définit la couleur de la forme + * @param iris objet de données à afficher. + * @param form forme à configurer. + * @param root scène principale pour le menu contextuel. + * @return forme configurée. + */ public static Shape getForm(LoadableData iris, Shape form, Stage root) { try { form.setFill(iris.getColor()); diff --git a/src/main/java/fr/univlille/sae/classification/view/AddDataView.java b/src/main/java/fr/univlille/sae/classification/view/AddDataView.java index a6a495f70fdcdc5425809aa766e6e26b9568c52c..a220919c3c6efc9973f3338feb81b5a7bfbd76d8 100644 --- a/src/main/java/fr/univlille/sae/classification/view/AddDataView.java +++ b/src/main/java/fr/univlille/sae/classification/view/AddDataView.java @@ -11,18 +11,30 @@ import java.io.File; import java.io.IOException; import java.net.URL; +/** + * Classe responsable de la création et de l'affichage de la vue d'ajout de données. + */ public class AddDataView { private ClassificationModel model; private Stage owner; private MainStageView mainStageView; + /** + * Constructeur pour initialiser la vue d'ajout de données. + * @param model le modèle de classification utilisé pour gérer les données. + * @param owner la fenêtre parente de cette vue. + * @param mainStageView la vue principale associée. + */ public AddDataView(ClassificationModel model, Stage owner, MainStageView mainStageView) { this.model = model; this.owner = owner; this.mainStageView = mainStageView; } + /** + * Charge le fichier FXML et initialise la scène. + */ public void show() { FXMLLoader loader = new FXMLLoader(); URL fxmlFileUrl = null; diff --git a/src/main/java/fr/univlille/sae/classification/view/AxesSettingsView.java b/src/main/java/fr/univlille/sae/classification/view/AxesSettingsView.java index 999e8176d6f3f4ce6690540134965633628646e1..70aa3ea9d39a7ff8662685c65061da9e49cc1a89 100644 --- a/src/main/java/fr/univlille/sae/classification/view/AxesSettingsView.java +++ b/src/main/java/fr/univlille/sae/classification/view/AxesSettingsView.java @@ -12,18 +12,30 @@ import java.io.File; import java.io.IOException; import java.net.URL; +/** + * Classe responsable de la création et de l'affichage de la vue de configuration des axes. + */ public class AxesSettingsView { private ClassificationModel model; private Stage owner; private DataVisualizationView dataVisualizationView; + /** + * Constructeur pour initialiser la vue de configuration des axes. + * @param model modèle de classification utilisé pour gérer les données. + * @param owner fenêtre parente de cette vue. + * @param dataVisualizationView vue de visualisation des données associée. + */ public AxesSettingsView(ClassificationModel model, Stage owner, DataVisualizationView dataVisualizationView) { this.model = model; this.owner = owner; this.dataVisualizationView = dataVisualizationView; } + /** + * Affiche la vue de configuration des axes. + */ public void show() { FXMLLoader loader = new FXMLLoader(); URL fxmlFileUrl = null; diff --git a/src/main/java/fr/univlille/sae/classification/view/DataStageView.java b/src/main/java/fr/univlille/sae/classification/view/DataStageView.java index fd721c1b61a1d56513ca0f6b67b0cbf496455315..efd846ba40c927472296b3d2108e8379830477a5 100644 --- a/src/main/java/fr/univlille/sae/classification/view/DataStageView.java +++ b/src/main/java/fr/univlille/sae/classification/view/DataStageView.java @@ -13,8 +13,6 @@ import javafx.fxml.FXMLLoader; import javafx.scene.chart.XYChart; import javafx.scene.shape.Circle; import javafx.scene.shape.Rectangle; -import javafx.scene.shape.Shape; -import javafx.scene.shape.Rectangle; import javafx.stage.Stage; import java.io.File; @@ -23,19 +21,26 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; +/** + * Classe responsable de l'affichage et de la gestion de la vue des données. + * Implémente l'interface Observer pour recevoir des notifications de mise à jour. + */ public class DataStageView extends DataVisualizationView implements Observer { private ClassificationModel model; private DataStageController controller; - - private XYChart.Series series1 ; - private XYChart.Series series2 ; - private XYChart.Series series3 ; - private XYChart.Series series4 ; + private XYChart.Series series1; + private XYChart.Series series2; + private XYChart.Series series3; + private XYChart.Series series4; private Stage root; + /** + * Constructeur pour initialiser la vue de données. + * @param model le modèle de classification utilisé pour gérer les données. + */ public DataStageView(ClassificationModel model) { super(); this.model = model; @@ -46,31 +51,31 @@ public class DataStageView extends DataVisualizationView implements Observer { model.attach(this); } + /** + * Affiche la vue des données en chargeant le fichier FXML et en initialisant la scène. + */ public void show() { FXMLLoader loader = new FXMLLoader(); try { URL fxmlFileUrl = new File(System.getProperty("user.dir") + File.separator + "res" + File.separator + "stages" + File.separator + "data-view-stage.fxml").toURI().toURL(); - if (fxmlFileUrl == null) { - System.out.println("Impossible de charger le fichier fxml"); - System.exit(-1); - } - loader.setLocation(fxmlFileUrl); - root = loader.load(); - root.setResizable(false); - root.setTitle("SAE3.3 - Logiciel de classification"); - root.show(); - loader.getController(); - controller = loader.getController(); - controller.setDataStageView(this); - scatterChart = controller.getScatterChart(); - - scatterChart.getData().addAll(series4, series1, series2, series3 ); - + if (fxmlFileUrl == null) { + System.out.println("Impossible de charger le fichier fxml"); + System.exit(-1); + } + loader.setLocation(fxmlFileUrl); + root = loader.load(); + root.setResizable(false); + root.setTitle("SAE3.3 - Logiciel de classification"); + root.show(); + controller = loader.getController(); + controller.setDataStageView(this); + scatterChart = controller.getScatterChart(); + scatterChart.getData().addAll(series4, series1, series2, series3); - controller.setAxesSelected("Aucun fichier sélectionné"); + controller.setAxesSelected("Aucun fichier sélectionné"); if (!model.getDatas().isEmpty()) { update(model); @@ -80,6 +85,10 @@ public class DataStageView extends DataVisualizationView implements Observer { } } + /** + * Met à jour l'affichage des données en fonction des changements dans le modèle. + * @param observable modèle observé. + */ @Override public void update(Observable observable) { try { @@ -91,63 +100,57 @@ public class DataStageView extends DataVisualizationView implements Observer { ObservableList<XYChart.Series> series = scatterChart.getData(); for(XYChart.Series serie : series) {serie.getData().clear();} - - - //Jalon 1: on verifie que le type de donnée est bien IRIS - if(model.getType() == DataType.IRIS) { - if(actualX==null && actualY==null){ - controller.setAxesSelected("Aucuns axes sélectionnés"); - } - else{ - controller.setAxesSelected(""); - - //On recupere les données du model - List<LoadableData> points = new ArrayList<>(model.getDatas()); - points.addAll(model.getDataToClass()); - // on ajoute chaque point a la serie - for(LoadableData i : points) { - - Iris iris = (Iris)i; - XYChart.Data<Double, Double> dataPoint = new XYChart.Data<>(iris.getDataType(actualX), - iris.getDataType(actualY)); - + if (model.getType() == DataType.IRIS) { + if (actualX == null && actualY == null) { + controller.setAxesSelected("Aucuns axes sélectionnés"); + } + else { + controller.setAxesSelected(""); + + //On recupere les données du model + List<LoadableData> points = new ArrayList<>(model.getDatas()); + points.addAll(model.getDataToClass()); + // on ajoute chaque point a la serie + for (LoadableData i : points) { + Iris iris = (Iris) i; + XYChart.Data<Double, Double> dataPoint = new XYChart.Data<>(iris.getDataType(actualX), + iris.getDataType(actualY)); dataPoint.setNode(ViewUtil.getForm(iris, new Circle(5), root)); - switch (iris.getClassification()) { - case "Setosa": - series1.getData().add(dataPoint); - break; - case "Versicolor": - series2.getData().add(dataPoint); - break; - case "Virginica": - series3.getData().add(dataPoint); - break; - default: - dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root)); - series4.getData().add(dataPoint); - break; + switch (iris.getClassification()) { + case "Setosa": + series1.getData().add(dataPoint); + break; + case "Versicolor": + series2.getData().add(dataPoint); + break; + case "Virginica": + series3.getData().add(dataPoint); + break; + default: + dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root)); + series4.getData().add(dataPoint); + break; + } + + series1.setName("Setosa"); + series2.setName("Versicolor"); + series3.setName("Virginica"); + series4.setName("indefini"); } - - - series1.setName("Setosa"); - series2.setName("Versicolor"); - series3.setName("Virginica"); - series4.setName("undefinied"); - } } - - } } catch (Exception e) { System.err.println("Erreur de mise à jour : " + e.getMessage()); } - - - } + /** + * Met à jour l'affichage en ajoutant un nouveau point de données. + * @param observable modèle observé. + * @param data point de données à ajouter. + */ @Override public void update(Observable observable, Object data) { try { @@ -166,20 +169,27 @@ public class DataStageView extends DataVisualizationView implements Observer { iris.getDataType(actualY) ); - dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root)); - if (!scatterChart.getData().isEmpty()) { - series4.getData().add(dataPoint); + dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root)); + if (!scatterChart.getData().isEmpty()) { + series4.getData().add(dataPoint); + } } - } } catch (Exception e) { System.err.println("Erreur de mise à jour : " + e.getMessage()); } } + /** + * Renvoie le contrôleur associé à cette vue. + * @return contrôleur de la vue. + */ public DataStageController getController() { return controller; } + /** + * Recharge les données de la vue en fonction des données du modèle. + */ @Override public void reload() { this.update(ClassificationModel.getClassificationModel()); diff --git a/src/main/java/fr/univlille/sae/classification/view/DataVisualizationView.java b/src/main/java/fr/univlille/sae/classification/view/DataVisualizationView.java index fd6757379be8e74f0903511c25872f56b27db1cd..c3ad5af65602dcf8a469e619d393a5955429e562 100644 --- a/src/main/java/fr/univlille/sae/classification/view/DataVisualizationView.java +++ b/src/main/java/fr/univlille/sae/classification/view/DataVisualizationView.java @@ -2,31 +2,63 @@ package fr.univlille.sae.classification.view; import javafx.scene.chart.ScatterChart; +/** + * Classe abstraite représentant une vue de visualisation des données. + * Elle gère les axes actuels et le graphique de dispersion. + */ public abstract class DataVisualizationView { - protected DataVisualizationView() {} + protected String actualX; protected String actualY; protected ScatterChart scatterChart; + /** + * Constructeur par défaut. + */ + protected DataVisualizationView() {} + + /** + * Renvoie le nom de l'axe X actuel. + * @return nom de l'axe X. + */ public String getActualX() { return actualX; } + /** + * Définit le nom de l'axe X actuel. + * @param actualX nom de l'axe X à définir. + */ public void setActualX(String actualX) { this.actualX = actualX; } + /** + * Renvoie le nom de l'axe Y actuel. + * @return nom de l'axe Y. + */ public String getActualY() { return actualY; } + /** + * Définit le nom de l'axe Y actuel. + * @param actualY nom de l'axe Y à définir. + */ public void setActualY(String actualY) { this.actualY = actualY; } + /** + * Renvoie le graphique de dispersion associé à cette vue. + * @return graphique de dispersion. + */ public ScatterChart getScatterChart() { return this.scatterChart; } + /** + * Méthode abstraite à implémenter pour recharger les données de la vue. + */ public abstract void reload(); } diff --git a/src/main/java/fr/univlille/sae/classification/view/LoadDataView.java b/src/main/java/fr/univlille/sae/classification/view/LoadDataView.java index 4ece4c3509f00d695926eac378c8754f9850959e..31e19836f488a3d8e8f5615716199c3440273d58 100644 --- a/src/main/java/fr/univlille/sae/classification/view/LoadDataView.java +++ b/src/main/java/fr/univlille/sae/classification/view/LoadDataView.java @@ -9,16 +9,27 @@ import java.io.File; import java.io.IOException; import java.net.URL; +/** + * Classe responsable de l'affichage de la vue de chargement des données. + */ public class LoadDataView { private ClassificationModel model; private Stage owner; + /** + * Constructeur de la vue de chargement des données. + * @param model modèle de classification à utiliser. + * @param owner fenêtre parente. + */ public LoadDataView(ClassificationModel model, Stage owner) { this.model = model; this.owner = owner; } + /** + * Affiche la fenêtre de chargement des données. + */ public void show() { FXMLLoader loader = new FXMLLoader(); URL fxmlFileUrl = null; diff --git a/src/main/java/fr/univlille/sae/classification/view/MainStageView.java b/src/main/java/fr/univlille/sae/classification/view/MainStageView.java index 74523537bafd58a92b91f7eb178b696f0750df02..bb96b1651bae24ac638216592ef41b60e901633c 100644 --- a/src/main/java/fr/univlille/sae/classification/view/MainStageView.java +++ b/src/main/java/fr/univlille/sae/classification/view/MainStageView.java @@ -8,18 +8,11 @@ import fr.univlille.sae.classification.model.LoadableData; import fr.univlille.sae.classification.utils.Observable; import fr.univlille.sae.classification.utils.Observer; import fr.univlille.sae.classification.utils.ViewUtil; -import javafx.application.Application; import javafx.collections.ObservableList; -import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.chart.XYChart; -import javafx.scene.control.Alert; -import javafx.scene.control.ButtonType; -import javafx.scene.control.ContextMenu; -import javafx.scene.control.MenuItem; -import javafx.scene.shape.Circle; -import javafx.scene.shape.Rectangle; -import javafx.scene.shape.Shape; +import javafx.scene.control.*; +import javafx.scene.shape.*; import javafx.stage.Stage; import java.io.File; @@ -29,6 +22,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +/** + * Classe représentant la vue principale de l'application de classification. + */ public class MainStageView extends DataVisualizationView implements Observer { private ClassificationModel model; @@ -36,68 +32,68 @@ public class MainStageView extends DataVisualizationView implements Observer { private Stage root; - private XYChart.Series series1 ; - private XYChart.Series series2 ; + private XYChart.Series series1; + private XYChart.Series series2; private XYChart.Series series3; - private XYChart.Series series4 ; + private XYChart.Series series4; + /** + * Constructeur de la vue principale. + * @param model modèle de classification à utiliser. + */ public MainStageView(ClassificationModel model) { super(); this.series1 = new XYChart.Series(); this.series2 = new XYChart.Series(); this.series3 = new XYChart.Series(); this.series4 = new XYChart.Series(); - this.model = model; model.attach(this); } - + /** + * Affiche la vue principale. + */ public void show() { FXMLLoader loader = new FXMLLoader(); try { URL fxmlFileUrl = new File(System.getProperty("user.dir") + File.separator + "res" + File.separator + "stages" + File.separator + "main-stage.fxml").toURI().toURL(); - if (fxmlFileUrl == null) { - System.out.println("Impossible de charger le fichier fxml"); - System.exit(-1); - } - loader.setLocation(fxmlFileUrl); - root = loader.load(); - root.setResizable(false); - root.setTitle("SAE3.3 - Logiciel de classification"); - root.show(); - root.setOnCloseRequest(event -> { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - alert.setTitle("Confirmation"); - alert.setHeaderText("Voulez vous quitter l'application ?"); - alert.setContentText("Aucunes modifications ne sera sauvegardé ! Les points qui ont été ajoutés ne seront pas sauvegardés"); - Optional<ButtonType> optionalButtonType = alert.showAndWait(); - if(optionalButtonType.isPresent() && optionalButtonType.get() == ButtonType.OK) { - System.exit(0); - }else { - event.consume(); + if (fxmlFileUrl == null) { + System.out.println("Impossible de charger le fichier fxml"); + System.exit(-1); } + loader.setLocation(fxmlFileUrl); + root = loader.load(); + root.setResizable(false); + root.setTitle("SAE3.3 - Logiciel de classification"); + root.show(); + + root.setOnCloseRequest(event -> { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle("Confirmation"); + alert.setHeaderText("Voulez-vous quitter l'application ?"); + alert.setContentText("Aucunes modifications ne seront sauvegardées ! Les points ajoutés ne seront pas sauvegardés."); + Optional<ButtonType> optionalButtonType = alert.showAndWait(); + if (optionalButtonType.isPresent() && optionalButtonType.get() == ButtonType.OK) { + System.exit(0); + } else { + event.consume(); + } + }); - }); - loader.getController(); - controller = loader.getController(); - controller.setMainStageView(this); - - scatterChart = controller.getScatterChart(); - scatterChart.getData().addAll(series1, series2, series3, series4); - - System.out.println("DataStageView scatter chart: " +scatterChart ); - controller.setAxesSelected("Aucun fichier sélectionné"); + controller = loader.getController(); + controller.setMainStageView(this); + scatterChart = controller.getScatterChart(); + scatterChart.getData().addAll(series1, series2, series3, series4); + controller.setAxesSelected("Aucun fichier sélectionné"); } catch (IOException e) { System.err.println("Erreur lors du chargement du fichier FXML : " + e.getMessage()); } - } - @Override public void update(Observable observable) { try { @@ -107,62 +103,51 @@ public class MainStageView extends DataVisualizationView implements Observer { } ObservableList<XYChart.Series> series = scatterChart.getData(); - for(XYChart.Series serie : series) {serie.getData().clear();} - - - - //Jalon 1: on verifie que le type de donnée est bien IRIS - if(model.getType() == DataType.IRIS) { - - - if(actualX==null && actualY==null){ - controller.setAxesSelected("Aucuns axes sélectionnés"); + for (XYChart.Series serie : series) { + serie.getData().clear(); } - else{ - controller.setAxesSelected(""); + + if (model.getType() == DataType.IRIS) { + if (actualX == null && actualY == null) { + controller.setAxesSelected("Aucuns axes sélectionnés"); + } else { + controller.setAxesSelected(""); List<LoadableData> points = new ArrayList<>(model.getDatas()); points.addAll(model.getDataToClass()); for (LoadableData i : points) { - Iris iris = (Iris) i; - XYChart.Data<Double, Double> dataPoint = new XYChart.Data<>(iris.getDataType(actualX), - iris.getDataType(actualY)); - + XYChart.Data<Double, Double> dataPoint = new XYChart.Data<>(iris.getDataType(actualX), iris.getDataType(actualY)); dataPoint.setNode(ViewUtil.getForm(iris, new Circle(5), root)); - switch (iris.getClassification()) { - case "Setosa": - series1.getData().add(dataPoint); - break; - case "Versicolor": - series2.getData().add(dataPoint); - break; - case "Virginica": - series3.getData().add(dataPoint); - break; - default: - dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root)); - series4.getData().add(dataPoint); - break; + switch (iris.getClassification()) { + case "Setosa": + series1.getData().add(dataPoint); + break; + case "Versicolor": + series2.getData().add(dataPoint); + break; + case "Virginica": + series3.getData().add(dataPoint); + break; + default: + dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root)); + series4.getData().add(dataPoint); + break; + } } + series1.setName("Setosa"); + series2.setName("Versicolor"); + series3.setName("Virginica"); + series4.setName("indéfini"); } - - series1.setName("Setosa"); - series2.setName("Versicolor"); - series3.setName("Virginica"); - series4.setName("undefinied"); - - } - } - }catch (Exception e) { + } + } catch (Exception e) { System.err.println("Erreur de mise à jour : " + e.getMessage()); } } - - @Override public void update(Observable observable, Object data) { try { @@ -170,9 +155,9 @@ public class MainStageView extends DataVisualizationView implements Observer { System.err.println("Erreur de mise à jour."); return; } - if(data instanceof Iris) { + if (data instanceof Iris) { Iris iris = (Iris) data; - if(actualX == null || actualY == null) { + if (actualX == null || actualY == null) { controller.setAxesSelected("Aucuns axes sélectionnés"); return; }