如何使用Jung(java库)以编程方式平移VisualizationViewer?

经过大量的调查,我无法找到以下问题的方便答案:如何用Jung以编程方式平移VisualizationViewer?

我有一个GUI,其中包含我的图形顶点列表,我希望双击列表中的一个项目(即节点描述),对我单击的节点执行VisualizationViewer的“居中操作”。 如何编码这样的行为? 看起来很简单,但我找不到方便的答案。

如果有人可以提供帮助,谢谢!

njames

以下是在右键单击JUNG2中的节点后弹出菜单,然后选择居中到此节点:

graphMouse.add(new MyPopupGraphMousePlugin()); /** * a GraphMousePlugin that offers popup * menu support */ protected class MyPopupGraphMousePlugin extends AbstractPopupGraphMousePlugin implements MouseListener { public MyPopupGraphMousePlugin() { this(MouseEvent.BUTTON3_MASK); } public MyPopupGraphMousePlugin(int modifiers) { super(modifiers); } /** * If this event is over a node, pop up a menu to * allow the user to center view to the node * * @param e */ protected void handlePopup(MouseEvent e) { final VisualizationViewer vv = (VisualizationViewer)e.getSource(); final Point2D p = e.getPoint(); GraphElementAccessor pickSupport = vv.getPickSupport(); if(pickSupport != null) { final Node station = pickSupport.getVertex(vv.getGraphLayout(), p.getX(), p.getY()); if(station != null) { JPopupMenu popup = new JPopupMenu(); String center = "Center to Node"; popup.add(new AbstractAction("
" + center) { public void actionPerformed(ActionEvent e) { MutableTransformer view = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW); MutableTransformer layout = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT); Point2D ctr = vv.getCenter(); Point2D pnt = view.inverseTransform(ctr); double scale = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW).getScale(); double deltaX = (ctr.getX() - p.getX())*1/scale; double deltaY = (ctr.getY() - p.getY())*1/scale; Point2D delta = new Point2D.Double(deltaX, deltaY); layout.translate(deltaX, deltaY); } }); popup.show(vv, e.getX(), e.getY()); } else { } } } }

编辑:终于! 正确的节点到中心视图与比例因子计算…

 public void centerViewsOnVertex(SynsetVertex v) { //the following location have sense in the space of the layout Point2D v_location = layout.transform(v); Point2D vv1_center_location = vv1.getRenderContext() .getMultiLayerTransformer() .inverseTransform(Layer.LAYOUT, vv1.getCenter()); double scale = vv1.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW).getScale(); vv1.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).translate( -(v_location.getX() - vv1_center_location.getX()) * 1 / scale, -(v_location.getY() - vv1_center_location.getY()) * 1 / scale); refreshViews(); } 

因为我只是想找到答案,而上述工作非常糟糕; 这是我在AnimatedPickingGraphMousePlugin中找到的代码片段,它将重新定位:

 Layout layout = vv.getGraphLayout(); Point2D q = layout.transform(vertex); Point2D lvc = vv.getRenderContext().getMultiLayerTransformer().inverseTransform(vv.getCenter()); final double dx = (lvc.getX() - q.getX()); final double dy = (lvc.getY() - q.getY()); vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).translate(dx, dy); 

实际上,我已经找到了下一个解决方案:

 //the following location have sense in the space of the layout Point2D v_location = layout.transform(v); Point2D vv1_center_location = vv1.getRenderContext() .getMultiLayerTransformer() .inverseTransform(Layer.LAYOUT, vv1.getCenter()); vv1.getRenderContext() .getMultiLayerTransformer() .getTransformer(Layer.LAYOUT) .translate(-(v_location.getX() - vv1_center_location.getX()), -(v_location.getY() - vv1_center_location.getY())); 

节点function的中心已经在AnimatedPickingGraphMousePlugin中实现

http://sourceforge.net/p/jung/discussion/252062/thread/18b4b941

在拾取模式中,按住ctrl +单击顶点以使其居中。

 @SuppressWarnings("unchecked") public void mouseReleased(MouseEvent e) { if (e.getModifiers() == modifiers) { final VisualizationViewer vv = (VisualizationViewer) e.getSource(); if (vertex != null) { Layout layout = vv.getGraphLayout(); Point2D q = layout.transform(vertex); Point2D lvc = vv.getRenderContext().getMultiLayerTransformer().inverseTransform(vv.getCenter()); final double dx = (lvc.getX() - q.getX()) / 10; final double dy = (lvc.getY() - q.getY()) / 10; Runnable animator = new Runnable() { public void run() { for (int i = 0; i < 10; i++) { vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).translate(dx, dy); try { Thread.sleep(100); } catch (InterruptedException ex) { } } } }; Thread thread = new Thread(animator); thread.start(); } } } 

我试图弄清楚如何以给定顶点为中心并遇到这个问题,但不幸的是它并没有特别有用,我花了相当多的时间来弄清楚如何去做。 所以,在这里分享我的经验,以防它可能对其他人有所帮助。

我正在编写的应用程序有一个VisualizationViewer,它被加载到GraphZoomScrollPane中。 我有一个GraphMouseListener,我已经添加到VisualizationViewer,它允许用户右键单击滚动窗格的可视区域中的顶点,并在弹出菜单中,他们可以选择以顶点为中心。

此线程上的最高投票答案引用了LAYOUT层中MutableTransformer的使用,并使用该变换器的translate方法进行居中操作。 不幸的是,如果你使用缩放/滚动,那么你并不真正知道布局图层相对于视图层的大小和位置,而不需要进行一些额外的数学运算。

使用缩放/滚动窗格时,我建议在窗格所代表的图形的可视区域中查找顶点的位置,然后调整视图窗格所在的位置。

这是我编写的代码片段:

 void center(MouseEvent me, GraphZoomScrollPane gzsp) { VisualizationViewer vv = (VisualizationViewer)me.getSource(); MutableTransformer viewTransformer = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW); double scaleFromViewTransformer = viewTransformer.getScale(); Dimension paneSize = gzsp.getSize(); Point2D positionOfVertexInPane = me.getPoint(); double[] centerOfPane = new double[] { paneSize.getWidth()/2d, paneSize.getHeight()/2d }; double[] amountToMovePane = new double[] { (centerOfPane[0]-positionOfVertexInPane.getX())/scaleFromViewTransformer, (centerOfPane[1]-positionOfVertexInPane.getY())/scaleFromViewTransformer }; viewTransformer.translate(amountToMovePane[0], amountToMovePane[1]); }