Retrieving node/edge with mouse events

238 Views Asked by At

I'm following the official GraphStream tutorial, and as the title suggest - I'm trying to get node's by clicking on it.

this is my code so far:

import org.graphstream.graph.*;
import org.graphstream.graph.implementations.*;
    
public static void main(String args[]) {
    Graph graph = new MultiGraph("Tutorial 1");
    graph.setStrict(false);
    graph.setAutoCreate( true );

    graph.addNode("A").setAttribute("xy", 1, 1);
    graph.addNode("B").setAttribute("xy", 5, 5);
    graph.addNode("C").setAttribute("xy", 1, 8);

    graph.addEdge("AB", "A", "B");
    graph.addEdge("BC", "B", "C");
    graph.addEdge("CA", "C", "A");

    Viewer viewer = graph.display();
    viewer.disableAutoLayout();
}

Is there an efficient way to do it?

2

There are 2 best solutions below

0
On BEST ANSWER

So here is the solution I have found:

First I've written a new MouseManager to override the default one, and I've used the function findNodeOrSpriteAt(int x, int y) to "catch" the clicked node:

public class CustomMouseManager implements MouseManager {

    protected View view;
    protected GraphicGraph graph;

    @Override
    public void init(GraphicGraph graph, View view) {
        this.graph = graph;
        this.view = view;
        view.addMouseListener(this);
        view.addMouseMotionListener(this);
    }

    @Override
    public void release() {
        view.removeMouseListener(this);
        view.removeMouseMotionListener(this);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();

        GraphicElement node = view.findNodeOrSpriteAt(x, y);

        if(node != null){
            System.out.println("Node " + node.getId() + ": (" + x + "," + y + ")");
        }
    }
    // here you should implement the rest of the MouseManager's methods (mouseDragged, mouseReleased, etc.)

After that, I've added the new custom MouseManager to my Viewer with setMouseManager()

public static void main(String args[]) {
    Graph graph = new MultiGraph("Tutorial 1");
    graph.setStrict(false);
    graph.setAutoCreate( true );

    graph.addNode("A").setAttribute("xy", 1, 1);
    graph.addNode("B").setAttribute("xy", 5, 5);
    graph.addNode("C").setAttribute("xy", 1, 8);

    graph.addEdge("AB", "A", "B");
    graph.addEdge("BC", "B", "C");
    graph.addEdge("CA", "C", "A");

    Viewer viewer = graph.display();
    viewer.disableAutoLayout();
    viewer.getDefaultView().setMouseManager(new MyMouseManager());
}

this code works for nodes but I'm still not sure what is the correct way to get an edge by clicking on it.

However, a naive solution might be to get the mouse-click's coordinates and then iterate the nodes and check if those coordinates are between 2 nodes.

another (faster) solution is - attaching sprites to the edges:

Sprite s1;
s1.attachToEdge("AB");

By doing this, one can retrieve the edge's sprite with the function findNodeOrSpriteAt(int x, int y) that I've used to retrieve nodes.

0
On

For nodes, simply implement a ViewerListener as in the official documentation:

https://graphstream-project.org/doc/Tutorials/Graph-Visualisation/

On OS X you might want to run with -Dsun.java2d.uiScale=100% or otherwise coordinates might be wrong

For the hover events, you'll need to add viewer.getDefaultView().enableMouseOptions();

public class Clicks implements ViewerListener {
    protected boolean loop = true;

    public static void main(String args[]) {
        System.setProperty("org.graphstream.ui", "swing");
        new Clicks();
    }
    public Clicks() {
        Graph graph = new SingleGraph("Clicks");
        Viewer viewer = graph.display();

        viewer.setCloseFramePolicy(Viewer.CloseFramePolicy.HIDE_ONLY);

        ViewerPipe fromViewer = viewer.newViewerPipe();
        fromViewer.addViewerListener(this);
        fromViewer.addSink(graph);
    
        while(loop) {
            fromViewer.pump();
        }
    }

    public void viewClosed(String id) {
        loop = false;
    }

    public void buttonPushed(String id) {
        System.out.println("Button pushed on node "+id);
    }

    public void buttonReleased(String id) {
        System.out.println("Button released on node "+id);
    }

    public void mouseOver(String id) {
        System.out.println("Need the Mouse Options to be activated");
    }

    public void mouseLeft(String id) {
        System.out.println("Need the Mouse Options to be activated");
    }
}