- From: Antoine Dutot <antoine.dutot AT gmail.com>
- To: graphstream-users AT litislab.fr
- Subject: Re: Interactions avec le graphe via un GUI
- Date: Tue, 10 May 2011 09:28:48 +0200
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; b=IPNquxWNOSOO43W0db5RiFHuY4EM553Bur2moeY5txtdQ75GTlkrUn8RtaimtyIMVX LWlVPwIdZj4Aqd4XZ7d9cy0azY6Ak4aMir5m2YgQsq6wfC5gxgjjht4JdV7ZxiAN4H0E z1QNl3OsJurQsZn7qvAtx51nqRKUnWSuoCqKs=
Bonjour,
Tout cela est probablement un peu plus compliqué que cela ne le
devrait. On essayera de changer ça pour les prochaines releases !
Le principe consiste à écouter les évènements qui proviennent du
viewer. Le viewer est un listener (sink) sur le graphe, donc les
événements se produisant sur le graphe ne peuvent aller que vers le
viewer. Cependant, le viewer, tout comme le graphe produit aussi des
évènements, on peut former une boucle en faisant en sorte que le
graphe soit listener du viewer, toute modification de l'un ou de
l'autre se synchronisant sur les deux. Le
système de mise en forme qui positionne les nœuds automatiquement ne
communique qu'avec le viewer, ce qui explique pourquoi les positions
des nœuds ne sont pas répercutées automatiquement sur le graphe sans
cette boucle d'évènements.
Les évènements ne sont que des attributs stockés sur le graphe,
cependant, pour rendre les choses plus pratiques, une classe
ViewerListener a été créée qui lit ces attributs et appelle des
listeners. Il suffit d'étendre l'interface ViewerListener et
d'implanter trois méthodes "viewClosed", "buttonPushed",
"buttonReleased" (d'autres types d'évènements sont prévus). Les deux
dernières prennent en argument l'identifiant du nœud clické.
On crée un viewer comme usuellement:
Graph graph = new MultiGraph("foo");
Viewer viewer = graph.display();
Puis on récupère un objet nous permettant de traiter les événements du
viewer sur le graphe. Sur cet objet, on installe comme sink le Graph
(ce qui nous permettra de copier les attributs du viewer dans le
graphe), et comme listener d'évènements notre ViewerListener (qui
extraira certains attributs du graphe et les transformera en appel de
méthode vers le ViewerListener):
ViewerPipe fromView = viewer.newViewerPipe();
fromView.addAttributeSink(graph);
fromView.addViewerListener(this);
Comme souvent le graphe et le viewer ne sont pas dans le même thread,
il faut régulièrement récupérer les attributs sur le viewer pour le
copier dans le graphe, on fait cela avec la méthode fromView.pump().
Quand on travaille directement dans le thread Swing, il devrait y
avoir une méthode plus simple avec un listener qui n'utilise pas
pump(), mais elle n'est pas encore implantée malheureusement.
Malheureusement, en testant ces opérations, j'ai trouvé un petit bug
dans ViewerPipe qui empêche de recevoir les clics souris. C'est
corrigé sur le repository git, mais pas dans la version que vous devez
avoir. Voici en attaché un jar gs-core.jar à jour.
Voici un programme qui réalise ces opérations. Tous les attributs
modifiés par le viewer se trouvent copié dans le graphe, donc aussi
les positions des nœuds, en commentaire dans le programme se trouve un
moyen de récupérer ces positions grâce à la méthode
Toolkit.nodePosition().
import org.graphstream.graph.Graph;
import org.graphstream.graph.Node;
import org.graphstream.graph.implementations.MultiGraph;
import org.graphstream.ui.swingViewer.Viewer;
import org.graphstream.ui.swingViewer.ViewerListener;
import org.graphstream.ui.swingViewer.ViewerPipe;
import static org.graphstream.algorithm.Toolkit.*;
public class TestEvents implements ViewerListener {
public static void main(String args[]) {
new TestEvents();
}
public TestEvents() {
Graph graph = new MultiGraph("main graph");
Viewer viewer = graph.display();
ViewerPipe fromView = viewer.newViewerPipe();
fromView.addAttributeSink(graph);
fromView.addViewerListener(this);
graph.addNode("A");
graph.addNode("B");
graph.addNode("C");
graph.addEdge("AB", "A", "B");
graph.addEdge("BC", "B", "C");
graph.addEdge("CA", "C", "A");
while(true) {
fromView.pump();
try { Thread.sleep(10); } catch (Exception e) {}
// System.out.printf("Node positions:%n");
// for(Node node:graph) {
// double[] pos = nodePosition(node);
// System.out.printf(" [%s] (%f, %f, %f)%n",
node.getId(),
pos[0], pos[1], pos[2]);
// }
}
}
public void viewClosed(String viewName) {
System.err.printf("View closed%n");
}
public void buttonPushed(String id) {
System.err.printf("pushed %s%n", id);
}
public void buttonReleased(String id) {
System.err.printf("released %s%n", id);
}
}
Cordialement
2011/5/9 Tièche Simon
<Simon.Tieche AT edu.hefr.ch>:
>
Il y a encore 2 choses que j’aimerais faire et je suis un peu perdu :
>
récupérer un clic sur une nœud, et obtenir les coordonnées d’un nœud pour
>
centrer la vue sur celui-ci.
>
>
>
>
Il y a un exemple dans un ancien tutoriel
>
(http://graphstream.sourceforge.net/tutorials/tut115.html) mais étant donnée
>
que les classes ne sont plus les mêmes, je ne vois pas vraiment comment
>
réaliser ces 2 actions.
>
>
>
>
Pourriez-vous m’aider svp ?
>
>
>
>
Merci beaucoup et bonne fin de journée.
>
>
>
>
_________________________________________
>
>
>
>
Simon Tièche - 3e année Télécommunications
>
>
Ecole d'Ingénieurs et d'Architectes de Fribourg
>
>
>
>
Attachment:
gs-core-bin.jar
Description: application/java-archive
Archives gérées par MHonArc 2.6.16.