经过大量的调查后,我无法找到以下问题的方便答案:如何用Jung以编程方式平移VisualizationViewer?
我有一个GUI,其中包含我的图形顶点列表,我希望双击列表中的一个项目(即节点描述),对我单击的节点执行VisualizationViewer的“居中操作”。 如何编码这样的行为?看起来很简单,但我找不到方便的答案。
如果有人可以提供帮助,谢谢!
njames
答案 0 :(得分:4)
以下是在右键单击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<Node,Link> vv =
(VisualizationViewer<Node,Link>)e.getSource();
final Point2D p = e.getPoint();
GraphElementAccessor<Node,Link> 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("<html><center>" + 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 {
}
}
}
}
编辑:最后!具有比例因子计算的正确的节点到中心视图......
答案 1 :(得分:1)
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();
}
答案 2 :(得分:1)
因为我只是在寻找答案,而上述工作非常糟糕;这是我在AnimatedPickingGraphMousePlugin中找到的代码片段,它将重新定位:
Layout<V,E> 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);
答案 3 :(得分:0)
实际上,我已经找到了下一个解决方案:
//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()));
答案 4 :(得分:0)
节点功能的中心已经在AnimatedPickingGraphMousePlugin
中实现http://sourceforge.net/p/jung/discussion/252062/thread/18b4b941
在拣选模式中,按住Ctrl键并点击顶点以使其居中。
@SuppressWarnings("unchecked")
public void mouseReleased(MouseEvent e) {
if (e.getModifiers() == modifiers) {
final VisualizationViewer<V,E> vv = (VisualizationViewer<V,E>) e.getSource();
if (vertex != null) {
Layout<V,E> 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();
}
}
}
答案 5 :(得分:0)
我试图找出如何以给定顶点为中心并遇到这个问题,但不幸的是它并没有特别有用,我花了相当多的时间来弄清楚如何去做。所以,在这里分享我的经验,以防它可能对其他人有所帮助。
我写的应用程序有一个VisualizationViewer,它被加载到GraphZoomScrollPane中。我有一个GraphMouseListener,我已经添加到VisualizationViewer,它允许用户右键单击滚动窗格的可视区域中的顶点,并在弹出菜单中,他们可以选择以顶点为中心。
此线程的最高投票回答引用了LAYOUT层中MutableTransformer的用法,并使用该转换器的translate方法进行居中操作。不幸的是,如果你使用缩放/滚动,那么你就不会真正了解布局图层相对于视图图层的大小和位置,而无需进行大量的额外数学运算。
使用缩放/滚动窗格时,我建议在窗格所代表的图形的可视区域中找到顶点的位置,然后调整视图窗格所在的位置。
以下是我编写的代码片段:
void center(MouseEvent me, GraphZoomScrollPane gzsp) {
VisualizationViewer<V,E> vv =
(VisualizationViewer<V,E>)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]);
}