1,7 → 1,5 |
package org.tela_botanica.client.vues; |
|
|
|
import org.tela_botanica.client.image.ImageMediateur; |
import org.tela_botanica.client.interfaces.Rafraichissable; |
|
21,10 → 19,11 |
import com.gwtext.client.widgets.tree.event.TreePanelListenerAdapter; |
|
/** |
* Arbre des mots clés, qui est une vue rafraichissable, |
* qui contient des mots clés cochables et réorganisables à volonté |
* Arbre des mots clés, qui est une vue rafraichissable, qui contient des mots |
* clés cochables et réorganisables à volonté |
* |
* @author aurelien |
* |
* |
*/ |
public class ArbreMotsClesVue extends Panel implements Rafraichissable { |
|
31,118 → 30,124 |
/** |
* Le médiateur associé à la vue |
*/ |
private ImageMediateur iMediateur = null ; |
|
private ImageMediateur iMediateur = null; |
|
/** |
* Le treepanel qui affiche l'arbre |
*/ |
private TreePanel arbreMotsCles = null ; |
private TreePanel arbreMotsCles = null; |
/** |
* L'éditeur qui permet de modifier les mots clés dans l'arbre |
*/ |
private TreeEditor te = null ; |
private TreeEditor te = null; |
/** |
* Le textfield associé à l'éditeur |
*/ |
private TextField tfEdit = null ; |
private TextField tfEdit = null; |
/** |
* Bouton de validation |
*/ |
private Button valider = null ; |
private Button valider = null; |
/** |
* Une string permettant connaitre les mots clés cochés en cours séparés par des virgules |
* Une string permettant connaitre les mots clés cochés en cours séparés par |
* des virgules |
*/ |
private String motsClesEnCours = "" ; |
private String motsClesEnCours = ""; |
/** |
* Tableau contenant les mots clés qui n'ont pas encore été jaouté à l'arbre |
* (sert au lazy rendering quand on reçoit des mots clés avant que le rendu du conteneur n'ai été effectué) |
* Tableau contenant les mots clés qui n'ont pas encore été jaouté à l'arbre |
* (sert au lazy rendering quand on reçoit des mots clés avant que le rendu |
* du conteneur n'ai été effectué) |
*/ |
private String[] motsClesEnAttente ; |
private String[] motsClesEnAttente; |
/** |
* Booléen d'évènement qui sert à savoir si on est en train d'ajouter un noeud |
* Booléen d'évènement qui sert à savoir si on est en train d'ajouter un |
* noeud |
*/ |
private boolean ajoutNoeud = false ; |
private boolean ajoutNoeud = false; |
/** |
* Booléen d'évènement qui sert à savoir si on est en train de modifier un noeud |
* Booléen d'évènement qui sert à savoir si on est en train de modifier un |
* noeud |
*/ |
private boolean modifNoeud = false ; |
private boolean modifNoeud = false; |
/** |
* Booléen d'instanciation du conteneur |
*/ |
private boolean estInstancie = false ; |
private boolean estInstancie = false; |
/** |
* Booléen d'évènement qui sert à savoir si les mots clés ont bien été reçu |
*/ |
private boolean motsCleInitialises ; |
|
private boolean motsCleInitialises; |
|
/** |
* Constructeur sans paramètre (privé car interdit d'utilisation) |
*/ |
@SuppressWarnings("unused") |
private ArbreMotsClesVue() |
{ |
super() ; |
private ArbreMotsClesVue() { |
super(); |
} |
|
|
/** |
* Constructeur avec paramètre |
* @param im le médiateur à associer |
* |
* @param im |
* le médiateur à associer |
*/ |
public ArbreMotsClesVue(ImageMediateur im) |
{ |
public ArbreMotsClesVue(ImageMediateur im) { |
// on crée le panel |
super("Mots clés") ; |
super("Mots clés"); |
this.setLayout(new VerticalLayout()); |
iMediateur = im ; |
|
iMediateur = im; |
|
// on crée le conteneur de l'arbre |
arbreMotsCles = new TreePanel() ; |
arbreMotsCles = new TreePanel(); |
// on permet le drag and drop dans l'arbre |
arbreMotsCles.setEnableDD(true) ; |
arbreMotsCles.setId("x-view-tree-keyword") ; |
|
arbreMotsCles.setEnableDD(true); |
arbreMotsCles.setId("x-view-tree-keyword"); |
|
// on crée une racine pour l'arbre |
TreeNode root = new TreeNode("Tags") ; |
root.setId("racine") ; |
String[] usObject = {"Mots clés" , "racine" } ; |
root.setUserObject(usObject) ; |
arbreMotsCles.setRootNode(root) ; |
arbreMotsCles.setRootVisible(false) ; |
arbreMotsCles.setBorder(false) ; |
arbreMotsCles.setWidth(500) ; |
|
TreeNode root = new TreeNode("Tags"); |
root.setId("racine"); |
String[] usObject = { "Mots clés", "racine" }; |
root.setUserObject(usObject); |
arbreMotsCles.setRootNode(root); |
arbreMotsCles.setRootVisible(false); |
arbreMotsCles.setBorder(false); |
arbreMotsCles.setWidth(500); |
|
// on crée l'éditeur pour l'arbre |
tfEdit = new TextField() ; |
tfEdit.setAutoWidth(true) ; |
te = new TreeEditor(arbreMotsCles,tfEdit) ; |
valider = new Button("Appliquer") ; |
arbreMotsCles.add(te) ; |
|
tfEdit = new TextField(); |
tfEdit.setAutoWidth(true); |
te = new TreeEditor(arbreMotsCles, tfEdit); |
valider = new Button("Appliquer"); |
arbreMotsCles.add(te); |
|
// on met en forme le layout |
this.add(arbreMotsCles) ; |
this.add(valider) ; |
|
this.setBorder(false) ; |
this.setCollapsible(true) ; |
this.setTitleCollapse(true) ; |
|
this.add(arbreMotsCles); |
this.add(valider); |
|
this.setBorder(false); |
this.setCollapsible(true); |
this.setTitleCollapse(true); |
|
// on ajoute les listeners |
ajouterListeners() ; |
|
ajouterListeners(); |
|
} |
|
|
/** |
* Acesseur pour le médiateur |
* |
* @return le médiateur associé à la vue |
*/ |
private ImageMediateur GetIMediateur() { |
|
return iMediateur ; |
|
|
return iMediateur; |
|
} |
|
|
/** |
* Acesseur pour l'arbre des mots clés |
* |
* @return le panel contenant l'arbre |
*/ |
public TreePanel getArbreMotsCles() { |
151,6 → 156,7 |
|
/** |
* Accesseur pour l'éditeur |
* |
* @return l'éditeur associé à l'arbre |
*/ |
public TreeEditor getTe() { |
159,308 → 165,318 |
|
/** |
* Acesseur pour le TextField associé à l'éditeur |
* |
* @return le champ texte associé à l'éditeur |
*/ |
public TextField getTfEdit() { |
return tfEdit; |
} |
|
|
/** |
* Ajoute les listeners nécessaires pour la gestion des évènements |
*/ |
private void ajouterListeners() |
{ |
private void ajouterListeners() { |
arbreMotsCles.addListener(new TreePanelListenerAdapter() { |
|
|
// gestion du clic sur un noeud |
public void onClick(TreeNode node, EventObject e) { |
|
e.stopEvent() ; |
|
e.stopEvent(); |
gererClicNoeud(node); |
} |
|
// gestion du clic droit sur un noeud |
public void onContextMenu(TreeNode node, EventObject e) { |
|
e.stopEvent() ; |
GetIMediateur().montrerContextMenuArbre(node, e , getTe()) ; |
|
|
e.stopEvent(); |
GetIMediateur().montrerContextMenuArbre(node, e, getTe()); |
|
} |
|
|
// gestion du double clic sur un noeud |
public void onDblClick(TreeNode node, EventObject e) { |
|
modifNoeud = true ; |
if(! node.getId().equals("racine")) |
{ |
|
modifNoeud = true; |
if (!node.getId().equals("racine")) { |
te.startEdit(node); |
} |
} |
|
// gestion de la modification du texte d'un noeud |
|
// gestion de la modification du texte d'un noeud |
public void onTextChange(TreeNode node, String text, String oldText) { |
|
// on récupère les informations associées au noeud |
TreeNode nd = node ; |
String[] usObject = new String[2] ; |
usObject[0] = text ; |
usObject[1] = ((String[])nd.getUserObject())[1] ; |
nd.setUserObject(usObject) ; |
|
TreeNode nd = node; |
String[] usObject = new String[2]; |
usObject[0] = text; |
usObject[1] = ((String[]) nd.getUserObject())[1]; |
nd.setUserObject(usObject); |
|
// si c'est un nouveau noeud |
if(ajoutNoeud) |
{ |
// on notifie le médiateur de l'ajout et on lui passe l'arbre |
GetIMediateur().ajouterMotCleDansArbre(nd,getArbreMotsCles().getTree()) ; |
if (ajoutNoeud) { |
// on notifie le médiateur de l'ajout et on lui passe |
// l'arbre |
GetIMediateur().ajouterMotCleDansArbre(nd, |
getArbreMotsCles().getTree()); |
// et considière l'ajout achevé |
ajoutNoeud = false ; |
ajoutNoeud = false; |
} |
// si c'est noeud déjà existant |
else |
{ |
if(modifNoeud) |
{ |
// on notifie le médiateur de la modification et on lui passe l'arbre |
GetIMediateur().modifierMotCleDansArbre(nd,getArbreMotsCles().getTree()) ; |
else { |
if (modifNoeud) { |
// on notifie le médiateur de la modification et on lui |
// passe l'arbre |
GetIMediateur().modifierMotCleDansArbre(nd, |
getArbreMotsCles().getTree()); |
// et on considère la modification achevée |
modifNoeud = false ; |
modifNoeud = false; |
} |
} |
|
|
} |
|
|
// gestion du déplacement d'un noeud |
public void onMoveNode(Tree tree, TreeNode node, TreeNode oldParent, TreeNode newParent,int index) |
{ |
public void onMoveNode(Tree tree, TreeNode node, |
TreeNode oldParent, TreeNode newParent, int index) { |
// on notifie le médiateur et on lui passe l'arbre |
GetIMediateur().deplacerMotCleDansArbre(node, getArbreMotsCles().getTree()) ; |
} |
|
}) ; |
|
GetIMediateur().deplacerMotCleDansArbre(node, |
getArbreMotsCles().getTree()); |
} |
|
}); |
|
// gestion de la validation |
valider.addListener(new ButtonListenerAdapter() { |
|
|
// lors du clic |
public void onClick(Button button, EventObject e) { |
|
|
// on vide les mots clés en cours |
motsClesEnCours = "" ; |
motsClesEnCours = ""; |
// pour chaque noeud à partir de la racine |
getArbreMotsCles().getRootNode().cascade(new NodeTraversalCallback() { |
|
// on éxécute une fonction |
public boolean execute(Node node) { |
|
// on récupère le mot clé associé au noeud et ses infos |
TreeNode tn = getArbreMotsCles().getNodeById(node.getId()) ; |
getArbreMotsCles().getRootNode().cascade( |
new NodeTraversalCallback() { |
|
String[] usObject = (String[])tn.getUserObject() ; |
GetIMediateur().mettreAjourMotsClesId(usObject[0],usObject[1]) ; |
|
if(tn.getUI().isChecked()) |
{ |
// et les concatène à la string des mots clés en cours |
motsClesEnCours += usObject[1]+"," ; |
} |
|
return true ; |
} |
|
}); |
|
// enfin on notifie le médiateur et on lui passe l'arbre et la liste des mots clés ainsi obtenue |
GetIMediateur().mettreAjourMotsCles(motsClesEnCours,arbreMotsCles.getTree()) ; |
// on éxécute une fonction |
public boolean execute(Node node) { |
|
// on récupère le mot clé associé au noeud et |
// ses infos |
TreeNode tn = getArbreMotsCles().getNodeById( |
node.getId()); |
|
String[] usObject = (String[]) tn |
.getUserObject(); |
GetIMediateur().mettreAjourMotsClesId( |
usObject[0], usObject[1]); |
|
if (tn.getUI().isChecked()) { |
// et les concatène à la string des mots |
// clés en cours |
motsClesEnCours += usObject[1] + ","; |
} |
|
return true; |
} |
|
}); |
|
// enfin on notifie le médiateur et on lui passe l'arbre et la |
// liste des mots clés ainsi obtenue |
GetIMediateur().mettreAjourMotsCles(motsClesEnCours, |
arbreMotsCles.getTree()); |
} |
}) ; |
|
}); |
|
} |
|
|
/** |
* Envoie une demande au médiateur pour obtenir l'arbre des mots clés |
*/ |
public void obtenirArbreMotsCles() { |
|
GetIMediateur().obtenirArbreMotsCles(this) ; |
|
|
GetIMediateur().obtenirArbreMotsCles(this); |
|
} |
|
/** |
* Supprime un noeud de l'arbre |
* @param n le noeud à supprimer |
* |
* @param n |
* le noeud à supprimer |
*/ |
public void supprimerNoeud(TreeNode n) |
{ |
public void supprimerNoeud(TreeNode n) { |
// si ça n'est pas la racine (qu'on ne peut pas supprimer) |
if(!n.getId().equals(getArbreMotsCles().getRootNode().getId())) |
{ |
if (!n.getId().equals(getArbreMotsCles().getRootNode().getId())) { |
// on détache le noeud et on le détruit |
n.getParentNode().removeChild(n); |
n.destroy() ; |
// puis on en notifie le médiateur en lui passant le noeud supprimé et l'arbre |
GetIMediateur().supprimerMotCleDansArbre(n, arbreMotsCles.getTree()) ; |
n.destroy(); |
// puis on en notifie le médiateur en lui passant le noeud supprimé |
// et l'arbre |
GetIMediateur() |
.supprimerMotCleDansArbre(n, arbreMotsCles.getTree()); |
} else { |
// si l'utilisateur tente de supprimer la racine, on l'avertit de |
// son erreur |
Window.alert("Impossible de supprimer la racine de l'arbre"); |
} |
else |
{ |
// si l'utilisateur tente de supprimer la racine, on l'avertit de son erreur |
Window.alert("Impossible de supprimer la racine de l'arbre") ; |
} |
} |
|
|
/** |
* Ajoute un noeud dans l'arbre au parent donné |
* @param parent le futur parent du noeud à ajouter |
* |
* @param parent |
* le futur parent du noeud à ajouter |
*/ |
public void ajouterNoeud(TreeNode parent) |
{ |
|
// on met l'ajout du noeud à vrai |
ajoutNoeud = true ; |
// on crée un nouveau noeud vide |
TreeNode nd = new TreeNode(""); |
nd.setCls("x-view-treenode-keyword") ; |
nd.setChecked(true); |
// on associe un objet au noeud qui contient des infos |
String[] usObject = new String[2] ; |
// l'objet contient le nom du noeud |
usObject[0] = "" ; |
usObject[1] = genererIdMotCle(nd) ; |
nd.setId(usObject[1]) ; |
nd.setUserObject(usObject) ; |
// l'identifiant d'un noeud c'est son hashcode |
// l'objet associé au noeud contient aussi son identifiant |
|
// on le concatène au parent et on étend ses enfants |
parent.appendChild(nd); |
parent.expand() ; |
// enfin on place le curseur et on fait apparaitre le champ d'édition pour que l'utilisateur nomme son mot clé |
te.startEdit(nd); |
public void ajouterNoeud(TreeNode parent) { |
|
|
// on met l'ajout du noeud à vrai |
ajoutNoeud = true; |
// on crée un nouveau noeud vide |
TreeNode nd = new TreeNode(""); |
nd.setCls("x-view-treenode-keyword"); |
nd.setChecked(true); |
// on associe un objet au noeud qui contient des infos |
String[] usObject = new String[2]; |
// l'objet contient le nom du noeud |
usObject[0] = ""; |
usObject[1] = genererIdMotCle(nd); |
nd.setId(usObject[1]); |
nd.setUserObject(usObject); |
// l'identifiant d'un noeud c'est son hashcode |
// l'objet associé au noeud contient aussi son identifiant |
|
// on le concatène au parent et on étend ses enfants |
parent.appendChild(nd); |
parent.expand(); |
// enfin on place le curseur et on fait apparaitre le champ d'édition |
// pour que l'utilisateur nomme son mot clé |
te.startEdit(nd); |
|
} |
|
|
/** |
* Coche le noeud s'il est décoché, le décoche sinon |
* |
* @param node |
*/ |
public void gererClicNoeud(TreeNode node) |
{ |
if(node.getUI().isChecked()) |
{ |
node.getUI().toggleCheck(false) ; |
public void gererClicNoeud(TreeNode node) { |
if (node.getUI().isChecked()) { |
node.getUI().toggleCheck(false); |
} else { |
node.getUI().toggleCheck(true); |
} |
else |
{ |
node.getUI().toggleCheck(true) ; |
} |
} |
|
|
/** |
* Parcourt l'arbre et coche les noeud qui font partie de la liste des mots clés à cocher |
* @param motsClesIds un tableau contenant les identifiants des mots clés à cocher |
* Parcourt l'arbre et coche les noeud qui font partie de la liste des mots |
* clés à cocher |
* |
* @param motsClesIds |
* un tableau contenant les identifiants des mots clés à cocher |
*/ |
public void cocherMotsCles(final String[] motsClesIds) |
{ |
if(getArbreMotsCles() != null && getArbreMotsCles().getRootNode() != null) |
{ |
public void cocherMotsCles(final String[] motsClesIds) { |
if (getArbreMotsCles() != null |
&& getArbreMotsCles().getRootNode() != null) { |
// à partir de la racine |
getArbreMotsCles().getRootNode().cascade(new NodeTraversalCallback() { |
|
// pour chaque noeud |
public boolean execute(Node node) { |
|
// on parcourt le tableau des mots clés |
for(int i = 0 ; i < motsClesIds.length ; i++) |
{ |
// si le mot clé fait partie des id à cocher on le coche |
String usObject[] = (String[])node.getUserObject() ; |
String nodeId = usObject[1] ; |
|
if(nodeId.equals(motsClesIds[i])) |
{ |
getArbreMotsCles().getNodeById(nodeId).getUI().toggleCheck(true) ; |
return true ; |
getArbreMotsCles().getRootNode().cascade( |
new NodeTraversalCallback() { |
|
// pour chaque noeud |
public boolean execute(Node node) { |
|
// on parcourt le tableau des mots clés |
for (int i = 0; i < motsClesIds.length; i++) { |
// si le mot clé fait partie des id à cocher on |
// le coche |
String usObject[] = (String[]) node |
.getUserObject(); |
String nodeId = usObject[1]; |
|
if (nodeId.equals(motsClesIds[i])) { |
getArbreMotsCles().getNodeById(nodeId) |
.getUI().toggleCheck(true); |
return true; |
} |
|
getArbreMotsCles().getNodeById(node.getId()) |
.getUI().toggleCheck(false); |
} |
|
getArbreMotsCles().getNodeById(node.getId()).getUI().toggleCheck(false) ; |
// et on passe au suivant |
return true; |
} |
// et on passe au suivant |
return true; |
} |
|
}) ; |
|
}); |
} |
} |
|
|
/** |
* Méthode héritée de l'interface rafraichissable |
* @param nouvelleDonnees les nouvelles données pour l'objet |
* @param repandreRafraichissement booleen qui dit si on doit répandre l'évenement |
* |
* @param nouvelleDonnees |
* les nouvelles données pour l'objet |
* @param repandreRafraichissement |
* booleen qui dit si on doit répandre l'évenement |
*/ |
public void rafraichir(Object nouvelleDonnees, |
boolean repandreRafraichissement) { |
// si on a reçu un arbre |
if(nouvelleDonnees instanceof Tree) |
{ |
Tree nouvelArbre = (Tree)nouvelleDonnees ; |
|
if(nouvelArbre.getRootNode().getChildNodes().length <= 0) |
{ |
// on crée une racine pour l'arbre |
TreeNode root = new TreeNode("Tags") ; |
root.setId("racine") ; |
String[] usObject = {"Mots clés" , "racine" } ; |
root.setUserObject(usObject) ; |
} |
|
// on prend sa racine et on l'attache à l'arbre des mots clés |
Node[] rootChild = getArbreMotsCles().getRootNode().getChildNodes() ; |
for (int i = 0; i < rootChild.length; i++) { |
|
rootChild[i].remove() ; |
} |
|
getArbreMotsCles().getRootNode().appendChild(nouvelArbre.getRootNode()) ; |
|
// si l'arbre n'était pas encore considéré comme instancié |
if(!estInstancie) |
{ |
// on signale que oui |
estInstancie = true ; |
} |
|
// s'il y a des mots clés en attente (lors du premier rendering) |
if(motsCleInitialises == false && motsClesEnAttente != null) |
{ |
// on les coche |
//cocherMotsCles(motsClesEnAttente) ; |
motsCleInitialises = true ; |
} |
if (nouvelleDonnees instanceof Tree) { |
Tree nouvelArbre = (Tree) nouvelleDonnees; |
|
if (nouvelArbre.getRootNode().getChildNodes().length <= 0) { |
// on crée une racine pour l'arbre |
TreeNode root = new TreeNode("Tags"); |
root.setId("racine"); |
String[] usObject = { "Mots clés", "racine" }; |
root.setUserObject(usObject); |
} |
|
// on prend sa racine et on l'attache à l'arbre des mots clés |
Node[] rootChild = getArbreMotsCles().getRootNode().getChildNodes(); |
for (int i = 0; i < rootChild.length; i++) { |
|
rootChild[i].remove(); |
} |
|
getArbreMotsCles().getRootNode().appendChild( |
nouvelArbre.getRootNode()); |
|
// si l'arbre n'était pas encore considéré comme instancié |
if (!estInstancie) { |
// on signale que oui |
estInstancie = true; |
} |
|
// s'il y a des mots clés en attente (lors du premier rendering) |
if (motsCleInitialises == false && motsClesEnAttente != null) { |
// on les coche |
// cocherMotsCles(motsClesEnAttente) ; |
motsCleInitialises = true; |
} |
} |
|
|
// Si on reçoit un tableau de String (cas ou l'on séléectionne une nouvelle image) |
if(nouvelleDonnees instanceof String[]) |
{ |
|
// Si on reçoit un tableau de String (cas ou l'on séléectionne une |
// nouvelle image) |
if (nouvelleDonnees instanceof String[]) { |
// et que l'arbre est instancié |
if(estInstancie && nouvelleDonnees != null) |
{ |
// le tableau de String contient les id des mots clés associés à l'image |
if (estInstancie && nouvelleDonnees != null) { |
// le tableau de String contient les id des mots clés associés à |
// l'image |
// on coche les mots clés contenu dans le tableau |
String[] motsClesIds = (String[])nouvelleDonnees ; |
cocherMotsCles(motsClesIds) ; |
String[] motsClesIds = (String[]) nouvelleDonnees; |
cocherMotsCles(motsClesIds); |
} |
// si l'arbre n'est pas encore instancié on met les mots clés en attente |
else |
{ |
motsClesEnAttente = (String[])nouvelleDonnees ; |
// si l'arbre n'est pas encore instancié on met les mots clés en |
// attente |
else { |
motsClesEnAttente = (String[]) nouvelleDonnees; |
} |
} |
} |
|
private String genererIdMotCle(TreeNode nd) |
{ |
return ""+(nd.hashCode()+(Math.random()*10000)) ; |
|
private String genererIdMotCle(TreeNode nd) { |
return "" + (nd.hashCode() + (Math.random() * 10000)); |
} |
|
} |