仿VISIO连线
Posted soy-technology
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了仿VISIO连线相关的知识,希望对你有一定的参考价值。
说明:
1、未实现障碍物自动避让功能;
2、未实现添加图元到连线之间,连线自动避开新增图元功能;
后续再完善...
package com.sunsheen.jfids.studio.uml.modulediagram.anchorAndRouter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.Assert; import org.eclipse.draw2d.BendpointConnectionRouter; import org.eclipse.draw2d.Connection; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.draw2d.geometry.Vector; /** * uml连接线路由算法 * 1、一旦用户对某条连线的路由方式进行了调整,就不再为其提供智能路由布线的功能。 * 2、用户是否对连线的路径进行了调整的信息是需要持久存储的。 * 3、用户在建模时,只有当发生了连线和模型的布局冲突时,才对存在布局冲突的连线进行路由调整,对其他连线不做更改。 * * @author WangSong */ public class AIUmlConnectionRouter extends BendpointConnectionRouter private IFigure content;// 当前操作的图元 private final static int DEFAULT_SPACE = 10;// 默认点间距 private PointList points;// 连线上位置点集合 private int space; /* 离障碍物的间隙 */ private Vector endDirection;// 结束方向 private Point endPoint;// 结束位置 // 连线是否跟图元起点边平行 private boolean parallelStartSide; // 连线是否跟图元终点边平行 private boolean parallelEndSide; // 连线跟连接点平行的边(源图元) private String parallelSideSource; // 上下左右 // 连线跟连接点平行的边(目标图元) private String parallelSideTarget; // 上下左右 private int rectangleAffirm = 0;// 初始化当前图元选择 //冲突图元、拐点、关联关系 Map<Rectangle,List<Point[]>> rectangleLinesRelationMap = new HashMap<Rectangle,List<Point[]>>();//关联关系 private List<Rectangle> conflictRectangleList = new ArrayList<Rectangle>(); //有冲突的图元 private List<Point[]> conflictPointArrayList = new ArrayList<Point[]>();//存放一对一对冲突的拐点 private boolean sourceAcrossCenterPoint;//连线是否跨过源图元或者目标图元中心点(原图原) private boolean targetAcrossCenterPoint;//连线是否跨过源图元或者目标图元中心点(目标图元) private Rectangle sourceRect;// 初始化矩形图元 private Rectangle targetRect;//初始化目標圖元 //源点位于源图元的边 private String sourceSide; //源点位于目标图元的边 private String targetSide; // 初始化上下左右方向(从原点看) private final Vector DOWN = new Vector(0, -1),//下 UP = new Vector(0, 1), //上 LEFT = new Vector(-1, 0),//左 RIGHT = new Vector(1, 0),//右 LEFT_UP = new Vector(-1,1),//左上 RIGHT_UP = new Vector(1,1),//右上 LEFT_DOWN = new Vector(-1,-1),//左下 RIGHT_DOWN = new Vector(1,-1);//右下 //直线方向数组 private Vector[] straightLineArr = DOWN,UP,LEFT,RIGHT; //折线集合 private Vector[] brokenLineArr = LEFT_UP,RIGHT_UP,LEFT_DOWN,RIGHT_DOWN; public AIUmlConnectionRouter(IFigure content) this(content, DEFAULT_SPACE); public AIUmlConnectionRouter(IFigure content, int space) Assert.isNotNull(content); Assert.isLegal(space > 0, "空间间距不能为0!"); this.content = content; this.space = space; this.points = new PointList(); // 是否能连接 private boolean validConn(Connection conn) if ((conn.getSourceAnchor() == null) || (conn.getTargetAnchor() == null)) return false; return true; //初始化连线间冲突图元集合 private void conflictRectangleJudge(Connection conn) //获取到连线中的所有图元 List<IFigure> figures = conn.getChildren(); //这种方式获取不到连线中的所有图元,需要修改,后续完成.... /////////////////////////////////////////////////// //得到当前连线上所有图元 //所有图元周围添加拐点 /////////////////////////////////////////////////// PointList allPoint = conn.getPoints(); //得到冲突图元 for(IFigure f : figures) Rectangle currentR = f.getBounds().getCopy();//当前图元 f.translateToAbsolute(currentR);// //取出当前连线所有的拐点 for(int i=0;i<allPoint.size();i++) //最后一个点时,不能再进行检测 if(i == allPoint.size() - 1) break; //两个拐点之间是垂直或者平行的线段,存在有冲突的图元 Point start = allPoint.getPoint(i); Point end = allPoint.getPoint(i+1); //会依次检查当前图元是否跟连线冲突 if(detectionRectangleClash(currentR,start,end)) //可能存在拐点在冲突图元内(两段线段跟当前图元冲突)の情况 //拐点在冲突图元内的情况 if(!conflictRectangleList.contains(currentR)) conflictRectangleList.add(currentR);//存为冲突图元 //拐点在冲突图元外的情况 Point[] segment = start,end; conflictPointArrayList.add(segment);//存放冲突线段 //存入关联关系 rectangleLinesRelationMap.put(currentR, conflictPointArrayList); //检测当前图元是否跟线段冲突 private boolean detectionRectangleClash(Rectangle currentR,Point start,Point end) boolean result = false; //垂直情况下,跟当前图元是否冲突 if(start.x == end.x) if((currentR.x <= start.x) && (start.x <= currentR.x+currentR.width) ) result = true; //水平连线,是否跟当前图元冲突 else if(start.y == end.y) if((start.y >= currentR.y) && (start.y <= currentR.y+currentR.height)) result = true; return result; /* * 连线路由 */ @Override public void route(Connection conn) points.removeAllPoints();// 清空连线 Point startPoint = getStartPoint(conn).getCopy();// 起点 conn.translateToRelative(startPoint);// 设置连接线起点 points.addPoint(startPoint);// 添加到路由连线点集合 endPoint = getEndPoint(conn).getCopy();// 终点 conn.translateToRelative(endPoint);// 设置连接线终点 // 是否能连接 if (validConn(conn)) Vector sdirection = getStartDirection(conn);// 得到起始方向 endDirection = getEndDirection(conn);// 终点方向 //连线方向异常情况 if(null == sdirection) return; else if(null == endDirection) endDirection = sdirection; //是直线且没有冲突图元时:调用直线路由算法 if(Arrays.asList(straightLineArr).contains(sdirection) && !sourceAcrossCenterPoint && !targetAcrossCenterPoint) processPoints(startPoint, sdirection, null);//调用直线路由算法 //斜线或者直线间有图元冲突,调用折线路由算法 else polyline(startPoint, sdirection) ;//折线路由算法 // 添加终点到连接线集合 if(null != endPoint) points.addPoint(endPoint); /////////////////////冲突图元应该在所有拐点连线完成之后再判断、绘制//////////////////////// //当前折线上冲突图元检测 conflictRectangleJudge(conn); //TODO 修正冲突图元周围的连线轨迹 // 通过连接点设置线轨迹 conn.setPoints(points.getCopy()); endDirection = null;// 清空终点方向 endPoint = null;// 清空终点位置 //将判断连线障碍物冲突规则重置 rectangleAffirm = 0;// 重置图元计数器 parallelSideTarget = null; parallelSideSource = null; parallelEndSide = false; parallelStartSide = false; sourceAcrossCenterPoint = false; targetAcrossCenterPoint = false; sourceRect = null; targetRect = null; sourceSide = null; targetSide = null; rectangleLinesRelationMap.clear(); conflictRectangleList.clear(); conflictPointArrayList.clear(); System.out.println("冲突图元的个数:"+conflictRectangleList.size()); System.out.println("当前连线的拐点数:"+points.size()); //折线连接 private void polyline(Point startPoint, Vector sdirection) //1、直线(垂直、水平)情况,源图元或者目标图元一定存在至少一个图元冲突,其余位置可能存在图元冲突 //源图元冲突 if(sourceAcrossCenterPoint) //连线中是否存在图元冲突 if(conflictRectangleList.isEmpty()) //连线中只有源图元冲突 //上边界向下连接 if(sdirection == DOWN) Point first = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE);//向上折点 points.addPoint(first); Point second = new Point((startPoint.x) + (sourceRect.width / 2+DEFAULT_SPACE),first.y);//向右折点 points.addPoint(second); Point third = new Point(second.x,endPoint.y - (DEFAULT_SPACE+1));//向下折点 Point fourth = new Point(startPoint.x,third.y);//向左折点 //如果终点也冲突,不需要当前两个拐点 if(!targetAcrossCenterPoint) points.addPoint(third); points.addPoint(fourth); //下边界向上 else if(sdirection == UP) Point first = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE);//向下折点 Point second = new Point((startPoint.x) + (sourceRect.width / 2+DEFAULT_SPACE),first.y);//向右折点 Point third = new Point(second.x,endPoint.y + DEFAULT_SPACE+1);//向上折点 Point fourth = new Point(endPoint.x,third.y);//向左折点 points.addPoint(first); points.addPoint(second); if(!targetAcrossCenterPoint) points.addPoint(third); points.addPoint(fourth); //左边界向右 else if(sdirection == RIGHT) Point first = new Point(startPoint.x - DEFAULT_SPACE,startPoint.y);//向左折点 Point second = new Point(first.x,(sourceRect.height/2 + DEFAULT_SPACE) + first.y);//向下折点 Point third = new Point(startPoint.x + DEFAULT_SPACE + sourceRect.width,second.y);//向右折点 Point fourth = new Point(third.x,startPoint.y);//向上折点 points.addPoint(first); points.addPoint(second); //如果目标图元有冲突,不需要最后两个拐点 if(!targetAcrossCenterPoint) points.addPoint(third); points.addPoint(fourth); //右边界向左 else if(sdirection == LEFT) Point first = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y);//向右折点 Point second = new Point(first.x,(sourceRect.height/2 + DEFAULT_SPACE) + first.y);//向下折点 Point third = new Point(startPoint.x - DEFAULT_SPACE - sourceRect.width,second.y);//向左折点 Point fourth = new Point(third.x,startPoint.y);//向上折点 points.addPoint(first); points.addPoint(second); //如果目标图元有冲突,不需要最后两个拐点 if(!targetAcrossCenterPoint) points.addPoint(third); points.addPoint(fourth); //存在连线中布局冲突时 else for(Rectangle r : conflictRectangleList) //TODO 绕开冲突图元 //目标图元冲突 if(targetAcrossCenterPoint) //连线中是否存在图元冲突 if(conflictRectangleList.isEmpty()) //连线中只有目标图元冲突 //上边界向下连接(终点在下边界) if(sdirection == DOWN) Point first = new Point(endPoint.x,endPoint.y - DEFAULT_SPACE-1);//向上折点 Point second = new Point((endPoint.x) + (targetRect.width / 2+DEFAULT_SPACE),first.y);//向右折点 Point third = new Point(second.x,endPoint.y + (DEFAULT_SPACE-1));//向下折点 Point fourth = new Point(endPoint.x,third.y);//向左折点 //如果源图元有冲突,不需要头两个拐点 if(!sourceAcrossCenterPoint) points.addPoint(first); points.addPoint(second); points.addPoint(third); points.addPoint(fourth); //下边界向上(终点在上边界) else if(sdirection == UP) Point first = new Point(endPoint.x,endPoint.y - DEFAULT_SPACE);//向上折点 Point second = new Point(endPoint.x + (targetRect.width / 2+DEFAULT_SPACE),first.y);//向右折点 Point third = new Point(second.x,endPoint.y + targetRect.width + (DEFAULT_SPACE - 1));//向下折点 Point fourth = new Point(endPoint.x,third.y);//向左折点 ///////注意:这里添加拐点的顺序决定了线的形状 //如果源图元有冲突,不需要尾两个拐点 if(!sourceAcrossCenterPoint) points.addPoint(fourth); points.addPoint(third); points.addPoint(second); points.addPoint(first); //左边界向右(终点在右边界) else if(sdirection == RIGHT) Point first = new Point(endPoint.x + DEFAULT_SPACE,endPoint.y);//向左折点 Point second = new Point(first.x,(targetRect.height/2 + DEFAULT_SPACE) + first.y);//向下折点 Point third = new Point(endPoint.x - DEFAULT_SPACE - sourceRect.width,second.y);//向右折点 Point fourth = new Point(third.x,endPoint.y);//向上折点 //如果源图元有冲突,不需要尾两个拐点 if(!sourceAcrossCenterPoint) points.addPoint(fourth); points.addPoint(third); points.addPoint(second); points.addPoint(first); //右边界向左(终点在左边界) else if(sdirection == LEFT) Point first = new Point(endPoint.x - DEFAULT_SPACE,endPoint.y);//向左折点 Point second = new Point(first.x,(targetRect.height/2 + DEFAULT_SPACE) + first.y);//向下折点 Point third = new Point(endPoint.x + DEFAULT_SPACE + targetRect.width,second.y);//向右折点 Point fourth = new Point(third.x,endPoint.y);//向上折点 //如果源图元有冲突,不需要尾两个拐点 if(!sourceAcrossCenterPoint) points.addPoint(fourth); points.addPoint(third); points.addPoint(second); points.addPoint(first); else //存在连线中布局冲突 for(Rectangle r : conflictRectangleList) //TODO 绕开冲突图元 //2、折线情况,可能图元冲突也可能没有图元冲突 if(Arrays.asList(brokenLineArr).contains(sdirection)) //没有冲突图元的情况 if(conflictRectangleList.isEmpty()) //***************左上方向******************* if(sdirection == LEFT_UP) leftUpOrRightDown(startPoint,endPoint,sourceSide,targetSide,sourceRect,targetRect); //***************左下方向************* else if(sdirection == LEFT_DOWN) leftDownOrRightUp(startPoint,endPoint,sourceSide,targetSide,sourceRect,targetRect); //***************右上方向************* else if(sdirection == RIGHT_UP) leftDownOrRightUp(endPoint,startPoint,targetSide,sourceSide,targetRect,sourceRect); //***************右下方向************* else if(sdirection == RIGHT_DOWN) leftUpOrRightDown(endPoint,startPoint,targetSide,sourceSide,targetRect,sourceRect); // 存在冲突图元的情况 else //取出当前冲突图元跟冲突线段,重新设置拐点 for(Map.Entry<Rectangle,List<Point[]>> relation : rectangleLinesRelationMap.entrySet()) Rectangle rectangle = relation.getKey();//conflictPointArrayList List<Point[]> points = relation.getValue(); //通过冲突位置,重新绘制拐点 // TODO //左上&右下路由算法(右边图元为源图元) private void leftUpOrRightDown(Point startPoint,Point endPoint, String sourceSide,String targetSide, Rectangle sourceRect,Rectangle targetRect) //有上下左右四个边起点 //上边情况 if(sourceSide.equals("上") && targetSide.equals("右")) //上右边(两种情况) if(targetRect.y > sourceRect.y + DEFAULT_SPACE) Point one = new Point(startPoint.x,endPoint.y); points.addPoint(one); else Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(startPoint.x - sourceRect.width - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("上") && targetSide.equals("上")) //上上边 Point one = new Point(startPoint.x,endPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x,one.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); else points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("上") && targetSide.equals("左")) //上左边 //目标图元在上方是一种连接方法,在下方是另一种连接方法 if((targetRect.y + targetRect.height) < (sourceRect.y - DEFAULT_SPACE)) //目标图元在源图元上方 Point one = new Point(startPoint.x,endPoint.y + targetRect.height/2 + DEFAULT_SPACE); Point two = new Point(endPoint.x - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); else //目标图元在源图元的下方 Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("上") && targetSide.equals("下")) //上下边(两种情况) if(targetRect.y < sourceRect.y) Point one = new Point(startPoint.x,endPoint.y + DEFAULT_SPACE); Point two = new Point(endPoint.x,one.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); else points.addPoint(two); points.addPoint(one); else Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x + targetRect.width/2 + DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y + DEFAULT_SPACE); Point four = new Point(endPoint.x,three.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); else points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); //左边情况 if(sourceSide.equals("左") && targetSide.equals("右")) Point one = new Point(startPoint.x - DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); else points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("左") && targetSide.equals("上")) Point one = new Point(startPoint.x - DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y - DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("左") && targetSide.equals("左")) Point one = null,two = null,three=null,four=null; //1、左边图元下边在右边图元上边界之上 if((targetRect.y+targetRect.height) < (sourceRect.y - DEFAULT_SPACE)) one = new Point(endPoint.x - DEFAULT_SPACE,startPoint.y); two = new Point(one.x,endPoint.y); //2、左边图元下边在右边图元的高度范围内 else one = new Point(targetRect.x+targetRect.width+DEFAULT_SPACE,startPoint.y); two = new Point(one.x,targetRect.y+targetRect.height+DEFAULT_SPACE); three = new Point(endPoint.x - DEFAULT_SPACE,two.y); four = new Point(three.x,endPoint.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); if(null != three && null != four) points.addPoint(three); points.addPoint(four); else if(null != three && null != four) points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("左") && targetSide.equals("下")) Point one = new Point(endPoint.x,startPoint.y); points.addPoint(one); //右边情况 if(sourceSide.equals("右") && targetSide.equals("右")) //两种情况 //1、目标图元的下边在源图元上边的上方 if(sourceRect.y > (targetRect.y + targetRect.height)) Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); else points.addPoint(two); points.addPoint(one); else //2、目标图元的下边界在源图元高度范围内 Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,startPoint.y - sourceRect.width/2 - DEFAULT_SPACE); Point three = new Point(sourceRect.x - DEFAULT_SPACE,two.y); Point four = new Point(three.x,endPoint.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); else points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("右") && targetSide.equals("上")) Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y - DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("右") && targetSide.equals("左")) //1、目标图元下边界在源图元上边界上面 if((targetRect.y+targetRect.height) < sourceRect.y - DEFAULT_SPACE) Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,sourceRect.y - DEFAULT_SPACE); Point three = new Point(endPoint.x - DEFAULT_SPACE,two.y); Point four = new Point(three.x,endPoint.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); else points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); else Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y - targetRect.width/2 - DEFAULT_SPACE); Point three = new Point(endPoint.x - DEFAULT_SPACE,two.y); Point four = new Point(three.x,endPoint.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); else points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("右") && targetSide.equals("下")) Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y + DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); //下边情况 if(sourceSide.equals("下") && targetSide.equals("右")) Point one = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE); Point two = new Point(one.x - sourceRect.width - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("下") && targetSide.equals("上")) Point one = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE); Point two = new Point(one.x - sourceRect.width - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y - DEFAULT_SPACE); Point four = new Point(endPoint.x,three.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); else points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("下") && targetSide.equals("左")) Point one = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE); Point two = new Point(endPoint.x - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("下") && targetSide.equals("下")) Point one = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE); Point two = new Point(endPoint.x,one.y); if(endDirection == LEFT_UP) points.addPoint(one); points.addPoint(two); else points.addPoint(two); points.addPoint(one); //左下&右上路由算法 private void leftDownOrRightUp(Point startPoint,Point endPoint, String sourceSide,String targetSide, Rectangle sourceRect,Rectangle targetRect) //右边图元下边 if(sourceSide.equals("下") && targetSide.equals("右")) Point one = new Point(startPoint.x,endPoint.y); points.addPoint(one); else if(sourceSide.equals("下") && targetSide.equals("上")) Point one = new Point(startPoint.x,endPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x,one.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); else points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("下") && targetSide.equals("左")) Point one = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE); Point two = new Point(endPoint.x - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("下") && targetSide.equals("下")) Point one = new Point(startPoint.x,endPoint.y + DEFAULT_SPACE); Point two = new Point(endPoint.x,one.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); else points.addPoint(two); points.addPoint(one); //右边图元右边 if(sourceSide.equals("右") && targetSide.equals("右")) Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); else points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("右") && targetSide.equals("上")) Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x ,endPoint.y - DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("右") && targetSide.equals("左")) //1、目标图元上边界在源图元下边界上面 if((sourceRect.y + sourceRect.height) > targetRect.y) Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x ,endPoint.y + DEFAULT_SPACE + targetRect.height/2); Point three = new Point(endPoint.x - DEFAULT_SPACE,two.y); Point four = new Point(three.x,endPoint.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); else points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); else Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x ,startPoint.y + DEFAULT_SPACE + sourceRect.height/2); Point three = new Point(endPoint.x - DEFAULT_SPACE,two.y); Point four = new Point(three.x,endPoint.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); else points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("右") && targetSide.equals("下")) Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x ,endPoint.y + DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); //右边图元上边 if(sourceSide.equals("上") && targetSide.equals("右")) Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x + DEFAULT_SPACE ,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("上") && targetSide.equals("上")) Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x ,one.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); else points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("上") && targetSide.equals("左")) Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("上") && targetSide.equals("下")) Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x + targetRect.width/2 + DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y + DEFAULT_SPACE); Point four = new Point(endPoint.x,three.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); else points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); //右边图元左边 if(sourceSide.equals("左") && targetSide.equals("右")) Point one = new Point(startPoint.x - DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); else points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("左") && targetSide.equals("上")) Point one = new Point(endPoint.x,startPoint.y); points.addPoint(one); else if(sourceSide.equals("左") && targetSide.equals("左")) Point one = null,two = null,three = null,four = null; //1、右边图元中心点在左边图元上边界的上面 if(startPoint.y < targetRect.y) one = new Point(endPoint.x - DEFAULT_SPACE,startPoint.y); two = new Point(one.x,endPoint.y); else one = new Point(targetRect.x+targetRect.width+DEFAULT_SPACE,startPoint.y); two = new Point(one.x,targetRect.y - DEFAULT_SPACE); three = new Point(endPoint.x - DEFAULT_SPACE,two.y); four = new Point(three.x,endPoint.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); if(null != three && null != four) points.addPoint(three); points.addPoint(four); else if(null != three && null != four) points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); else if(sourceSide.equals("左") && targetSide.equals("下")) Point one = new Point(startPoint.x - DEFAULT_SPACE,startPoint.y ); Point two = new Point(one.x,endPoint.y + DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_DOWN) points.addPoint(one); points.addPoint(two); points.addPoint(three); else points.addPoint(three); points.addPoint(two); points.addPoint(one); // 设置上下左右方向 private void processPoints(Point startPoint, Vector direction, Rectangle parallelObs) if (direction == UP) processUp(startPoint, parallelObs); else if (direction == DOWN) processDown(startPoint, parallelObs); else if (direction == LEFT) processLeft(startPoint, parallelObs); else if(direction == RIGHT) processRight(startPoint, parallelObs); // 设置向右 private void processRight(Point startPoint, Rectangle parallelObs) Point newStartPoint = new Point(startPoint);// 起始位置 //源图元冲突检测 monitorStartCollide(startPoint); //目标图元冲突检测 monitorEndCollide(endPoint); int min_xd = 0; Rectangle obstracle = null;//布局冲突的图元 List<IFigure> list = content.getChildren();// 当前图元的子 // 遍历每个图元 for (IFigure f : list) Rectangle fr = f.getBounds();// 当前子图元矩形 // 用户在矩形中连线,不操作 if (containPoint(fr, endPoint) || containPoint(fr, startPoint) || fr.x > endPoint.x) continue; // 用户在矩形外连线(起点和终点没有同时在一个矩形上) int xd = fr.x - startPoint.x;// 矩形左边跟起始点x方向距离(正数:左侧;负数:右侧) // 如果当前连线起点在图元上 if (xd > 0 && fr.y <= startPoint.y && (fr.y + fr.height) >= startPoint.y) // 图元之间水平距离控制 if (xd < min_xd || min_xd == 0) min_xd = xd; obstracle = fr;// 最后一个子图元 conflictRectangleList.add(obstracle); if (min_xd == 0) // no obstacles if (parallelObs == null) // y坐标直线 if (newStartPoint.y == endPoint.y) return; else // 连线未到目标图元,继续折叠 if (newStartPoint.x < parallelObs.x) newStartPoint.x -= (parallelObs.x - newStartPoint.x) / 2;// x坐标对半弯曲 // 连线未到目标图元 if (newStartPoint.x < endPoint.x) // 如果方向向上或者向下 if (isVertical(endDirection, RIGHT)) newStartPoint.x = endPoint.x;// 重新设置起始x坐标 else // 如果方向向右 if (endDirection.equals(RIGHT)) newStartPoint.x = endPoint.x + space;// 新起始点坐标 = 终点坐标 + // 距离障碍物距离 else // 方向向左 newStartPoint.x += (endPoint.x - newStartPoint.x) / 2;// 折半弯曲 // 跟图元还有水平间距 else int x = newStartPoint.x + min_xd - space;// 重置水平方向 if (x < newStartPoint.x) x = newStartPoint.x + min_xd / 2; newStartPoint.x = x; if (parallelObs != null) if (newStartPoint.x >= parallelObs.x && newStartPoint.x <= parallelObs.x + parallelObs.width) newStartPoint.x = parallelObs.x + parallelObs.width + space; if (!newStartPoint.equals(startPoint)) points.addPoint(newStartPoint); // next Vector newDirection = UP; if (obstracle == null) if (endPoint.y > newStartPoint.y) newDirection = DOWN; else if (endPoint.y > obstracle.y) newDirection = DOWN; processPoints(newStartPoint, newDirection, obstracle); // 处理向左的连接 private void processLeft(Point startPoint, Rectangle parallelObs) Point newStartPoint = new Point(startPoint); //源图元冲突检测 monitorStartCollide(startPoint); //目标图元冲突检测 monitorEndCollide(endPoint); int min_xd = 0; Rectangle obstracle = null;// 初始化障碍物 List<IFigure> list = content.getChildren(); for (IFigure f : list) Rectangle fr = f.getBounds(); // 起始点和结束点在当前图元里面,不绘制连线 // ////////////////这里代表有障碍物,需要绘制绕开障碍物的连线折点/////////////////////////// if (containPoint(fr, endPoint) || containPoint(fr, startPoint) || (fr.x + fr.width) <= endPoint.x) continue; // TODO 注释掉continue,绘制避开障碍物的折点 int xd = startPoint.x - fr.x - fr.width; if (xd > 0 && fr.y <= startPoint.y && (fr.y + fr.height) >= startPoint.y) if (xd < min_xd || min_xd == 0) min_xd = xd; obstracle = fr; conflictRectangleList.add(obstracle); if (min_xd == 0) // no obstacles // not need bend point if (parallelObs == null) if (newStartPoint.y == endPoint.y) return; else if (newStartPoint.x > parallelObs.x + parallelObs.width) newStartPoint.x -= (newStartPoint.x - parallelObs.x - parallelObs.width) / 2; if (newStartPoint.x > endPoint.x) // 水平方向 if (isVertical(endDirection, LEFT)) newStartPoint.x = endPoint.x;// 直接连接到结束的坐标点(设置横线折点x坐标) else // 垂直方向 if (endDirection.equals(LEFT)) newStartPoint.x = endPoint.x - space; else newStartPoint.x += (newStartPoint.x - endPoint.x) / 2; else int x = newStartPoint.x + min_xd - space; if (x < newStartPoint.x) x = newStartPoint.x + min_xd / 2; newStartPoint.x = x; if (parallelObs != null) if (newStartPoint.x >= parallelObs.x && newStartPoint.x <= (parallelObs.x + parallelObs.width)) newStartPoint.x = parallelObs.x - space; if (!newStartPoint.equals(startPoint)) points.addPoint(newStartPoint);// 添加转折点坐标 // next row point Vector newDirection = UP;// 初始化连线方向 if (obstracle == null) if (endPoint.y > newStartPoint.y) newDirection = DOWN;// 判断真实的连线方向 else if (endPoint.y >= obstracle.y) newDirection = DOWN; processPoints(newStartPoint, newDirection, obstracle); // 处理向下的连接 private void processDown(Point startPoint, Rectangle parallelObs) Point newStartPoint = new Point(startPoint);// 建立起始点位置 //源图元冲突检测 monitorStartCollide(startPoint); //目标图元冲突检测 monitorEndCollide(endPoint); int min_yd = 0; Rectangle obstracle = null;// 初始化障碍图元(默认没有) // ///////////这里的图元获取不正确////////////// List<IFigure> list = content.getChildren();// 得到当前连线中子图元 for (IFigure f : list) Rectangle fr = f.getBounds();// 当前图元的矩形 // 如果在当前单个图元绘制,不建立连接 if (containPoint(fr, endPoint) || containPoint(fr, startPoint) || fr.y > endPoint.y) continue; int yd = fr.y - startPoint.y;// 当前起始点跟当前图元垂直方向距离(为负数时是起始图元,正数可能存在布局冲突) // 判断当前图元是否是障碍物 // ////////////会把目标图元也判定成障碍物,需要修改////////////////// if (yd > 0 && fr.x <= startPoint.x && (fr.x + fr.width) >= startPoint.x) if (yd < min_yd || min_yd == 0) min_yd = yd; obstracle = fr;// 设置障碍图元 conflictRectangleList.add(obstracle); // 如果没有子图元或者没有障碍物 if (min_yd == 0) // 不需要去弯曲其他点 if (parallelObs == null) if (newStartPoint.x == endPoint.x) return; else // 设置第一个弯曲点 if (parallelObs.y > startPoint.y) newStartPoint.y += (parallelObs.y - startPoint.y) / 2; // 如果还没有连线到结束点 if (newStartPoint.y < endPoint.y) // 当前连线绘制方向是水平方向 if (isVertical(endDirection, DOWN)) newStartPoint.y = endPoint.y; // 重新设置起始点y坐标 // TODO avoid itself else // 当前方向是向下 if (endDirection.equals(DOWN)) newStartPoint.y = startPoint.y + space;// 转折点y坐标设置 else newStartPoint.y += (endPoint.y - newStartPoint.y) / 2;// 取中间点位置作为折点 else // 存在障碍物情况 int y = newStartPoint.y + min_yd - space; if (y < newStartPoint.y) y = newStartPoint.y + min_yd / 2; newStartPoint.y = y; // 父图元、障碍物都不为空 if (parallelObs != null) // 起始y坐标在父图元内 if (newStartPoint.y > parallelObs.y && newStartPoint.y < parallelObs.y + parallelObs.height) newStartPoint.y = parallelObs.y + parallelObs.height + space;// 转折点y坐标赋值 // 添加转折点到连线集合 if (!newStartPoint.equals(startPoint)) points.addPoint(newStartPoint);// 依次添加转折点 // 下一个转折点 Vector newDirection = LEFT;// 初始化方向向左 // 没有障碍物情况 if (obstracle == null) if (endPoint.x > newStartPoint.x) newDirection = RIGHT;// 连线方向判定 else // 存在障碍物情况 if (endPoint.x > (obstracle.x + obstracle.width)) newDirection = RIGHT; // 调用折线算法,重新设置转折点 processPoints(newStartPoint, newDirection, obstracle); // 是否垂直 boolean isVertical(Vector v1, Vector v2) double val = v1.x * v2.x + v1.y * v2.y; if (val == 0) return true; return false; // 当前点位置是否在矩形中 boolean containPoint(Rectangle r, Point p) return p.x >= r.x && p.x <= r.x + r.width && p.y >= r.y && p.y <= r.y + r.height; // 处理向上的连接 private void processUp(Point startPoint, Rectangle parallelObs) Point newStartPoint = new Point(startPoint); //源图元冲突检测 monitorStartCollide(startPoint); //目标图元冲突检测 monitorEndCollide(endPoint); int min_yd = 0; Rectangle obstracle = null; List<IFigure> list = content.getChildren(); for (IFigure f : list) Rectangle fr = f.getBounds(); if (containPoint(fr, endPoint) || containPoint(fr, startPoint) || (fr.y + fr.height) <= endPoint.y) continue; int yd = startPoint.y - fr.y - fr.height; if (yd > 0 && fr.x <= startPoint.x && (fr.x + fr.width) >= startPoint.x) if (yd < min_yd || min_yd == 0) min_yd = yd; obstracle = fr; conflictRectangleList.add(obstracle); if (min_yd == 0) // no obstacles // not need bend point if (parallelObs == null) if (newStartPoint.x == endPoint.x) return; else if (newStartPoint.y > parallelObs.y + parallelObs.height) newStartPoint.y -= (newStartPoint.y - parallelObs.y - parallelObs.height) / 2; if (newStartPoint.y > endPoint.y) if (isVertical(endDirection, UP)) newStartPoint.y = endPoint.y; else if (endDirection.equals(UP)) newStartPoint.y = endPoint.y - space; else newStartPoint.y -= (newStartPoint.y - endPoint.y) / 2; else int y = newStartPoint.y - min_yd + space; if (y > newStartPoint.y) y = newStartPoint.y - min_yd / 2; newStartPoint.y = y; if (parallelObs != null) if (newStartPoint.y >= parallelObs.y && newStartPoint.y <= parallelObs.y + parallelObs.height) newStartPoint.y = parallelObs.y - space; if (!newStartPoint.equals(startPoint)) points.addPoint(newStartPoint); // next row point Vector newDirection = LEFT; if (obstracle == null) if (endPoint.x > newStartPoint.x) newDirection = RIGHT; else if (endPoint.x >= obstracle.x) newDirection = RIGHT; processPoints(newStartPoint, newDirection, obstracle); //得到当前连线的斜向方向 private Vector getSlantDirection(Point p) Vector direction = null; //右上方 if(endPoint.x > p.x && endPoint.y < p.y) direction = RIGHT_UP; return direction; //右下方 if(endPoint.x > p.x && endPoint.y > p.y) direction = RIGHT_DOWN; return direction; //左上方 if(endPoint.x < p.x && endPoint.y < p.y) direction = LEFT_UP; return direction; //左下方 if(endPoint.x < p.x && endPoint.y > p.y) direction = LEFT_DOWN; return direction; return direction; // 得到当前线条的方向 protected Vector getDirection(Rectangle r, Point p, Connection conn) // //////////////////////////////////////////////////// // 当前连线上只有两个图元: // // 第一次进来的是 源图元 // // 第二次进来的是目标图元 // // //////////////////////////////////////////////////// rectangleAffirm++; //1:源图元 ; 2:目标图元 Vector direction = LEFT;// 初始化方向 // 如果当前点没有在当前矩形里面,退出 if (!containPoint(r, p)) return null; // 当前连线矩形的四个顶点坐标 Point leftTop = new Point(r.x, r.y), leftBottom = new Point(r.x, (r.y + r.height - 1)), rightTop = new Point((r.x + r.width), r.y), rightBottom = new Point((r.x + r.width), (r.y + r.height - 1)); // 根据图元类别调用判定方向的方法 // *****************************源图元***********************************// //起点坐标跟边角坐标比较 if (rectangleAffirm == 1) // 在上边界的情况 if (p.y == leftTop.y) //起始边 sourceSide = "上"; //方向判定 if (endPoint.y == p.y && p.x < endPoint.x) direction = RIGHT; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "上";// 跟上边界平行 return direction; if (endPoint.y == p.y && p.x > endPoint.x) parallelStartSide = true; // 平行于起始边界 parallelSideSource = "上";// 跟上边界平行 return direction; if (p.x == endPoint.x && endPoint.y > p.y) direction = DOWN; sourceAcrossCenterPoint = true;//源图元起点冲突 return direction; if (p.x == endPoint.x && endPoint.y < p.y) direction = UP; return direction; //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; // 在下边界的情况 if (p.y == rightBottom.y) //设置起始边 sourceSide = "下"; //方向判定 //垂直、水平方向 if (endPoint.x == p.x && endPoint.y < leftTop.y) direction = UP; sourceAcrossCenterPoint = true;//源图元起点冲突 return direction; if (endPoint.x == p.x && endPoint.y > leftBottom.y) direction = DOWN; return direction; if (endPoint.y == p.y && rightBottom.x > p.x) direction = RIGHT; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "下";// 跟下边界平行 return direction; if (endPoint.y == p.y && leftBottom.x < p.x) parallelStartSide = true; // 平行于起始边界 parallelSideSource = "下";// 跟下边界平行 return direction; //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; // 在左边界的情况 if (p.x == leftTop.x) //设置起始边 sourceSide = "左"; //方向判定 //水平、垂直方向情况 if (leftTop.x == endPoint.x && leftTop.y <= p.y) direction = UP; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "左"; return direction; if (leftTop.x == endPoint.x && rightBottom.y >= p.y) direction = DOWN; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "左"; return direction; if (endPoint.y == p.y && endPoint.x < leftTop.x) return direction; if ((endPoint.y-1 == p.y || p.y==endPoint.y) && endPoint.x > rightBottom.x) direction = RIGHT; sourceAcrossCenterPoint = true;//源图元起点冲突 return direction; //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; // 在右边界的情况 if (p.x == rightTop.x) //设置起始边 sourceSide = "右"; //方向判定 //水平、垂直 if (rightTop.x == endPoint.x && rightTop.y <= p.y) direction = UP; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "右"; return direction; if (rightTop.x == endPoint.x && rightBottom.y >= p.y) direction = DOWN; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "右"; return direction; if ((endPoint.y == p.y || endPoint.y+1 == p.y) && endPoint.x < leftTop.x) sourceAcrossCenterPoint = true;//源图元起点冲突 return direction; if (endPoint.y == p.y && endPoint.x > rightBottom.x) direction = RIGHT; return direction; //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; // ********************目标图元*****************************// else if(null == sourceRect || null == targetRect) return null; //源图元、目标图元的中心点 Point sourceCentPoint = new Point(sourceRect.x + sourceRect.width/2,sourceRect.y + sourceRect.height/2); Point targetCentPoint = new Point(targetRect.x + targetRect.width/2,targetRect.y + targetRect.height/2); //在上边界情况 if (p.y == leftTop.y) //设置终点边 targetSide = "上"; //方向判定 //水平、垂直 if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x > sourceCentPoint.x) direction = RIGHT; parallelEndSide = true; // 平行于起始边界 parallelSideTarget = "上";// 跟上边界平行 return direction; if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x < sourceCentPoint.x) parallelEndSide = true; // 平行于边界 parallelSideTarget = "上";// 跟上边界平行 return direction; if (sourceCentPoint.y < targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x) direction = DOWN; return direction; if (sourceCentPoint.y > targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x) direction = UP; targetAcrossCenterPoint = true;//终点图元跟连线冲突 return direction; //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; // 在下边界的情况 if (p.y == rightBottom.y) //设置终点边 targetSide = "下"; //方向判定 //水平、垂直 if (sourceCentPoint.y > targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x) direction = UP; return direction; if (sourceCentPoint.y < targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x) direction = DOWN; targetAcrossCenterPoint = true;//终点图元跟连线冲突 return direction; if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x > sourceCentPoint.x) direction = RIGHT; parallelEndSide = true; // 平行于边界 parallelSideTarget = "下";// 跟下边界平行 return direction; if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x < sourceCentPoint.x) parallelEndSide = true; // 平行于边界 parallelSideTarget = "下";// 跟下边界平行 return direction; //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; // 在左边界的情况 if (p.x == leftTop.x) //设置终点边 targetSide = "左"; //方向判定 //直线方向 if (sourceCentPoint.y > targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x && sourceSide.equals(targetSide)) direction = UP; parallelEndSide = true; // 平行于边界 parallelSideTarget = "左"; return direction; if (sourceCentPoint.y < targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x && sourceSide.equals(targetSide)) direction = DOWN; parallelEndSide = true; // 平行于边界 parallelSideTarget = "左"; return direction; if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x < sourceCentPoint.x && sourceSide.equals(targetSide)) targetAcrossCenterPoint = true;//终点图元跟连线冲突 return direction; if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x > sourceCentPoint.x && sourceSide.equals(targetSide)) direction = RIGHT; return direction; //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; // 在右边界的情况 if (p.x == rightTop.x) //设置终点边 targetSide = "右"; //方向判定 //直线方向 if (sourceCentPoint.y > targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x) direction = UP; parallelEndSide = true; // 平行于边界 parallelSideTarget = "右"; return direction; if (sourceCentPoint.y < targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x ) direction = DOWN; parallelEndSide = true; // 平行于边界 parallelSideTarget = "右"; return direction; if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x < sourceCentPoint.x) return direction; if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x > sourceCentPoint.x) direction = RIGHT; targetAcrossCenterPoint = true;//终点图元跟连线冲突 return direction; //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; return direction; // 得到当前连接线起始方向 protected Vector getStartDirection(Connection conn) ConnectionAnchor anchor = conn.getSourceAnchor();// 获取源连接锚点 Point p = getStartPoint(conn);// 通过连接线获取到起始点坐标 // 如果获取不到源连接锚点,自定义一个矩形图元 if (anchor.getOwner() == null) sourceRect = new Rectangle(p.x - 1, p.y - 1, 2, 2); else sourceRect = conn.getSourceAnchor().getOwner().getBounds().getCopy();// 得到当前矩形 conn.getSourceAnchor().getOwner().translateToAbsolute(sourceRect);// 转换当前矩形 return getDirection(sourceRect, p, conn); // 得到当前连线的结束方向 protected Vector getEndDirection(Connection conn) ConnectionAnchor anchor = conn.getTargetAnchor(); Point p = getEndPoint(conn); if (anchor.getOwner() == null) targetRect = new Rectangle(p.x - 1, p.y - 1, 2, 2); else targetRect = conn.getTargetAnchor().getOwner().getBounds().getCopy(); conn.getTargetAnchor().getOwner().translateToAbsolute(targetRect); return getDirection(targetRect, p, conn); // 起点跟源图元冲突时 private void monitorStartCollide(Point startPoint) if (parallelStartSide) Point bendPoint = null;// 初始化弯曲点 int bendPointSpace = 10;// 初始化点间距 // 上边界 if ("上".equals(parallelSideSource)) bendPoint = new Point(startPoint.x, startPoint.y - bendPointSpace); points.addPoint(bendPoint); return; // 下边界 if ("下".equals(parallelSideSource)) bendPoint = new Point(startPoint.x, startPoint.y + bendPointSpace); points.addPoint(bendPoint); return; // 左边界 if ("左".equals(parallelSideSource)) bendPoint = new Point(startPoint.x - bendPointSpace, startPoint.y); points.addPoint(bendPoint); return; // 右边界 if ("右".equals(parallelSideSource)) bendPoint = new Point(startPoint.x + bendPointSpace, startPoint.y); points.addPoint(bendPoint); return; // 终点连线跟源图元冲突时 private void monitorEndCollide(Point endPoint) if (parallelEndSide) Point bendPoint = null;// 初始化弯曲点 int bendPointSpace = 10;// 初始化点间距 // 上边界 if ("上".equals(parallelSideTarget)) bendPoint = new Point(endPoint.x, endPoint.y - bendPointSpace); points.addPoint(bendPoint); return; // 下边界 if ("下".equals(parallelSideTarget)) bendPoint = new Point(endPoint.x, endPoint.y + bendPointSpace); points.addPoint(bendPoint); return; // 左边界 if ("左".equals(parallelSideTarget)) bendPoint = new Point(endPoint.x - bendPointSpace, endPoint.y); points.addPoint(bendPoint); return; // 右边界 if ("右".equals(parallelSideTarget)) bendPoint = new Point(endPoint.x + bendPointSpace, endPoint.y); points.addPoint(bendPoint); return;
以上是关于仿VISIO连线的主要内容,如果未能解决你的问题,请参考以下文章