Hi,

I am trying to change the geometry of an Edge within a new beginUpdate/endUpdate, but it seems not to work is the operation is executed from within a new begin/end Update. Here is the code based on the HelloWorld jgraphx example.

package jgraphx.tests;

import java.util.ArrayList; import java.util.List;

import javax.swing.JFrame;

import com.mxgraph.model.mxCell; import com.mxgraph.model.mxGeometry; import com.mxgraph.model.mxGraphModel; import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.util.mxPoint; import com.mxgraph.view.mxGraph;

public class JGraphXHelloWorld extends JFrame {

/**
 * 
 */
private static final long serialVersionUID = -2707712944901661771L;

public JGraphXHelloWorld() {
    super("Hello, World!");

    mxGraph graph = new mxGraph();
    Object parent = graph.getDefaultParent();

    graph.getModel().beginUpdate();
    try {
        Object v1 = graph.insertVertex(parent, null, "Hello", 20, 20, 80, 30);
        Object v2 = graph.insertVertex(parent, null, "World!", 240, 150, 80, 30);
        graph.insertEdge(parent, "Edge", "Edge", v1, v2);
        // changeGeometryOfAnEdge(graph); // Change geometry of an edge works here
    } finally {
        graph.getModel().endUpdate();
    }

    graph.getModel().beginUpdate();
    changeGeometryOfAnEdge(graph); // Change geometry of an edge DOES NOT work here (another beginUpdate, endUpdate)
    graph.getModel().endUpdate();

    mxGraphComponent graphComponent = new mxGraphComponent(graph);
    getContentPane().add(graphComponent);
}

public void changeGeometryOfAnEdge(mxGraph graph) {
    mxCell edgeToChange = (mxCell) ((mxGraphModel) (graph.getModel())).getCell("Edge");
    mxGeometry geometryOfEdge = edgeToChange.getGeometry();
    List<mxPoint> pointsOfTheEdge = geometryOfEdge.getPoints();
    if (pointsOfTheEdge == null) {
        pointsOfTheEdge = new ArrayList<mxPoint>();
    }
    pointsOfTheEdge.add(new mxPoint(100, 200));
    geometryOfEdge.setPoints(pointsOfTheEdge);
    edgeToChange.setGeometry(geometryOfEdge);
}

public static void main(String[] args) {
    JGraphXHelloWorld frame = new JGraphXHelloWorld();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 320);
    frame.setVisible(true);
}

}

asked 13 May '12, 17:07

stefanutti's gravatar image

stefanutti
1516
accept rate: 0%

edited 13 May '12, 17:23


When changing the model, always looks for the method being either on mxGraph or mxGraphModel. The methods on the cell itself tend to be in-place and not perform the updating required (they are public to match the JavaScript API, which cannot scope functions like Java).

So, in your case, obtain the geometry using model.getGeometry() , clone that geometry before working on it and set it back using model.setGeometry().

Using the model methods will ensure the appropriate updating is done. Cloning the geometry is required because when the transaction is enacted, the previous states of the cells are compared to the current. If you edit in-place, no change is detected and nothing happens.

When you perform your next transaction you are invalidating the cell state and only then is the cell geometry taking effect. You can tell this has happened because your undo history will be broken due to the in-place edit (the geometry change never happened as part of a proper edit, so it will never revert since undos simply "unplay" the edit sequence).

link

answered 13 May '12, 17:29

David's gravatar image

David
4.9k21831
accept rate: 47%

It worked just fine. I cannot upvote but you have my thanks!

Here is the modified method:

public void changeGeometryOfAnEdge(mxGraph graph) {
    mxCell edgeToChange = (mxCell) ((mxGraphModel) (graph.getModel())).getCell("Edge");
    mxGeometry geometryOfEdge = ((mxGraphModel) (graph.getModel())).getGeometry(edgeToChange);
    geometryOfEdge = (mxGeometry) geometryOfEdge.clone();
    List<mxPoint> pointsOfTheEdge = geometryOfEdge.getPoints();
    if (pointsOfTheEdge == null) {
        pointsOfTheEdge = new ArrayList<mxPoint>();
    }
    pointsOfTheEdge.add(new mxPoint(100, 200));
    geometryOfEdge.setPoints(pointsOfTheEdge);
    ((mxGraphModel) (graph.getModel())).setGeometry(edgeToChange, geometryOfEdge);
}
(13 May '12, 17:54) stefanutti

Minor point, get/setGeometry are on the model interface, you don't need to cast to mxGraphModel.

(13 May '12, 18:14) David

Thanks again!

(14 May '12, 06:34) stefanutti
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×194
×100
×66
×8
×6

Asked: 13 May '12, 17:07

Seen: 3,105 times

Last updated: 14 May '12, 06:34