Skip to content
Snippets Groups Projects
Commit 3d48f7c3 authored by Hugo Debuyser's avatar Hugo Debuyser
Browse files

Ajout de javadoc pour toutes les classes

parent 4eafa050
Branches
No related tags found
No related merge requests found
Showing
with 464 additions and 239 deletions
...@@ -30,9 +30,8 @@ public class DataStageController { ...@@ -30,9 +30,8 @@ public class DataStageController {
/** /**
* Ouvrir les paramètres des axes de la vue * 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 axesSettingsView = new AxesSettingsView(ClassificationModel.getClassificationModel(), stage, dataStageView);
axesSettingsView.show(); axesSettingsView.show();
} }
......
...@@ -43,7 +43,7 @@ public class LoadDataController { ...@@ -43,7 +43,7 @@ public class LoadDataController {
/** /**
* Valide le fichier sélectionné au préalable * Valide le fichier sélectionné au préalable
*/ */
public void validate() throws IOException { public void validate(){
if (file == null || file.isDirectory() || !file.exists()) { if (file == null || file.isDirectory() || !file.exists()) {
Alert alert = new Alert(Alert.AlertType.ERROR); Alert alert = new Alert(Alert.AlertType.ERROR);
......
...@@ -10,15 +10,11 @@ import javafx.stage.Stage; ...@@ -10,15 +10,11 @@ import javafx.stage.Stage;
import java.io.IOException; import java.io.IOException;
public class MainStageController { public class MainStageController {
@FXML @FXML
Stage stage; Stage stage;
@FXML @FXML
Button classifyData; Button classifyData;
...@@ -28,36 +24,38 @@ public class MainStageController { ...@@ -28,36 +24,38 @@ public class MainStageController {
@FXML @FXML
Label AxesSelected; Label AxesSelected;
private MainStageView mainStageView; private MainStageView mainStageView;
/** /**
* Ouvre l'interface de chargement des données. * 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 loadDataView = new LoadDataView(ClassificationModel.getClassificationModel(), stage);
loadDataView.show(); loadDataView.show();
} }
/** /**
* Ouvre l'interface d'une nouvelle vue. * 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 dataStageView = new DataStageView(ClassificationModel.getClassificationModel());
dataStageView.show(); dataStageView.show();
} }
/** /**
* Ouvre l'interface de la configuration des axes. * 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 axesSettingsView = new AxesSettingsView(ClassificationModel.getClassificationModel(), stage, mainStageView);
axesSettingsView.show(); axesSettingsView.show();
} }
/** /**
* Associe la mainStageView associer à la classe * Associe la mainStageView à la classe.
* @param mainStageView * @param mainStageView Instance de MainStageView à associer.
*/ */
public void setMainStageView(MainStageView mainStageView) { public void setMainStageView(MainStageView mainStageView) {
this.mainStageView = mainStageView; this.mainStageView = mainStageView;
...@@ -65,14 +63,16 @@ public class MainStageController { ...@@ -65,14 +63,16 @@ public class MainStageController {
/** /**
* Ouvre l'interface d'ajout de donnée. * 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 addDataView = new AddDataView(ClassificationModel.getClassificationModel(), stage, mainStageView);
addDataView.show(); 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() { public void classifyDatas() {
ClassificationModel.getClassificationModel().classifierDonnees(); ClassificationModel.getClassificationModel().classifierDonnees();
...@@ -80,24 +80,24 @@ public class MainStageController { ...@@ -80,24 +80,24 @@ public class MainStageController {
} }
/** /**
* Renvoie la grille associé à la classe * Renvoie la grille associée à la classe.
* @return grille de la classe * @return grille de type ScatterChart utilisée pour la visualisation des données.
*/ */
public ScatterChart getScatterChart() { public ScatterChart getScatterChart() {
return this.scatterChart; return this.scatterChart;
} }
/** /**
* Attribut une valeur à l'axe de la grille * Attribue une valeur à l'axe de la grille.
* @param texte Valeur de l'axe * @param texte Valeur de l'axe à afficher sur l'interface.
*/ */
public void setAxesSelected(String texte) { public void setAxesSelected(String texte) {
this.AxesSelected.setText(texte); this.AxesSelected.setText(texte);
} }
/** /**
* Renvoie le bouton de classification de données * Renvoie le bouton de classification de données.
* @return Bouton de classification * @return Bouton utilisé pour déclencher la classification des données.
*/ */
public Button getClassifyData() { public Button getClassifyData() {
return this.classifyData; return this.classifyData;
......
...@@ -9,10 +9,12 @@ import java.nio.file.Files; ...@@ -9,10 +9,12 @@ import java.nio.file.Files;
import java.util.*; import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList; 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 { public class ClassificationModel extends Observable {
private List<LoadableData> datas; private List<LoadableData> datas;
private List<LoadableData> dataToClass; private List<LoadableData> dataToClass;
...@@ -20,33 +22,36 @@ public class ClassificationModel extends Observable { ...@@ -20,33 +22,36 @@ public class ClassificationModel extends Observable {
private static ClassificationModel model; private static ClassificationModel model;
/** /**
* Renvoie une instance unique du model. Par default le type de ce modele est Iris. * Renvoie une instance unique du modèle. Par défaut, le type de ce modèle est Iris.
* Modifier en .setType(DataType). * @return l'instance du modèle
* @return l'instance du model
*/ */
public static ClassificationModel getClassificationModel() { public static ClassificationModel getClassificationModel() {
if(model == null) model = new ClassificationModel(); if(model == null) model = new ClassificationModel();
return model; return model;
} }
/**
* Constructeur privé par défaut.
* Initialise le modèle avec le type de données Iris.
*/
private ClassificationModel() { private ClassificationModel() {
this(DataType.IRIS); this(DataType.IRIS);
} }
/**
* Constructeur privé avec type de données.
* @param type type de données à utiliser pour la classification.
*/
private ClassificationModel(DataType type) { private ClassificationModel(DataType type) {
this.datas = new ArrayList<>(); this.datas = new ArrayList<>();
this.dataToClass = new CopyOnWriteArrayList<>(); this.dataToClass = new CopyOnWriteArrayList<>();
this.type = type; this.type = type;
} }
/** /**
* Ajoute un point au nuage de points avec toutes les données de ce point * Ajoute un point au nuage de points avec toutes les données de ce point.
* @param coords toutes les données du points * @param coords toutes les données du point.
* @throws IllegalArgumentException Exception levée si le nombre de parametres est insuffisant pour creer un point du type du model
*/ */
public void ajouterDonnee(double... coords) { public void ajouterDonnee(double... coords) {
LoadableData newData = PointFactory.createPoint(type, coords); LoadableData newData = PointFactory.createPoint(type, coords);
...@@ -54,59 +59,78 @@ public class ClassificationModel extends Observable { ...@@ -54,59 +59,78 @@ public class ClassificationModel extends Observable {
notifyObservers(newData); notifyObservers(newData);
} }
/** /**
* TODO * Charge les données à partir d'un fichier CSV.
* @param file * @param file fichier contenant les données à charger.
*/ */
public void loadData(File file) throws IOException { public void loadData(File file) {
this.datas = new CsvToBeanBuilder<LoadableData>(Files.newBufferedReader(file.toPath())) try {
.withSeparator(',') this.datas = new CsvToBeanBuilder<LoadableData>(Files.newBufferedReader(file.toPath()))
.withType(Iris.class) .withSeparator(',')
.build().parse(); .withType(Iris.class)
.build().parse();
Set<String> types = new HashSet<>();
for (LoadableData d : datas) { Set<String> types = new HashSet<>();
types.add(d.getClassification()); 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() { public void classifierDonnees() {
dataToClass.forEach(this::classifierDonnee); dataToClass.forEach(this::classifierDonnee);
} }
/** /**
* TODO * Classifie une donnée spécifique.
* @param data * Attribue une classification aléatoire à la donnée fournie et notifie les observateurs.
* @param data donnée à classifier.
*/ */
private void classifierDonnee(LoadableData data) { private void classifierDonnee(LoadableData data) {
List<String> classes = new ArrayList<>(LoadableData.getClassificationTypes()); List<String> classes = new ArrayList<>(LoadableData.getClassificationTypes());
Random rdm = new Random(); Random rdm = new Random();
data.setClassification(classes.get(rdm.nextInt(classes.size()))); data.setClassification(classes.get(rdm.nextInt(classes.size())));
notifyObservers(data); notifyObservers(data);
dataToClass.remove(data); dataToClass.remove(data);
} }
/**
* Définit le type de données à classifier.
* @param type type de données.
*/
public void setType(DataType type) { public void setType(DataType type) {
this.type = type; this.type = type;
} }
/**
* Renvoie la liste des données chargées.
* @return liste des données chargées.
*/
public List<LoadableData> getDatas() { public List<LoadableData> getDatas() {
return datas; return datas;
} }
/**
* Renvoie la liste des données à classifier.
* @return liste des données à classifier.
*/
public List<LoadableData> getDataToClass() { public List<LoadableData> getDataToClass() {
return dataToClass; return dataToClass;
} }
/**
* Renvoie le type de données actuellement défini.
* @return type de données.
*/
public DataType getType() { public DataType getType() {
return type; return type;
} }
......
...@@ -3,8 +3,11 @@ package fr.univlille.sae.classification.model; ...@@ -3,8 +3,11 @@ package fr.univlille.sae.classification.model;
import com.opencsv.bean.CsvBindByName; import com.opencsv.bean.CsvBindByName;
import javafx.scene.paint.Color; 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") @CsvBindByName(column = "sepal.length")
private double sepalLength; private double sepalLength;
...@@ -17,24 +20,50 @@ public class Iris extends LoadableData{ ...@@ -17,24 +20,50 @@ public class Iris extends LoadableData{
@CsvBindByName(column = "variety") @CsvBindByName(column = "variety")
private String 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) { public Iris(double sepalLength, double sepalWidth, double petalLength, double petalWidth) {
this(sepalLength, sepalWidth, petalLength, petalWidth, "undefined"); this(sepalLength, sepalWidth, petalLength, petalWidth, "undefined");
} }
/**
* Constructeur par défaut.
*/
public Iris() { public Iris() {
// //
} }
/**
* Renvoie la classification (variété) de l'Iris.
* @return variété de l'Iris.
*/
@Override @Override
public String getClassification() { public String getClassification() {
return variety; return variety;
} }
/**
* Définit la classification (variété) de l'Iris.
* @param classification variété à définir.
*/
@Override @Override
public void setClassification(String classification) { public void setClassification(String classification) {
this.variety = 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) { public Iris(double sepalLength, double sepalWidth, double petalLength, double petalWidth, String variety) {
super(); super();
this.sepalWidth = sepalWidth; this.sepalWidth = sepalWidth;
...@@ -44,24 +73,45 @@ public class Iris extends LoadableData{ ...@@ -44,24 +73,45 @@ public class Iris extends LoadableData{
this.variety = variety; this.variety = variety;
} }
/**
* Renvoie la largeur du sépale.
* @return largeur du sépale.
*/
public double getSepalWidth() { public double getSepalWidth() {
return sepalWidth; return sepalWidth;
} }
/**
* Renvoie la longueur du sépale.
* @return longueur du sépale.
*/
public double getSepalLength() { public double getSepalLength() {
return sepalLength; return sepalLength;
} }
/**
* Renvoie la largeur du pétale.
* @return largeur du pétale.
*/
public double getPetalWidth() { public double getPetalWidth() {
return petalWidth; return petalWidth;
} }
/**
* Renvoie la longueur du pétale.
* @return longueur du pétale.
*/
public double getPetalLength() { public double getPetalLength() {
return petalLength; 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": case "sepalWidth":
return sepalWidth; return sepalWidth;
case "sepalLength": case "sepalLength":
...@@ -75,8 +125,12 @@ public class Iris extends LoadableData{ ...@@ -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": case "Setosa":
return Color.RED; return Color.RED;
case "Versicolor": case "Versicolor":
...@@ -84,10 +138,14 @@ public class Iris extends LoadableData{ ...@@ -84,10 +138,14 @@ public class Iris extends LoadableData{
case "Virginica": case "Virginica":
return Color.GREEN; return Color.GREEN;
default: 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() { public String[] getAttributesName() {
return new String[]{ return new String[]{
"sepalLength", "sepalLength",
...@@ -97,6 +155,10 @@ public class Iris extends LoadableData{ ...@@ -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 @Override
public String toString() { public String toString() {
return "Iris{" + return "Iris{" +
......
...@@ -4,30 +4,63 @@ import javafx.scene.paint.Color; ...@@ -4,30 +4,63 @@ import javafx.scene.paint.Color;
import java.util.Set; import java.util.Set;
/**
* Classe abstraite représentant des données pouvant être chargées.
*/
public abstract class LoadableData { public abstract class LoadableData {
private static Set<String> classificationTypes; private static Set<String> classificationTypes;
/**
* Constructeur par défaut.
*/
protected LoadableData() { 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() { public static Set<String> getClassificationTypes() {
return classificationTypes; 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) { public static void setClassificationTypes(Set<String> classificationTypes) {
LoadableData.classificationTypes = classificationTypes; LoadableData.classificationTypes = classificationTypes;
} }
/**
* Définit la classification de l'objet.
* @param classification classification à définir.
*/
public abstract void setClassification(String classification); 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(); public abstract String[] getAttributesName();
/**
* Renvoie la couleur associée à l'objet.
* @return couleur correspondant à la classification de l'objet.
*/
public abstract Color getColor(); 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); public abstract double getDataType(String axes);
} }
package fr.univlille.sae.classification.model; package fr.univlille.sae.classification.model;
/**
* Usine pour créer des objets LoadableData en fonction du type de données.
*/
public class PointFactory { 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; int size = coords.length;
LoadableData data; LoadableData data;
switch (type) {
case IRIS: try {
if(size != 4) throw new IllegalArgumentException(); switch (type) {
data = new Iris(coords[0],coords[1],coords[2],coords[3]); case IRIS:
break; if (size != 4) {
default: throw new IllegalArgumentException("Le nombre de coordonnées doit être de 4 pour le type IRIS.");
throw new IllegalArgumentException(); }
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; return data;
......
...@@ -3,20 +3,33 @@ package fr.univlille.sae.classification.utils; ...@@ -3,20 +3,33 @@ package fr.univlille.sae.classification.utils;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
/**
* Classe abstraite représentant un sujet observable.
*/
public abstract class Observable { public abstract class Observable {
protected Collection<Observer> attached = new HashSet<>(); protected Collection<Observer> attached = new HashSet<>();
protected Collection<Observer> toDetach = new HashSet<>(); protected Collection<Observer> toDetach = new HashSet<>();
/**
* Attache un observateur à l'objet observable.
* @param obs observateur à attacher.
*/
public void attach(Observer obs) { public void attach(Observer obs) {
attached.add(obs); attached.add(obs);
} }
/**
* Détache un observateur de l'objet observable.
* @param obs observateur à détacher.
*/
public void detach(Observer obs) { public void detach(Observer obs) {
this.toDetach.add(obs); this.toDetach.add(obs);
} }
/**
* Notifie tous les observateurs attachés de tout changement.
*/
protected void notifyObservers() { protected void notifyObservers() {
this.updateList(); this.updateList();
for (Observer o : attached) { for (Observer o : attached) {
...@@ -24,6 +37,10 @@ public abstract class Observable { ...@@ -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) { protected void notifyObservers(Object data) {
this.updateList(); this.updateList();
for (Observer o : attached) { for (Observer o : attached) {
...@@ -31,9 +48,11 @@ public abstract class Observable { ...@@ -31,9 +48,11 @@ public abstract class Observable {
} }
} }
/**
* Met à jour la liste des observateurs attachés en supprimant ceux à détacher.
*/
private void updateList() { private void updateList() {
this.attached.removeAll(toDetach); this.attached.removeAll(toDetach);
this.toDetach.clear(); this.toDetach.clear();
} }
} }
...@@ -6,8 +6,18 @@ import javafx.scene.control.MenuItem; ...@@ -6,8 +6,18 @@ import javafx.scene.control.MenuItem;
import javafx.scene.shape.Shape; import javafx.scene.shape.Shape;
import javafx.stage.Stage; import javafx.stage.Stage;
/**
* Classe utilitaire pour la gestion des vues.
*/
public class ViewUtil { 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) { public static Shape getForm(LoadableData iris, Shape form, Stage root) {
try { try {
form.setFill(iris.getColor()); form.setFill(iris.getColor());
......
...@@ -11,18 +11,30 @@ import java.io.File; ...@@ -11,18 +11,30 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URL; 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 { public class AddDataView {
private ClassificationModel model; private ClassificationModel model;
private Stage owner; private Stage owner;
private MainStageView mainStageView; 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) { public AddDataView(ClassificationModel model, Stage owner, MainStageView mainStageView) {
this.model = model; this.model = model;
this.owner = owner; this.owner = owner;
this.mainStageView = mainStageView; this.mainStageView = mainStageView;
} }
/**
* Charge le fichier FXML et initialise la scène.
*/
public void show() { public void show() {
FXMLLoader loader = new FXMLLoader(); FXMLLoader loader = new FXMLLoader();
URL fxmlFileUrl = null; URL fxmlFileUrl = null;
......
...@@ -12,18 +12,30 @@ import java.io.File; ...@@ -12,18 +12,30 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
/**
* Classe responsable de la création et de l'affichage de la vue de configuration des axes.
*/
public class AxesSettingsView { public class AxesSettingsView {
private ClassificationModel model; private ClassificationModel model;
private Stage owner; private Stage owner;
private DataVisualizationView dataVisualizationView; 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) { public AxesSettingsView(ClassificationModel model, Stage owner, DataVisualizationView dataVisualizationView) {
this.model = model; this.model = model;
this.owner = owner; this.owner = owner;
this.dataVisualizationView = dataVisualizationView; this.dataVisualizationView = dataVisualizationView;
} }
/**
* Affiche la vue de configuration des axes.
*/
public void show() { public void show() {
FXMLLoader loader = new FXMLLoader(); FXMLLoader loader = new FXMLLoader();
URL fxmlFileUrl = null; URL fxmlFileUrl = null;
......
...@@ -13,8 +13,6 @@ import javafx.fxml.FXMLLoader; ...@@ -13,8 +13,6 @@ import javafx.fxml.FXMLLoader;
import javafx.scene.chart.XYChart; import javafx.scene.chart.XYChart;
import javafx.scene.shape.Circle; import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle; import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage; import javafx.stage.Stage;
import java.io.File; import java.io.File;
...@@ -23,19 +21,26 @@ import java.net.URL; ...@@ -23,19 +21,26 @@ import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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 { public class DataStageView extends DataVisualizationView implements Observer {
private ClassificationModel model; private ClassificationModel model;
private DataStageController controller; private DataStageController controller;
private XYChart.Series series1;
private XYChart.Series series1 ; private XYChart.Series series2;
private XYChart.Series series2 ; private XYChart.Series series3;
private XYChart.Series series3 ; private XYChart.Series series4;
private XYChart.Series series4 ;
private Stage root; 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) { public DataStageView(ClassificationModel model) {
super(); super();
this.model = model; this.model = model;
...@@ -46,31 +51,31 @@ public class DataStageView extends DataVisualizationView implements Observer { ...@@ -46,31 +51,31 @@ public class DataStageView extends DataVisualizationView implements Observer {
model.attach(this); model.attach(this);
} }
/**
* Affiche la vue des données en chargeant le fichier FXML et en initialisant la scène.
*/
public void show() { public void show() {
FXMLLoader loader = new FXMLLoader(); FXMLLoader loader = new FXMLLoader();
try { try {
URL fxmlFileUrl = new File(System.getProperty("user.dir") + File.separator + "res" + File.separator + "stages" + File.separator + "data-view-stage.fxml").toURI().toURL(); 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) { if (fxmlFileUrl == null) {
System.out.println("Impossible de charger le fichier fxml"); System.out.println("Impossible de charger le fichier fxml");
System.exit(-1); System.exit(-1);
} }
loader.setLocation(fxmlFileUrl); loader.setLocation(fxmlFileUrl);
root = loader.load(); root = loader.load();
root.setResizable(false); root.setResizable(false);
root.setTitle("SAE3.3 - Logiciel de classification"); root.setTitle("SAE3.3 - Logiciel de classification");
root.show(); root.show();
loader.getController(); controller = loader.getController();
controller = loader.getController(); controller.setDataStageView(this);
controller.setDataStageView(this); scatterChart = controller.getScatterChart();
scatterChart = controller.getScatterChart();
scatterChart.getData().addAll(series4, series1, series2, series3 );
scatterChart.getData().addAll(series4, series1, series2, series3);
controller.setAxesSelected("Aucun fichier sélectionné"); controller.setAxesSelected("Aucun fichier sélectionné");
if (!model.getDatas().isEmpty()) { if (!model.getDatas().isEmpty()) {
update(model); update(model);
...@@ -80,6 +85,10 @@ public class DataStageView extends DataVisualizationView implements Observer { ...@@ -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 @Override
public void update(Observable observable) { public void update(Observable observable) {
try { try {
...@@ -91,63 +100,57 @@ public class DataStageView extends DataVisualizationView implements Observer { ...@@ -91,63 +100,57 @@ public class DataStageView extends DataVisualizationView implements Observer {
ObservableList<XYChart.Series> series = scatterChart.getData(); ObservableList<XYChart.Series> series = scatterChart.getData();
for(XYChart.Series serie : series) {serie.getData().clear();} for(XYChart.Series serie : series) {serie.getData().clear();}
//Jalon 1: on verifie que le type de donnée est bien IRIS //Jalon 1: on verifie que le type de donnée est bien IRIS
if(model.getType() == DataType.IRIS) { if (model.getType() == DataType.IRIS) {
if(actualX==null && actualY==null){ if (actualX == null && actualY == null) {
controller.setAxesSelected("Aucuns axes sélectionnés"); controller.setAxesSelected("Aucuns axes sélectionnés");
} }
else{ else {
controller.setAxesSelected(""); controller.setAxesSelected("");
//On recupere les données du model //On recupere les données du model
List<LoadableData> points = new ArrayList<>(model.getDatas()); List<LoadableData> points = new ArrayList<>(model.getDatas());
points.addAll(model.getDataToClass()); points.addAll(model.getDataToClass());
// on ajoute chaque point a la serie // on ajoute chaque point a la serie
for(LoadableData i : points) { for (LoadableData i : points) {
Iris iris = (Iris) i;
Iris iris = (Iris)i; XYChart.Data<Double, Double> dataPoint = new XYChart.Data<>(iris.getDataType(actualX),
XYChart.Data<Double, Double> dataPoint = new XYChart.Data<>(iris.getDataType(actualX), iris.getDataType(actualY));
iris.getDataType(actualY));
dataPoint.setNode(ViewUtil.getForm(iris, new Circle(5), root)); dataPoint.setNode(ViewUtil.getForm(iris, new Circle(5), root));
switch (iris.getClassification()) { switch (iris.getClassification()) {
case "Setosa": case "Setosa":
series1.getData().add(dataPoint); series1.getData().add(dataPoint);
break; break;
case "Versicolor": case "Versicolor":
series2.getData().add(dataPoint); series2.getData().add(dataPoint);
break; break;
case "Virginica": case "Virginica":
series3.getData().add(dataPoint); series3.getData().add(dataPoint);
break; break;
default: default:
dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root)); dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root));
series4.getData().add(dataPoint); series4.getData().add(dataPoint);
break; 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) { } catch (Exception e) {
System.err.println("Erreur de mise à jour : " + e.getMessage()); 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 @Override
public void update(Observable observable, Object data) { public void update(Observable observable, Object data) {
try { try {
...@@ -166,20 +169,27 @@ public class DataStageView extends DataVisualizationView implements Observer { ...@@ -166,20 +169,27 @@ public class DataStageView extends DataVisualizationView implements Observer {
iris.getDataType(actualY) iris.getDataType(actualY)
); );
dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root)); dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root));
if (!scatterChart.getData().isEmpty()) { if (!scatterChart.getData().isEmpty()) {
series4.getData().add(dataPoint); series4.getData().add(dataPoint);
}
} }
}
} catch (Exception e) { } catch (Exception e) {
System.err.println("Erreur de mise à jour : " + e.getMessage()); 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() { public DataStageController getController() {
return controller; return controller;
} }
/**
* Recharge les données de la vue en fonction des données du modèle.
*/
@Override @Override
public void reload() { public void reload() {
this.update(ClassificationModel.getClassificationModel()); this.update(ClassificationModel.getClassificationModel());
......
...@@ -2,31 +2,63 @@ package fr.univlille.sae.classification.view; ...@@ -2,31 +2,63 @@ package fr.univlille.sae.classification.view;
import javafx.scene.chart.ScatterChart; 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 { public abstract class DataVisualizationView {
protected DataVisualizationView() {}
protected String actualX; protected String actualX;
protected String actualY; protected String actualY;
protected ScatterChart scatterChart; 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() { public String getActualX() {
return actualX; 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) { public void setActualX(String actualX) {
this.actualX = actualX; this.actualX = actualX;
} }
/**
* Renvoie le nom de l'axe Y actuel.
* @return nom de l'axe Y.
*/
public String getActualY() { public String getActualY() {
return actualY; 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) { public void setActualY(String actualY) {
this.actualY = actualY; this.actualY = actualY;
} }
/**
* Renvoie le graphique de dispersion associé à cette vue.
* @return graphique de dispersion.
*/
public ScatterChart getScatterChart() { public ScatterChart getScatterChart() {
return this.scatterChart; return this.scatterChart;
} }
/**
* Méthode abstraite à implémenter pour recharger les données de la vue.
*/
public abstract void reload(); public abstract void reload();
} }
...@@ -9,16 +9,27 @@ import java.io.File; ...@@ -9,16 +9,27 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
/**
* Classe responsable de l'affichage de la vue de chargement des données.
*/
public class LoadDataView { public class LoadDataView {
private ClassificationModel model; private ClassificationModel model;
private Stage owner; 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) { public LoadDataView(ClassificationModel model, Stage owner) {
this.model = model; this.model = model;
this.owner = owner; this.owner = owner;
} }
/**
* Affiche la fenêtre de chargement des données.
*/
public void show() { public void show() {
FXMLLoader loader = new FXMLLoader(); FXMLLoader loader = new FXMLLoader();
URL fxmlFileUrl = null; URL fxmlFileUrl = null;
......
...@@ -8,18 +8,11 @@ import fr.univlille.sae.classification.model.LoadableData; ...@@ -8,18 +8,11 @@ import fr.univlille.sae.classification.model.LoadableData;
import fr.univlille.sae.classification.utils.Observable; import fr.univlille.sae.classification.utils.Observable;
import fr.univlille.sae.classification.utils.Observer; import fr.univlille.sae.classification.utils.Observer;
import fr.univlille.sae.classification.utils.ViewUtil; import fr.univlille.sae.classification.utils.ViewUtil;
import javafx.application.Application;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.chart.XYChart; import javafx.scene.chart.XYChart;
import javafx.scene.control.Alert; import javafx.scene.control.*;
import javafx.scene.control.ButtonType; import javafx.scene.shape.*;
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.stage.Stage; import javafx.stage.Stage;
import java.io.File; import java.io.File;
...@@ -29,6 +22,9 @@ import java.util.ArrayList; ...@@ -29,6 +22,9 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
/**
* Classe représentant la vue principale de l'application de classification.
*/
public class MainStageView extends DataVisualizationView implements Observer { public class MainStageView extends DataVisualizationView implements Observer {
private ClassificationModel model; private ClassificationModel model;
...@@ -36,68 +32,68 @@ public class MainStageView extends DataVisualizationView implements Observer { ...@@ -36,68 +32,68 @@ public class MainStageView extends DataVisualizationView implements Observer {
private Stage root; private Stage root;
private XYChart.Series series1 ; private XYChart.Series series1;
private XYChart.Series series2 ; private XYChart.Series series2;
private XYChart.Series series3; 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) { public MainStageView(ClassificationModel model) {
super(); super();
this.series1 = new XYChart.Series(); this.series1 = new XYChart.Series();
this.series2 = new XYChart.Series(); this.series2 = new XYChart.Series();
this.series3 = new XYChart.Series(); this.series3 = new XYChart.Series();
this.series4 = new XYChart.Series(); this.series4 = new XYChart.Series();
this.model = model; this.model = model;
model.attach(this); model.attach(this);
} }
/**
* Affiche la vue principale.
*/
public void show() { public void show() {
FXMLLoader loader = new FXMLLoader(); FXMLLoader loader = new FXMLLoader();
try { try {
URL fxmlFileUrl = new File(System.getProperty("user.dir") + File.separator + "res" + File.separator + "stages" + File.separator + "main-stage.fxml").toURI().toURL(); URL fxmlFileUrl = new File(System.getProperty("user.dir") + File.separator + "res" + File.separator + "stages" + File.separator + "main-stage.fxml").toURI().toURL();
if (fxmlFileUrl == null) { if (fxmlFileUrl == null) {
System.out.println("Impossible de charger le fichier fxml"); System.out.println("Impossible de charger le fichier fxml");
System.exit(-1); 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();
} }
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();
}
});
}); controller = loader.getController();
loader.getController(); controller.setMainStageView(this);
controller = loader.getController(); scatterChart = controller.getScatterChart();
controller.setMainStageView(this); scatterChart.getData().addAll(series1, series2, series3, series4);
controller.setAxesSelected("Aucun fichier sélectionné");
scatterChart = controller.getScatterChart();
scatterChart.getData().addAll(series1, series2, series3, series4);
System.out.println("DataStageView scatter chart: " +scatterChart );
controller.setAxesSelected("Aucun fichier sélectionné");
} catch (IOException e) { } catch (IOException e) {
System.err.println("Erreur lors du chargement du fichier FXML : " + e.getMessage()); System.err.println("Erreur lors du chargement du fichier FXML : " + e.getMessage());
} }
} }
@Override @Override
public void update(Observable observable) { public void update(Observable observable) {
try { try {
...@@ -107,62 +103,51 @@ public class MainStageView extends DataVisualizationView implements Observer { ...@@ -107,62 +103,51 @@ public class MainStageView extends DataVisualizationView implements Observer {
} }
ObservableList<XYChart.Series> series = scatterChart.getData(); ObservableList<XYChart.Series> series = scatterChart.getData();
for(XYChart.Series serie : series) {serie.getData().clear();} 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(""); 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()); List<LoadableData> points = new ArrayList<>(model.getDatas());
points.addAll(model.getDataToClass()); points.addAll(model.getDataToClass());
for (LoadableData i : points) { for (LoadableData i : points) {
Iris iris = (Iris) i; Iris iris = (Iris) i;
XYChart.Data<Double, Double> dataPoint = new XYChart.Data<>(iris.getDataType(actualX), XYChart.Data<Double, Double> dataPoint = new XYChart.Data<>(iris.getDataType(actualX), iris.getDataType(actualY));
iris.getDataType(actualY));
dataPoint.setNode(ViewUtil.getForm(iris, new Circle(5), root)); dataPoint.setNode(ViewUtil.getForm(iris, new Circle(5), root));
switch (iris.getClassification()) { switch (iris.getClassification()) {
case "Setosa": case "Setosa":
series1.getData().add(dataPoint); series1.getData().add(dataPoint);
break; break;
case "Versicolor": case "Versicolor":
series2.getData().add(dataPoint); series2.getData().add(dataPoint);
break; break;
case "Virginica": case "Virginica":
series3.getData().add(dataPoint); series3.getData().add(dataPoint);
break; break;
default: default:
dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root)); dataPoint.setNode(ViewUtil.getForm(iris, new Rectangle(10, 10), root));
series4.getData().add(dataPoint); series4.getData().add(dataPoint);
break; break;
}
} }
series1.setName("Setosa");
series2.setName("Versicolor");
series3.setName("Virginica");
series4.setName("indéfini");
} }
}
series1.setName("Setosa"); } catch (Exception e) {
series2.setName("Versicolor");
series3.setName("Virginica");
series4.setName("undefinied");
}
}
}catch (Exception e) {
System.err.println("Erreur de mise à jour : " + e.getMessage()); System.err.println("Erreur de mise à jour : " + e.getMessage());
} }
} }
@Override @Override
public void update(Observable observable, Object data) { public void update(Observable observable, Object data) {
try { try {
...@@ -170,9 +155,9 @@ public class MainStageView extends DataVisualizationView implements Observer { ...@@ -170,9 +155,9 @@ public class MainStageView extends DataVisualizationView implements Observer {
System.err.println("Erreur de mise à jour."); System.err.println("Erreur de mise à jour.");
return; return;
} }
if(data instanceof Iris) { if (data instanceof Iris) {
Iris iris = (Iris) data; Iris iris = (Iris) data;
if(actualX == null || actualY == null) { if (actualX == null || actualY == null) {
controller.setAxesSelected("Aucuns axes sélectionnés"); controller.setAxesSelected("Aucuns axes sélectionnés");
return; return;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment