Link jumps incorrectly to the centre of object

Hi again,

Thanks for your previous help.

I am noticing a problem (it seems to be with all JGo objects but its very obvious with subgraphs). My link under certain link setup conditions and postions, jumps to the centre of my subgraph, when it really shouldn’t.

I am expecting the link to try and draw the link from the from-port to the to-port and if it cannot as child of the object gets in the way, it point to that intersection point. If the from-port point is already “inside” the to-ports object then I guess pointing to the centre is ok (though I would like it to point at the port really).

To reproduce you need the “from end port” setFromSpot and the “to end port” setToSpot set to NoSpot, the toPort’s object as the subgraph, and the link setCubic(true).

I think its a problem somewhere in the depths of calculateStroke routine.

So in the BoxView.java I have the overridden method:

public void newLink(JGoPort from, JGoPort to) {
JGoDocument doc = getDocument();
if (doc == null) return;

  JGoLabeledLink link = new JGoLabeledLink(from, to);
  JGoLinkLabel label = new JGoLinkLabel("Hello");
  label.setTransparent(false);
  link.setMidLabel(label);
  link.setCubic(true);

  JGoSubGraphBase.reparentToCommonSubGraph(link, from, to, true, doc.getLinksLayer());

  fireUpdate(JGoViewEvent.LINK_CREATED, 0, link);
  doc.endTransaction(getEditPresentationName(4));

}

In TestSubGraph.java initPorts() method I have added:
myInput.setValidSource(false);
myInput.setPortObject(this);
myInput.setToSpot(NoSpot);

addObjectAtTail(myInput);

In BoxApp.java I had added in the init() method:
node2.setDragsNode(false);
node2.getPort().setFromSpot(JGoPort.NoSpot);

Now link the “second” node to the input port.
Try moving the “second” node around the canvas. You will see the link jump suddenly in to the centre of the subgraph when in certain positions.

Any ideas?

Thanks.

See attached image:

The JGoPort.getLinkPointFromPoint method tries to determine the intersection point between a link and the designated port object. If the point is inside the port object’s bounding rectangle, there is no such intersection and the method simply returns the point at the center of the port object.

If the point is not inside the port object, the JGoPort.getNearestInsectionPoint method is called, and if the port object is a JGoArea the closest child object of the JGoArea will be used for calculating the intersection point. So a GoObject inside the port object's bounding rectangle may be used to compute the intersection point. In the case above, the JGoRoundRect child of the TestSubGraph is used to compute the intersection point, so the intersection point is indeed inside the port object's bounding rectangle.
This normally isn't a problem, but in the case of Bezier links, we adjust the end points of the links so that they appear to come from the closest control point of the Bezier link, calling getLinkPointFromPoint with the nearby control points to compute a "better" intersection point.
The problem you are observing is that these nearby control points can occasionally be inside the port object bounding rectangle, and when they are, the connection snaps to the center of the port object.
Probably the easiest way to correct this is modify the end of the JGoLink calculateBezierNoSpot method as follows:
// adjust end points so that they appear to come from the control points
if ((from.getPortObject() == null) || ((from.getPortObject() != null) && !(from.getPortObject() instanceof JGoArea)))
setPoint(0, from.getLinkPointFromPoint(x1, y1, p));
if ((to.getPortObject() == null) || ((to.getPortObject() != null) && !(to.getPortObject() instanceof JGoArea)))
setPoint(3, to.getLinkPointFromPoint(x2, y2, p));