Adding ports at runtime

Im new to JGo so I was hoping someone could clarify something for me. Initially I created a node with one port which could have multiple links. The problem with this is that I would get depending on the layout the links one on top of another and the end of the links all ending with the same arrow. I want to design it so that each link has its own arrow in other words its own port. Since I have no idea how many links might be joined to the node or which direction the link is coming from I was thinking of creating a node with no ports initially and add a port whenever the user attempted to add one. My question if anyone has any suggestions is what would be the cleanest solution. I dont want the user to have to double or single click on the node but rather have the user almost drag his mouse over the node to initiate a link but when I try this with what I have written I always end up dragging the node.



Thank you all for your time

One way of doing this is to keep a special port available from which and to which the user can draw links. But linking to this port would automatically add a port to the node and link to that port instead. And removing the last link on one of the node’s ports would cause the port to be removed from the node.
public class AutoLinkNode extends GeneralNode {
public AutoLinkNode() {}
public void initialize(Point loc, Dimension size, JGoObject icon,
String toplabeltext, String bottomlabeltext, int numinports, int numoutports) {
super.initialize(loc, size, icon, toplabeltext, bottomlabeltext, numinports, numoutports);
myAutoLinkingPort = new AutoLinkingPort();
addObjectAtTail(myAutoLinkingPort);
}
protected void copyChildren(JGoArea newarea, JGoCopyEnvironment env) {
super.copyChildren(newarea, env);
AutoLinkNode newobj = (AutoLinkNode)newarea;
newobj.myAutoLinkingPort = (AutoLinkingPort)env.get(myAutoLinkingPort);
}
public JGoObject removeObjectAtPos(JGoListPosition pos) {
JGoObject child = super.removeObjectAtPos(pos);
if (child == myAutoLinkingPort)
myAutoLinkingPort = null;
return child;
}
public void layoutChildren(JGoObject childchanged) {
if (isInitializing()) return;
super.layoutChildren(childchanged);
setInitializing(true);
JGoObject icon = getIcon();
if (icon != null && myAutoLinkingPort != null) {
myAutoLinkingPort.setSpotLocation(Center, icon, Center);
}
setInitializing(false);
}
private AutoLinkingPort myAutoLinkingPort = null;
}

public class AutoLinkingPort extends JGoPort {
public AutoLinkingPort() {
setStyle(StyleDiamond);
setFromSpot(Center);
setToSpot(Center);
setSize(7, 7);
setPen(null);
setBrush(JGoBrush.yellow);
}
public void update(int hint, int prevInt, Object prevVal) {
super.update(hint, prevInt, prevVal);
if (hint == JGoPort.ChangedAddedLink && getParent() instanceof GeneralNode) {
JGoLink link = (JGoLink)prevVal;
GeneralNode node = (GeneralNode)getParent();
if (link.getToPort() != null && link.getToPort().getParent() == node) {
String name = Integer.toString(node.getNumLeftPorts());
GeneralNodePort p = new AutoLinkNodePort();
p.initialize(true, name, node);
GeneralNodePortLabel lab = new GeneralNodePortLabel();
lab.initialize(name, p);
node.addLeftPort§;
link.setToPort§;
} else if (link.getFromPort() != null && link.getFromPort().getParent() == node) {
String name = Integer.toString(node.getNumRightPorts());
GeneralNodePort p = new AutoLinkNodePort();
p.initialize(false, name, node);
GeneralNodePortLabel lab = new GeneralNodePortLabel();
lab.initialize(name, p);
node.addRightPort§;
link.setFromPort§;
}
}
}
}

public class AutoLinkNodePort extends GeneralNodePort {
public AutoLinkNodePort() {
setSize(8, 8);
}
public void linkChange() {
super.linkChange();
if (getNumLinks() == 0 && getParent() instanceof GeneralNode) {
GeneralNode node = (GeneralNode)getParent();
if (isOnLeftSide())
node.removeLeftPort(getIndex());
else
node.removeRightPort(getIndex());
}
}
}

Thank you for your reply. I was wondering would it be difficult to change it so that the from and to links are not limited simply to either the left or the right side? What would be a simple way to detect which direction the mouse is being dragged to determine where to place the exit and entrance of the ports in order to be placed in the right area in the node?



Thanks again for your time

It would probably be easiest to compute the direction towards the other end of the link is, to decide which side of the node would be closest.

Thanks again walter. I have one more question. Is there an easy way to avoid having links being painted one on top of the other?



Thanks again

For Orthogonal links, you can turn on the AvoidsNodes property.
For Cubic (Bezier) links, you can control the Curviness property.
For multiple ports lined up in a row on a node, you can control the EndSegmentLength, typically so that the middle ports have a longer value than the ones at the ends.