使用鼠标事件检索 node/edge

Retrieving node/edge with mouse events

我正在关注 official GraphStream tutorial,如标题所示 - 我正在尝试通过单击它来获取节点。

到目前为止,这是我的代码:

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();
}

有什么有效的方法吗?

这是我找到的解决方案:

首先我写了一个新的 MouseManager 来覆盖默认的,我使用函数 findNodeOrSpriteAt(int x, int y) 来“捕捉”被点击的节点:

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.)

之后,我用 setMouseManager()

将新的自定义 MouseManager 添加到我的 Viewer
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());
}

此代码适用于节点,但我仍然不确定通过单击获得边缘的正确方法是什么。

但是,一个天真的解决方案可能是获取 mouse-click 的坐标,然后迭代节点和 check if those coordinates are between 2 nodes.

另一个(更快的)解决方案是 - 将 sprites 附加到边缘:

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

通过这样做,可以使用我用来检索节点的函数 findNodeOrSpriteAt(int x, int y) 来检索边的精灵。