This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
I am trying to create a custom anchor shape. I first started by coping one of the existing shapes (TriangleAnchorShape). I noticed that if the shape is on the target side of the ConnectionWidget that everything will work correctly. < See the TargetAnchor.png > However if I put the shape on the source side, things do not work so well. In the image below you can see that ConnectionWidget does not enter the shape from the bottom, but instead from the right side. < See the SourceAnchor.png > Also as you can see from the next image the connector actually enters the shape from the right then does a 90 degree turn down. to the center of the shape. < See the closeup.png >
Created attachment 52542 [details] An anchor on the target end of a ConnectionWidget
Created attachment 52543 [details] An anchor on the source end of a ConnectionWidget
Created attachment 52544 [details] Close up of anchor on the source end.
Response from David Kaspar: This is caused by the routing algorithm. Here is what the validation logic works: 1) ConnectionWidget realized that it has to be be re-routed. 2) ConnectionWidget ask router to route the path. 3) A router (in your case OrthogonalSearchRouter) asks source and target anchor to compute a source and target location. 4) Then it routes a path independently on anchor-shapes. In your case 10px down, 50px right, 50px down. 5) ConnectionWidget repaints itself - the path is painted from the first point to the last point but the first and last segments of the line are cut at the distance defined in AnchorShape.getCutDistance. 6) ERROR - In your case the cutdistance is correctly set but only first segment is cut at defined distance and at the same time the first segment is just 10px long and therefore the second line start in the middle of the anchor shape. The only correct solution is to use a Router which routes a path that has first and/or last segment long at least as AnchorShape.getCutDistance + some space pixels (e.g. 5px). This is actually possible by using a custom WidgetsCollisionCollector (copy the class from the library). Then: 1) Change its implements section to: "ConnectionWidgetCollisionCollector" 2) Fix the signature of the "collectCollisions" method. 3) In the collectCollisions method improve the logic and add a bigger collision rectangle in case that the collision Widget is fitting following condition: widget == connectionWidget.getSourceAnchor ().getRelatedWidget () || widget == connectionWidget.getTargetAnchor ().getRelatedWidget () This will assure that the router will create bigger the first and the last segments of routed paths.
This is caused by the OrthogonalSearchRouter. It does not have "minimal-first-and-last-connection-segment-length" property. Therefore following solutions could be done: 1) Introduce such parameter to the OrthogonalSearchRouter - requires API review 2) Extends the ConnectionWidgetCollisionCollector which calculate everything as normally but additionally it adds a "bigger" vertical and horizontal collision for source and target widgets. The "bigger" means that the scene boundary of those widgets will be enlarged by e.g. 20 pixels. Then the OrthogonalSearchRouter will route the first and the last segment long enough.
The implementation of the minimal-fisrt/last-segment-length property is not simple. The workaround exists to use a CollisionCollector that would produce represent source and target nodes as bigger collision areas. Lowering to P3 since a workaround exists.