connectionfigure.java

来自「mywork是rcp开发的很好的例子」· Java 代码 · 共 140 行

JAVA
140
字号
package net.sf.freenote.figure;

import java.util.HashMap;
import java.util.Map;

import net.sf.freenote.directedit.DirectEditable;
import net.sf.util.StringUtil;

import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.ConnectionLocator;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.MidpointLocator;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.PolylineDecoration;
import org.eclipse.draw2d.RotatableDecoration;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.swt.widgets.Text;

/**
 * 带label的connection
 * 约定:描述中含 1..n 则将其分配到源端和目标端
 * @author levin
 * @since 2008-1-26 下午02:55:44
 */
public class ConnectionFigure extends PolylineConnection implements DirectEditable{
	private Label[] descLabels;	//三个label,起、中、止
	//保持常数与修饰之间的对应
	private static Map<Integer,Class<? extends RotatableDecoration>> decorations=new HashMap<Integer,Class<? extends RotatableDecoration>>();
	static{
		decorations.put(1,PolygonDecoration.class);
		decorations.put(2,PolylineDecoration.class);
		decorations.put(3,DiamondPolygonDecoration.class);
		decorations.put(4,TrianglePolygonDecoration.class);
	}
	public ConnectionFigure() {
		super();
		descLabels=new Label[3];
		ConnectionLocator[] locators=new ConnectionLocator[]{
				new EndPointLocator(this,ConnectionLocator.SOURCE),
				new MidpointLocator(this,0),
				new EndPointLocator(this,ConnectionLocator.TARGET)
		};
		for(int i=0;i<descLabels.length;i++){
			descLabels[i] = new Label();
			descLabels[i].setOpaque(true);
			add(descLabels[i], locators[i]);
		}
	}

	public void setDesc(String text){
		String[] ss = splitDesc(text);
		for(int i=0;i<descLabels.length;i++)
			descLabels[i].setText(ss[i]);
	}
	
	//拆串,会扔掉1..n之后的换行
	private static String[] splitDesc(String text) {
		String[] ss=new String[3];
		//解析字串,判断是否有..
		int delim=text.indexOf("..");
		if(delim > 0){
			int start=text.lastIndexOf(Text.DELIMITER, delim) >0 ?text.lastIndexOf(Text.DELIMITER, delim)+Text.DELIMITER.length():0;
			int end=text.indexOf(Text.DELIMITER,delim) > delim ? text.indexOf(Text.DELIMITER,delim) : text.length();
			ss[0]=text.substring(start,delim);
			ss[2]=text.substring(delim+2,end);
			if(start > 0)
				ss[1]=text.substring(0,start-Text.DELIMITER.length());
			else if(end <text.length())
				ss[1]=text.substring(end+Text.DELIMITER.length());
			else
				ss[1]="";
		}else{
			ss[0]="";
			ss[1]=text;
			ss[2]="";
		}
		return ss;
	}
	public String getDesc(){
		if(StringUtil.isNotNull(descLabels[0].getText()))
			return descLabels[1].getText()+Text.DELIMITER+descLabels[0].getText()+".."+descLabels[2].getText();
		else
			return descLabels[1].getText();
	}

	public Label getDescLabel() {
		return descLabels[1];
	}
	
	public void setSourceDecoration(Integer index){
		try {
			setSourceDecoration(decorations.get(index).newInstance());
		} catch(NullPointerException npe) {
			setSourceDecoration((RotatableDecoration)null);
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	public void setTargetDecoration(Integer index){
		try {
			setTargetDecoration(decorations.get(index).newInstance());
		} catch(NullPointerException npe) {
			setTargetDecoration((RotatableDecoration)null);
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	//端点定位,距端点距离为12的点,上方为10,算法还可以进一步优化
	class EndPointLocator extends ConnectionLocator{
		private final double distance=12,gap=10;
		public EndPointLocator(Connection connection, int align) {
			super(connection, align);
		}
		protected Point getLocation(PointList points) {
			Point p=new Point(),p1=points.getFirstPoint(),p2=points.getLastPoint();
			//求总长
			double dy = p2.y-p1.y;
			double dx = p2.x-p1.x;
			double length=Math.sqrt(dy*dy+dx*dx);
			//两图太近,直接取源点了
			if(length < distance) return p1;
			if(getAlignment() == SOURCE){
				p.x=p1.x+(int)(dx*distance/length);
				p.y=p1.y+(int)(dy*distance/length);
			}else if(getAlignment() == TARGET){
				p.x=p2.x-(int)(dx*distance/length);
				p.y=p2.y-(int)(dy*distance/length);
			}
			//调整gap,需要一个针对矩形(类图)的算法
			if(dy/dx > 3 || dy/dx < - 1)
				p.x += gap;
			else
				p.y -= gap;
			return p;
		}
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?