Index: graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java =================================================================== RCS file: /cvs/graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java,v retrieving revision 1.86 diff -u -r1.86 RunDialog.java --- graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java 20 Aug 2007 08:06:29 -0000 1.86 +++ graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java 23 Aug 2007 09:03:47 -0000 @@ -102,6 +102,8 @@ "test.resize.ResizeTest", "test.router.OSRCollisionsCollectorTest", "test.router.OSRComputeControlPointsTest", + "test.routing.ActionsWithRoutingPolicyTest", + "test.routing.RoutingPolicyTest", "test.sceneresize.LimitedSceneTest", "test.sceneresize.SceneResizeTest", "test.scroll.ScrollTest", Index: graph/examples/src/test/routing/ActionsWithRoutingPolicyTest.java =================================================================== RCS file: graph/examples/src/test/routing/ActionsWithRoutingPolicyTest.java diff -N graph/examples/src/test/routing/ActionsWithRoutingPolicyTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ graph/examples/src/test/routing/ActionsWithRoutingPolicyTest.java 23 Aug 2007 09:03:47 -0000 @@ -0,0 +1,103 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package test.routing; + +import org.netbeans.api.visual.action.ActionFactory; +import org.netbeans.api.visual.anchor.AnchorFactory; +import org.netbeans.api.visual.anchor.AnchorShape; +import org.netbeans.api.visual.anchor.PointShape; +import org.netbeans.api.visual.border.BorderFactory; +import org.netbeans.api.visual.router.RouterFactory; +import org.netbeans.api.visual.widget.*; +import test.SceneSupport; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; + +/** + * @author David Kaspar + */ +public class ActionsWithRoutingPolicyTest extends Scene { + + private LayerWidget mainLayer; + private ConnectionWidget connection; + + public ActionsWithRoutingPolicyTest () { + mainLayer = new LayerWidget (this); + addChild (mainLayer); + LayerWidget connLayer = new LayerWidget (this); + addChild (connLayer); + + Widget source = createLabel ("Source", 50, 200, Color.GREEN); + Widget target = createLabel ("Target", 450, 200, Color.GREEN); + + connection = new ConnectionWidget (this); + connection.setSourceAnchor (AnchorFactory.createDirectionalAnchor (source, AnchorFactory.DirectionalAnchorKind.HORIZONTAL)); + connection.setTargetAnchor (AnchorFactory.createDirectionalAnchor (target, AnchorFactory.DirectionalAnchorKind.HORIZONTAL)); + connection.setTargetAnchorShape (AnchorShape.TRIANGLE_FILLED); + connection.setPaintControlPoints (true); + connection.setControlPointShape (PointShape.SQUARE_FILLED_BIG); + connection.setRouter (RouterFactory.createOrthogonalSearchRouter (mainLayer)); + connection.getActions ().addAction (ActionFactory.createAddRemoveControlPointAction (1.0, 5.0, ConnectionWidget.RoutingPolicy.UPDATE_END_POINTS_ONLY)); + connection.getActions ().addAction (ActionFactory.createMoveControlPointAction (ActionFactory.createFreeMoveControlPointProvider (), ConnectionWidget.RoutingPolicy.UPDATE_END_POINTS_ONLY)); + connLayer.addChild (connection); + } + + private Widget createLabel (String text, int x, int y, Color color) { + LabelWidget label = new LabelWidget (this, text); + label.setOpaque (true); + label.setBackground (color); + label.setBorder (BorderFactory.createLineBorder (5)); + label.setPreferredLocation (new Point (x, y)); + label.getActions ().addAction (ActionFactory.createMoveAction ()); + mainLayer.addChild (label); + return label; + } + + private JComponent createPanel () { + JPanel panel = new JPanel (); + panel.setLayout (new BorderLayout ()); + + JToolBar bar = new JToolBar (); + bar.add (new AbstractAction("Force Rerouting") { + public void actionPerformed (ActionEvent e) { + connection.reroute (); + validate (); + } + }); + bar.addSeparator (); + bar.add (new AbstractAction("Reset routing policy to always-route") { + public void actionPerformed (ActionEvent e) { + connection.setRoutingPolicy (ConnectionWidget.RoutingPolicy.ALWAYS_ROUTE); + validate (); + } + }); + panel.add (bar, BorderLayout.NORTH); + + panel.add (createView (), BorderLayout.CENTER); + return panel; + } + + public static void main (String[] args) { + SceneSupport.show (new ActionsWithRoutingPolicyTest ().createPanel ()); + } + +} Index: graph/examples/src/test/routing/RoutingPolicyTest.java =================================================================== RCS file: graph/examples/src/test/routing/RoutingPolicyTest.java diff -N graph/examples/src/test/routing/RoutingPolicyTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ graph/examples/src/test/routing/RoutingPolicyTest.java 23 Aug 2007 09:03:47 -0000 @@ -0,0 +1,130 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package test.routing; + +import org.netbeans.api.visual.action.ActionFactory; +import org.netbeans.api.visual.anchor.AnchorFactory; +import org.netbeans.api.visual.anchor.AnchorShape; +import org.netbeans.api.visual.anchor.PointShape; +import org.netbeans.api.visual.border.BorderFactory; +import org.netbeans.api.visual.router.RouterFactory; +import org.netbeans.api.visual.widget.*; +import test.SceneSupport; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; + +/** + * @author David Kaspar + */ +public class RoutingPolicyTest extends Scene { + + private LayerWidget mainLayer; + private ConnectionWidget connection; + + public RoutingPolicyTest () { + mainLayer = new LayerWidget (this); + addChild (mainLayer); + LayerWidget connLayer = new LayerWidget (this); + addChild (connLayer); + + createLabel ("Buttons in toolbar", 200, 100, Color.YELLOW); + createLabel ("allows you to switch", 200, 130, Color.YELLOW); + createLabel ("routing policy of the connection widget.", 200, 160, Color.YELLOW); + + createLabel ("Try double-clicking on the connection widget.", 200, 250, Color.CYAN); + createLabel ("Try dragging control points of the connection widget.", 200, 280, Color.CYAN); + createLabel ("Try force re-routing of the connection widget.", 200, 310, Color.CYAN); + + Widget source = createLabel ("Source", 50, 200, Color.GREEN); + Widget target = createLabel ("Target", 450, 200, Color.GREEN); + + connection = new ConnectionWidget (this); + connection.setSourceAnchor (AnchorFactory.createDirectionalAnchor (source, AnchorFactory.DirectionalAnchorKind.HORIZONTAL)); + connection.setTargetAnchor (AnchorFactory.createDirectionalAnchor (target, AnchorFactory.DirectionalAnchorKind.HORIZONTAL)); + connection.setTargetAnchorShape (AnchorShape.TRIANGLE_FILLED); + connection.setPaintControlPoints (true); + connection.setControlPointShape (PointShape.SQUARE_FILLED_BIG); + connection.setRouter (RouterFactory.createOrthogonalSearchRouter (mainLayer)); + connection.getActions ().addAction (ActionFactory.createAddRemoveControlPointAction ()); + connection.getActions ().addAction (ActionFactory.createFreeMoveControlPointAction ()); + connLayer.addChild (connection); + } + + private Widget createLabel (String text, int x, int y, Color color) { + LabelWidget label = new LabelWidget (this, text); + label.setOpaque (true); + label.setBackground (color); + label.setBorder (BorderFactory.createLineBorder (5)); + label.setPreferredLocation (new Point (x, y)); + label.getActions ().addAction (ActionFactory.createMoveAction ()); + mainLayer.addChild (label); + return label; + } + + private JComponent createPanel () { + JPanel panel = new JPanel (); + panel.setLayout (new BorderLayout ()); + + JToolBar bar = new JToolBar (); + bar.add (new AbstractAction("Force Rerouting") { + public void actionPerformed (ActionEvent e) { + connection.reroute (); + validate (); + } + }); + bar.addSeparator (); + bar.add (new JLabel ("Switch routing policy:")); + bar.add (new AbstractAction("Always Route") { + public void actionPerformed (ActionEvent e) { + connection.setRoutingPolicy (ConnectionWidget.RoutingPolicy.ALWAYS_ROUTE); + validate (); + } + }); + bar.add (new AbstractAction("Update End Points Only") { + public void actionPerformed (ActionEvent e) { + connection.setRoutingPolicy (ConnectionWidget.RoutingPolicy.UPDATE_END_POINTS_ONLY); + validate (); + } + }); + bar.add (new AbstractAction("Disable Routing Until End Point is Moved") { + public void actionPerformed (ActionEvent e) { + connection.setRoutingPolicy (ConnectionWidget.RoutingPolicy.DISABLE_ROUTING_UNTIL_END_POINT_IS_MOVED); + validate (); + } + }); + bar.add (new AbstractAction("Disable Routing") { + public void actionPerformed (ActionEvent e) { + connection.setRoutingPolicy (ConnectionWidget.RoutingPolicy.DISABLE_ROUTING); + validate (); + } + }); + panel.add (bar, BorderLayout.NORTH); + + panel.add (createView (), BorderLayout.CENTER); + return panel; + } + + public static void main (String[] args) { + SceneSupport.show (new RoutingPolicyTest ().createPanel ()); + } + +} Index: graph/lib/apichanges.xml =================================================================== RCS file: /cvs/graph/lib/apichanges.xml,v retrieving revision 1.41 diff -u -r1.41 apichanges.xml --- graph/lib/apichanges.xml 21 Aug 2007 08:46:59 -0000 1.41 +++ graph/lib/apichanges.xml 23 Aug 2007 09:03:47 -0000 @@ -534,6 +534,22 @@ + + + + Routing policy support for ConnectionWidget + + + + + + ConnectionWidget allows to specify routing policy. The policy defines behaviour of path routing in ConnectionWidget. + There are 4 values: Always-route, Update-end-points-only, Disable-routing-until-end-point-is-moved, Disable-routing. + AddRemoveControlPointAction and MoveControlPointAction has new factory methods for automatic assignment of routing policy. + + + + Index: graph/lib/manifest.mf =================================================================== RCS file: /cvs/graph/lib/manifest.mf,v retrieving revision 1.17 diff -u -r1.17 manifest.mf --- graph/lib/manifest.mf 21 Aug 2007 08:47:00 -0000 1.17 +++ graph/lib/manifest.mf 23 Aug 2007 09:03:47 -0000 @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.api.visual OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/visual/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 2.8 +OpenIDE-Module-Specification-Version: 2.9 AutoUpdate-Essential-Module: true Index: graph/lib/src/org/netbeans/api/visual/action/ActionFactory.java =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/api/visual/action/ActionFactory.java,v retrieving revision 1.28 diff -u -r1.28 ActionFactory.java --- graph/lib/src/org/netbeans/api/visual/action/ActionFactory.java 10 Aug 2007 08:50:02 -0000 1.28 +++ graph/lib/src/org/netbeans/api/visual/action/ActionFactory.java 23 Aug 2007 09:03:47 -0000 @@ -178,13 +178,26 @@ } /** - * Creates a add-remove control point action with a specified sensitivity. The action is assigned to a FreeConnectionWidget. + * Creates a add-remove control point action with a specified sensitivity. * @param createSensitivity the create sensitivity * @param deleteSensitivity the delete sensitivity * @return the add-remove control point action */ public static WidgetAction createAddRemoveControlPointAction (double createSensitivity, double deleteSensitivity) { - return new AddRemoveControlPointAction (createSensitivity, deleteSensitivity); + return createAddRemoveControlPointAction (createSensitivity, deleteSensitivity, null); + } + + /** + * Creates a add-remove control point action with a specified sensitivity. + * @param createSensitivity the create sensitivity + * @param deleteSensitivity the delete sensitivity + * @param routingPolicy the routing policy that is automatically set to a connection widget with control points modified by this action; + * if null, then routing policy is not set + * @return the add-remove control point action + * @since 2.9 + */ + public static WidgetAction createAddRemoveControlPointAction (double createSensitivity, double deleteSensitivity, ConnectionWidget.RoutingPolicy routingPolicy) { + return new AddRemoveControlPointAction (createSensitivity, deleteSensitivity, routingPolicy); } /** @@ -452,8 +465,20 @@ * @return the move control point action */ public static WidgetAction createMoveControlPointAction (MoveControlPointProvider provider) { + return createMoveControlPointAction (provider, null); + } + + /** + * Creates a move control point (of a connection widget) action with a specified provider. + * @param provider the move control point provider + * @param routingPolicy the routing policy that is automatically set to a connection widget with control points modified by this action; + * if null, then routing policy is not set + * @return the move control point action + * @since 2.9 + */ + public static WidgetAction createMoveControlPointAction (MoveControlPointProvider provider, ConnectionWidget.RoutingPolicy routingPolicy) { assert provider != null; - return new MoveControlPointAction (provider); + return new MoveControlPointAction (provider, routingPolicy); } /** Index: graph/lib/src/org/netbeans/api/visual/widget/ConnectionWidget.java =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/api/visual/widget/ConnectionWidget.java,v retrieving revision 1.41 diff -u -r1.41 ConnectionWidget.java --- graph/lib/src/org/netbeans/api/visual/widget/ConnectionWidget.java 9 Jul 2007 11:44:13 -0000 1.41 +++ graph/lib/src/org/netbeans/api/visual/widget/ConnectionWidget.java 23 Aug 2007 09:03:47 -0000 @@ -61,6 +61,46 @@ private static final double HIT_DISTANCE_SQUARE = 16.0; private static final Stroke STROKE_DEFAULT = new BasicStroke (1.0f); + /** + * This enum represents a policy which is used for re-routing control points of a ConnectionWidget. + * @since 2.9 + */ + public enum RoutingPolicy { + + /** + * All control points are rerouted when it is necessary. This is the default policy. + * @since 2.9 + */ + ALWAYS_ROUTE, + + /** + * All control points (except end points) are kept at the same location. + * End points are updated to locations resolved by source and target anchors. + * Note: This is used when an user customizes/adds/removes control points + * and the change has to be kept until it is reset by the user (setting policy to ALWAYS_ROUTE. + * @since 2.9 + */ + UPDATE_END_POINTS_ONLY, + + /** + * Temporarily disables routing until any end point changes its location. Locations are the first + * and the last point of control points. When an end point location is changed, + * then the policy is automatically changed to ALWAYS_ROUTE. + * Note: This is used by GraphLayouts which routes the path (control points) + * by themselves and would like to keep the path until user moves with source or target widget/anchor. + * @since 2.9 + */ + DISABLE_ROUTING_UNTIL_END_POINT_IS_MOVED, + + /** + * Disable routing completely, so control points are kept at their previous location. + * Note: This is not often used unless you have to freeze a ConnectionWidget + * @since 2.9 + */ + DISABLE_ROUTING + + } + private Anchor sourceAnchor; private Anchor targetAnchor; private AnchorShape sourceAnchorShape; @@ -81,6 +121,8 @@ private Anchor.Entry sourceEntry; private Anchor.Entry targetEntry; + private RoutingPolicy routingPolicy; + /** * Creates a connection widget. * @param scene the scene @@ -100,6 +142,8 @@ controlPointCutDistance = 0; sourceEntry = new ConnectionEntry (true); targetEntry = new ConnectionEntry (false); + + routingPolicy = RoutingPolicy.ALWAYS_ROUTE; } /** @@ -338,6 +382,30 @@ } /** + * Returns a routing policy. + * @return the routing policy + * @since 2.9 + */ + public final RoutingPolicy getRoutingPolicy () { + return routingPolicy; + } + + /** + * Sets a routing policy. It invokes re-routing in case of routing policy change unless its is changed to DISABLE_ROUTING. + * @param routingPolicy the new routing policy + * @since 2.9 + */ + public final void setRoutingPolicy (RoutingPolicy routingPolicy) { + assert routingPolicy != null; + if (this.routingPolicy == routingPolicy) + return; + boolean changed = routingPolicy != RoutingPolicy.DISABLE_ROUTING; + this.routingPolicy = routingPolicy; + if (changed) + reroute (); + } + + /** * Returns the control-points-based path router of the connection widget. * @return the path router */ @@ -427,8 +495,51 @@ * Forces path routing. */ public final void calculateRouting () { - if (routingRequired) - setControlPoints (router.routeConnection (this), true); + if (routingRequired) { + switch (routingPolicy) { + case ALWAYS_ROUTE: + setControlPoints (router.routeConnection (this), true); + break; + case UPDATE_END_POINTS_ONLY: { + Point sourcePoint = sourceAnchor != null ? sourceAnchor.compute (sourceEntry).getAnchorSceneLocation () : null; + Point targetPoint = targetAnchor != null ? targetAnchor.compute (targetEntry).getAnchorSceneLocation () : null; + if (sourcePoint == null || targetPoint == null) { + controlPoints.clear (); + break; + } + sourcePoint = convertSceneToLocal (sourcePoint); + targetPoint = convertSceneToLocal (targetPoint); + if (controlPoints.size () < 1) + controlPoints.add (sourcePoint); + else + controlPoints.set (0, sourcePoint); + if (controlPoints.size () < 2) + controlPoints.add (targetPoint); + else + controlPoints.set (controlPoints.size () - 1, targetPoint); + } break; + case DISABLE_ROUTING_UNTIL_END_POINT_IS_MOVED: { + Point sourcePoint = sourceAnchor != null ? sourceAnchor.compute (sourceEntry).getAnchorSceneLocation () : null; + Point firstPoint = getFirstControlPoint (); + if (firstPoint != null) + firstPoint = convertLocalToScene (firstPoint); + if (sourcePoint == null ? firstPoint == null : sourcePoint.equals (firstPoint)) { + Point targetPoint = targetAnchor != null ? targetAnchor.compute (targetEntry).getAnchorSceneLocation () : null; + Point lastPoint = getLastControlPoint (); + if (lastPoint != null) + lastPoint = convertLocalToScene (lastPoint); + if (targetPoint == null ? lastPoint == null : targetPoint.equals (lastPoint)) + break; + } + routingPolicy = RoutingPolicy.ALWAYS_ROUTE; + setControlPoints (router.routeConnection (this), true); + } break; + case DISABLE_ROUTING: + break; + default: + throw new IllegalStateException ("Unexpected routing policy: " + routingPolicy); // NOI18N + } + } } /** Index: graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html,v retrieving revision 1.30 diff -u -r1.30 documentation.html --- graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html 10 Aug 2007 13:24:13 -0000 1.30 +++ graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html 23 Aug 2007 09:03:48 -0000 @@ -132,6 +132,7 @@
  • Anchor @@ -857,7 +858,7 @@ Created by: ActionFactory.createAddRemoveControlPointAction

    -The action could be attached to FreeConnectionWidget only and allow user to add a control point by double-clicking on path or remove control point by double-clicking on it. The action requires FreeRouter to be set to the FreeConnectionWidget where the action is attached - otherwise the control points are rerouted and therefore you loose the change. For fixing moving-anchor problem use FreeRectangularAnchor. +The action allows user to add a control point by double-clicking on path or remove control point by double-clicking on it. The action has routingPolicy which is automatically set to ConnectionWidget to prevent discarding of user changes by router assigned to the connection widget. For fixing moving-anchor problem use FreeRectangularAnchor.

    AlignWithMoveAction

    @@ -1175,7 +1176,7 @@
  • RouterFactory.createDirectRouter creates a straight line between the source and the target anchor.
  • RouterFactory.createOrthogonalSeachRouter (CollisionsCollector) creates an orthogonal path that tries to avoid overlapping areas specified by the CollisionsCollector. There is a built-in implementation RouterFactory.createWidgetsCollisionCollector (LayerWidget...) which collects all validated children widgets of the specified layer widgets and for each it gets the widget boundary and claims it as a vertical and horizontal collision. In case of ConnectionWidget, it takes the path (defined by its control points) and claims all horizontal and vertical segments as appropriate collisions.
  • RouterFactory.createOrthogonalSeachRouter (ConnectionWidgetCollisionsCollector) creates an orthogonal path similarly as the previous case but the ConnectionWidgetCollisionsCollector gets a context of currently routed connection widget. -
  • RouterFactory.createFreeRouter is similar to DirectRouter but it modifies only the first and last point of the route. The "middle" control points stay the same. This effect is used by AddRemoveControlPointAction to maintain the control points created by user. +
  • RouterFactory.createFreeRouter is similar to DirectRouter but it modifies only the first and last point of the route. The "middle" control points stay the same. This effect is used by AddRemoveControlPointAction to maintain the control points created by user. From now this router is no longer useful, since it can be replaced by more flexible way: use any router that you like and set "Update-end-points-only" routing policy to the ConnectionWidget.

    ConnectionWidgetLayout

    @@ -1186,6 +1187,23 @@

    See test.connectionlabels.ConnectionLabelsTest for details. +

    Routing Policy

    + +Since version 2.9, the ConnectionWidget class has additional routingPolicy property. It ease management of control points changed by users. There are 4 values: +
      +
    1. ALWAYS_ROUTE - This is default value. The router is always invoked when a ConnectionWidget is changed and needs to be re-routed. +
    2. UPDATE_END_POINTS_ONLY - The router is not invoked. Instead location of the first and the last control points are changed/updated to location computed by source and target anchors. +
    3. DISABLE_ROUTING_UNTIL_END_POINT_IS_MOVED - The router is not invoked until the first or the last control points is moved (means it has different location from one computed by source or target anchor). +
    4. DISABLE_ROUTING - The router is not invoked. The control points are freezed at the same locations. +
    + +These routing policy are very useful when you are using modifying control points: +
      +
    • You can specify routingPolicy value to factory method of AddRemoveControlPointAction and MoveControlPointAction. If not null, then the value is automatically set to a ConnectionWidget which control points are modified by the action. Usually UPDATE_END_POINT_ONLY is used. +
    • Some graph-oriented layout algorithms are resolving not only location of nodes on a scene but also routes path of edges. Then you can use UPDATE_END_POINT_ONLY or DISABLE_ROUTING_UNTIL_END_POINT_IS_MOVED to prevent discard of paths routed by the graph-oriented layout. + +For usages, see test.routing.ActionsWithRoutingPolicyTest and test.routing.RoutingPolicyTest examples. +

      ConnectionWidget Methods

      @@ -1225,6 +1243,9 @@ getRouter
      setRouter Controls a router assigned to the connection widget. The routers is calculating a path and sets a new one using setControlPoints method. + +getRoutingPolicy
      setRoutingPolicy +Controls a routing policy assigned to the connection widget. It controls whether and how control points are re-routed. For details, see Routing Policy section. getControlPoints()
      setControlPoints(List<Point>controlPoints,boolean sceneLocations)
      getControlPoint(int index) Manipulates with control points. If the sceneLocations is true then the controlPoints are recalculated relatively to the connection widget location otherwise controlPoints are taken as they are (and therefore they are taken as local locations). This method is usually called by the assigned router. Index: graph/lib/src/org/netbeans/modules/visual/action/AddRemoveControlPointAction.java =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/modules/visual/action/AddRemoveControlPointAction.java,v retrieving revision 1.3 diff -u -r1.3 AddRemoveControlPointAction.java --- graph/lib/src/org/netbeans/modules/visual/action/AddRemoveControlPointAction.java 14 Nov 2006 10:04:21 -0000 1.3 +++ graph/lib/src/org/netbeans/modules/visual/action/AddRemoveControlPointAction.java 23 Aug 2007 09:03:48 -0000 @@ -18,95 +18,73 @@ */ package org.netbeans.modules.visual.action; -import java.awt.Point; -import java.awt.geom.Line2D; -import java.util.ArrayList; import org.netbeans.api.visual.action.WidgetAction; import org.netbeans.api.visual.widget.ConnectionWidget; import org.netbeans.api.visual.widget.Widget; +import java.awt.*; import java.awt.event.MouseEvent; -import java.util.List; -import org.netbeans.api.visual.action.WidgetAction.State; +import java.awt.geom.Line2D; +import java.util.ArrayList; /** * @author Alex */ public class AddRemoveControlPointAction extends WidgetAction.Adapter { - private double createSensitivity=1.00, deleteSensitivity=5.00; - private ConnectionWidget cWidget; - - public AddRemoveControlPointAction(){ - - } - - public AddRemoveControlPointAction(double createSensitivity, double deleteSensitivity) { + private double createSensitivity; + private double deleteSensitivity; + private ConnectionWidget.RoutingPolicy routingPolicy; + + public AddRemoveControlPointAction (double createSensitivity, double deleteSensitivity, ConnectionWidget.RoutingPolicy routingPolicy) { this.createSensitivity = createSensitivity; this.deleteSensitivity = deleteSensitivity; + this.routingPolicy = routingPolicy; } public State mouseClicked(Widget widget, WidgetMouseEvent event) { if(event.getButton()==MouseEvent.BUTTON1 && event.getClickCount()==2 && widget instanceof ConnectionWidget) { - cWidget=(ConnectionWidget)widget; - Point point=event.getPoint(); - addRemoveControlPoint (point); + addRemoveControlPoint ((ConnectionWidget) widget, event.getPoint ()); + return State.CONSUMED; } return State.REJECTED; } /** * Adds or removes a control point on a specified location + * @param widget the connection widget * @param localLocation the local location */ - private void addRemoveControlPoint (Point localLocation) { - ArrayList list = new ArrayList (cWidget.getControlPoints()); - if(!removeControlPoint(localLocation,list,deleteSensitivity)){ - Point exPoint=null;int index=0; - for (Point elem : list) { - if(exPoint!=null){ - Line2D l2d=new Line2D.Double(exPoint,elem); - if(l2d.ptLineDist(localLocation) list = new ArrayList (widget.getControlPoints ()); + if (!removeControlPoint (localLocation, list, deleteSensitivity)) { + Point exPoint = null; + int index = 0; + for (Point elem : list) { + if (exPoint != null) { + Line2D l2d = new Line2D.Double (exPoint, elem); + if (l2d.ptLineDist (localLocation) < createSensitivity) { + list.add (index, localLocation); + break; } - exPoint=elem;index++; } + exPoint = elem; + index++; } - cWidget.setControlPoints(list,false); + } + if (routingPolicy != null) + widget.setRoutingPolicy (routingPolicy); + widget.setControlPoints (list, false); } private boolean removeControlPoint(Point point, ArrayList list, double deleteSensitivity){ for (Point elem : list) { - if(elem.distance(point) controlPoints=cWidget.getControlPoints(); - if (controlPoints.size () <= 0) return null; - return new Point (controlPoints.get (index)); - } - - /** - * Sets a sensitivity. - * @param createSensitivity the sensitivity for adding a control point - * @param deleteSensitivity the sensitivity for removing a control point - */ - public void setSensitivity(double createSensitivity, double deleteSensitivity){ - this.createSensitivity=createSensitivity; - this.deleteSensitivity=deleteSensitivity; - } - } Index: graph/lib/src/org/netbeans/modules/visual/action/MoveControlPointAction.java =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/modules/visual/action/MoveControlPointAction.java,v retrieving revision 1.2 diff -u -r1.2 MoveControlPointAction.java --- graph/lib/src/org/netbeans/modules/visual/action/MoveControlPointAction.java 14 Nov 2006 10:04:21 -0000 1.2 +++ graph/lib/src/org/netbeans/modules/visual/action/MoveControlPointAction.java 23 Aug 2007 09:03:48 -0000 @@ -32,14 +32,16 @@ public final class MoveControlPointAction extends WidgetAction.LockedAdapter { private MoveControlPointProvider provider; + private ConnectionWidget.RoutingPolicy routingPolicy; private ConnectionWidget movingWidget = null; private Point controlPointLocation; private int controlPointIndex; private Point lastLocation = null; - public MoveControlPointAction (MoveControlPointProvider provider) { + public MoveControlPointAction (MoveControlPointProvider provider, ConnectionWidget.RoutingPolicy routingPolicy) { this.provider = provider; + this.routingPolicy = routingPolicy; } protected boolean isLocked () { @@ -90,6 +92,8 @@ if (controlPoints == null) return State.REJECTED; + if (routingPolicy != null) + movingWidget.setRoutingPolicy (routingPolicy); movingWidget.setControlPoints (controlPoints, false); return State.createLocked (widget, this); } Index: graph/www/documentation.html =================================================================== RCS file: /cvs/graph/www/documentation.html,v retrieving revision 1.109 diff -u -r1.109 documentation.html --- graph/www/documentation.html 20 Aug 2007 16:41:56 -0000 1.109 +++ graph/www/documentation.html 23 Aug 2007 09:03:48 -0000 @@ -173,6 +173,8 @@

    • test.resize.ResizeTest - how to use ResizeAction
    • test.router.OSRCollisionsCollectorTest - test of bugfix #96462 - Incorrectly routed path by OrthogonalSearchRouter when a target in collision region
    • test.router.OSRComputeControlPointsTest - test of bugfix #96460 - Wrong control points computation in OrthogonalSearchRouter +
    • test.routing.ActionsWithRoutingPolicyTest - how to use routing policy with AddRemoveControlPointAction and MoveControlPointAction +
    • test.routing.RoutingPolicyTest - how to use routing policy of ConnectionWidget
    • test.sceneresize.LimitedSceneTest - test of cooperation of OrthogonalSearchRouter with Scene.maximumBounds property
    • test.sceneresize.SceneResizeTest - test of bugfix #84604 - scene resize based on Scene view component
    • test.scroll.ScrollTest - how to use ScrollWidget for scrollable view