📄 relation.java
字号:
package cn.myapps.core.workflow.element;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.geom.Area;
import java.util.Vector;
public class Relation extends PaintElement {
// System
public String state;
public String startnodeid;
public String endnodeid;
public boolean ispassed;
public boolean isreturn; // 是否是返回路径
public String condition = null;
public String action = null;
public String pointstack;
static final int ARROW_LONG = 14;
static final int ARROW_WIDTH = 4;
static final double PAI = 3.1415926525;
private Point _startpoint;
private Point _endpoint;
private Node _startnode;
private Node _endnode;
private Point _mousepoint;
private Point _movepoint = null; // 拖拉时鼠标的移动点
private Point breakpoint = null; // 按下鼠标时的点
protected Rectangle _txtrect;
private Vector vector = null;
private int changevector = -1; // 当鼠标按下时恰好是流程线原有折点时的折点位置
private boolean currentselect = false;
private boolean initstart = false; // 由于该流程图用xml文件保存,所以当装载流程图时要构造保存流程线的折点位置的vector
public String validateScript = null;
/**
* @param owner
* @roseuid 3E0428DB027D
*/
public Relation(FlowDiagram owner) {
super(owner);
vector = new Vector();
this.initstart = true;
}
public void paint(Graphics g) {
Color old = this.color; // 保存当前颜色
Point sp = this.getStartPoint();
Point ep = this.getEndPoint();
if (this.initstart) { // 如果流程图是第一次画,则要从原有xml文件中读取折点的坐标
this.initVector(this.pointstack); // pointstack是与xml文件打交道的用于存储流程线的折点坐标的public
// String型变量
}
this.initstart = false;
if (sp != null && ep != null) {
if (this.vector.size() >= 3) {
while (true) { // 把相邻的两个距离小于10的折点合并为一个点
if (this.vector.size() >= 3) {
int d = -1;
int m = 0;
int size = this.vector.size() - 1;
for (m = 0; m < size; m++) {
Point obj1 = (Point) this.vector.elementAt(m);
Point obj2 = (Point) this.vector.elementAt(m + 1);
if (m == 0) {
obj1 = this.getStartPoint();
}
if (m == this.vector.size() - 2) {
obj2 = this.getEndPoint();
}
d = this.getDistance(obj1, obj2);
if (d <= 10) { // 若两点相邻且距离小于10,则删去其中一个点
if (m == this.vector.size() - 2) {
this.vector.removeElementAt(m);
} else {
this.vector.removeElementAt(m + 1);
}
break;
}
}
if (m == size) {
break;
}
} else {
break;
}
}
while (true) { // 把相邻的两条夹角小于5度的直线合并为一条直线
if (this.vector.size() >= 3) {
boolean remove = false;
int n = 0;
int size = this.vector.size() - 2;
for (n = 0; n < size; n++) {
Point obj1 = (Point) this.vector.elementAt(n);
Point obj2 = (Point) this.vector.elementAt(n + 1);
Point obj3 = (Point) this.vector.elementAt(n + 2);
if (n == 0) {
obj1 = this.getStartPoint();
}
if (n == this.vector.size() - 3) {
obj3 = this.getEndPoint();
}
remove = this.lineTolineAngle(obj1, obj2, obj3); // 判断两线夹角是否小于5度
if (remove) {
this.vector.removeElementAt(n + 1);
break;
}
}
if (n == size) {
break;
}
} else {
break;
}
}
}
int i = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0, d2 = 0, h2 = 0;
int mx = 0, my = 0;
int hx = 0, hy = 0, ex1 = 0, ey1 = 0, ex2 = 0, ey2 = 0;
double k1 = 0, k2 = 0;
double sina = 0, cosa = 0;
double sinb = 0, cosb = 0;
double tx = 0, ty = 0;
boolean moveline = false;
x1 = ep.x;
y1 = ep.y;
x2 = sp.x;
y2 = sp.y;
if (this.ispassed) {
g.setColor(color.green);
} else if (this.currentselect) {
this.color = this.DEF_SELECTEDCOLOR;
g.setColor(this.color);
this.currentselect = false;
} else {
this.color = this.DEF_COLOR;
g.setColor(this.color);
}
if (this.vector.size() < 2) {
d2 = 0;
h2 = 0;
} else {
Node node = (Node) this.getEndnode();
d2 = node._imgrect.width;
h2 = node._imgrect.height;
}
Point arrowhead = null;
arrowhead = this.getArrowhead(new Point(x2, y2), new Point(x1, y1),
d2, h2); // 得到流程线箭头的坐标
if (this.vector.size() < 3) { // 鼠标从开始结点拖拉到结尾结点的过程中,鼠标当前移动点作为暂时的尾结点
if (this._movepoint != null) {
g.drawLine(x2, y2, this._movepoint.x, this._movepoint.y);
x2 = this._movepoint.x;
y2 = this._movepoint.y;
arrowhead = this.getArrowhead(new Point(x2, y2), new Point(
x1, y1), d2, h2);
g.drawLine(this._movepoint.x, this._movepoint.y,
arrowhead.x, arrowhead.y);
this._movepoint = null;
} else {
g.drawLine(x2, y2, arrowhead.x, arrowhead.y);
}
} else {
if (this._movepoint != null) { // 画流程线折点时拖拉鼠标的情况
int whichLine = this.getWhichLine(this.getBreakpoint());
for (int j = 0; j < this.vector.size() - 1; j++) {
Point obj1 = (Point) this.vector.elementAt(j);
Point obj2 = (Point) this.vector.elementAt(j + 1);
x2 = obj1.x;
y2 = obj1.y;
if (j == 0) {
obj1 = this.getStartPoint();
}
if (j == this.vector.size() - 2) {
arrowhead = this.getArrowhead(new Point(x2, y2),
new Point(x1, y1), d2, h2);
obj2 = arrowhead;
}
if (j == whichLine) {
g.drawLine(obj1.x, obj1.y, this._movepoint.x,
this._movepoint.y);
x2 = this._movepoint.x;
y2 = this._movepoint.y;
if (j == this.vector.size() - 2) {
arrowhead = this.getArrowhead(
new Point(x2, y2), new Point(x1, y1),
d2, h2);
obj2 = arrowhead;
}
g.drawLine(this._movepoint.x, this._movepoint.y,
obj2.x, obj2.y);
} else {
g.drawLine(obj1.x, obj1.y, obj2.x, obj2.y);
}
}
this._movepoint = null;
} else { // 鼠标释放点设为新折点
for (int k = 0; k < this.vector.size() - 1; k++) {
Point obj3 = (Point) this.vector.elementAt(k);
Point obj4 = (Point) this.vector.elementAt(k + 1);
x2 = obj3.x;
y2 = obj3.y;
if (k == 0) {
obj3 = this.getStartPoint();
}
if (k == this.vector.size() - 2) {
arrowhead = this.getArrowhead(new Point(x2, y2),
new Point(x1, y1), d2, h2);
obj4 = arrowhead;
}
g.drawLine(obj3.x, obj3.y, obj4.x, obj4.y);
}
}
}
mx = (x2 + x1) / 2;
my = (y2 + y1) / 2;
arrowhead = this.getArrowhead(new Point(x2, y2), new Point(x1, y1),
d2, h2);
sina = Math.abs((double) Math.sqrt((y2 - y1) * (y2 - y1))
/ Math
.sqrt(((x2 - x1) * (x2 - x1) + (y2 - y1)
* (y2 - y1))));
cosa = Math.abs((double) Math.sqrt((x2 - x1) * (x2 - x1))
/ Math
.sqrt(((x2 - x1) * (x2 - x1) + (y2 - y1)
* (y2 - y1))));
System.out.println("sina->"+sina + " cosa->"+cosa);
// 第一象限
Point arrowstart1 = new Point();
Point arrowstart2 = new Point();
if (x2 < arrowhead.x && y2 < arrowhead.y) { // 求箭头线的开始点,有两个,分别在流程线的两侧
arrowstart1.x = arrowhead.x
+ (int) (ARROW_WIDTH * sina - ARROW_LONG * cosa);
arrowstart1.y = arrowhead.y
- (int) (ARROW_LONG * sina + ARROW_WIDTH * cosa);
arrowstart2.x = arrowhead.x
- (int) (ARROW_LONG * cosa + ARROW_WIDTH * sina);
arrowstart2.y = arrowhead.y
+ (int) (ARROW_WIDTH * cosa - ARROW_LONG * sina);
} else if (x2 == arrowhead.x && y2 < arrowhead.y) {
arrowstart1.x = arrowhead.x + ARROW_WIDTH;
arrowstart1.y = arrowhead.y - ARROW_LONG;
arrowstart2.x = arrowhead.x - ARROW_WIDTH;
arrowstart2.y = arrowhead.y - ARROW_LONG;
} else if (x2 > arrowhead.x && y2 < arrowhead.y) {
arrowstart1.x = arrowhead.x
+ (int) (ARROW_LONG * cosa + ARROW_WIDTH * sina);
arrowstart1.y = arrowhead.y
+ (int) (ARROW_WIDTH * cosa - ARROW_LONG * sina);
arrowstart2.x = arrowhead.x
+ (int) (ARROW_LONG * cosa - ARROW_WIDTH * sina);
arrowstart2.y = arrowhead.y
- (int) (ARROW_LONG * sina + ARROW_WIDTH * cosa);
} else if (x2 > arrowhead.x && y2 == arrowhead.y) {
arrowstart1.x = arrowhead.x + ARROW_LONG;
arrowstart1.y = arrowhead.y + ARROW_WIDTH;
arrowstart2.x = arrowhead.x + ARROW_LONG;
arrowstart2.y = arrowhead.y - ARROW_WIDTH;
} else if (x2 > arrowhead.x && y2 > arrowhead.y) {
arrowstart1.x = arrowhead.x
+ (int) (ARROW_LONG * cosa - ARROW_WIDTH * sina);
arrowstart1.y = arrowhead.y
+ (int) (ARROW_LONG * sina + ARROW_WIDTH * cosa);
arrowstart2.x = arrowhead.x
+ (int) (ARROW_LONG * cosa + ARROW_WIDTH * sina);
arrowstart2.y = arrowhead.y
+ (int) (ARROW_LONG * sina - ARROW_WIDTH * cosa);
} else if (x2 == arrowhead.x && y2 > arrowhead.y) {
arrowstart1.x = arrowhead.x - ARROW_WIDTH;
arrowstart1.y = arrowhead.y + ARROW_LONG;
arrowstart2.x = arrowhead.x + ARROW_WIDTH;
arrowstart2.y = arrowhead.y + ARROW_LONG;
} else if (x2 < arrowhead.x && y2 > arrowhead.y) {
arrowstart1.x = arrowhead.x
- (int) (ARROW_LONG * cosa + ARROW_WIDTH * sina);
arrowstart1.y = arrowhead.y
+ (int) (ARROW_LONG * sina - ARROW_WIDTH * cosa);
arrowstart2.x = arrowhead.x
+ (int) (ARROW_WIDTH * sina - ARROW_LONG * cosa);
arrowstart2.y = arrowhead.y
+ (int) (ARROW_LONG * sina + ARROW_WIDTH * cosa);
} else {
arrowstart1.x = arrowhead.x - ARROW_LONG;
arrowstart1.y = arrowhead.y - ARROW_WIDTH;
arrowstart2.x = arrowhead.x - ARROW_LONG;
arrowstart2.y = arrowhead.y + ARROW_WIDTH;
}
hx = arrowhead.x;
hy = arrowhead.y;
// g.setColor(Color.red);
Polygon arrow = new Polygon();
arrow.addPoint(hx, hy);
arrow.addPoint(arrowstart1.x, arrowstart1.y);
arrow.addPoint(arrowstart2.x, arrowstart2.y);
// g.drawLine(arrowstart1.x, arrowstart1.y, hx, hy);
// g.drawLine(arrowstart2.x, arrowstart2.y, hx, hy);
g.fillPolygon(arrow);
g.setColor(Color.black);
if (this.name != null) {
java.awt.FontMetrics fm = _owner.getFontMetrics(font);
int rx = mx - 10;
int ry = my + fm.getHeight(); // 比线段中间位低
g.setColor(Color.blue);
g.drawString(name, rx, ry);
g.setColor(Color.black);
}
}
this.color = old; // 恢复当前颜色
this.setPointStack(this.vector); // 把vector里的折点坐标存储在pointstack里,跟xml文件打交道
}
/**
* Access method for the Startnode property.
*
* @return the current value of the Startnode property
* @roseuid 3E0A6E1B0318
*/
public int getChangevector() {
return this.changevector;
}
public void setChangevector(int change) {
this.changevector = change;
}
public void setPointStack(Vector vector) {
String strTemp = "";
if (this.vector != null) {
for (int i = 0; i < this.vector.size(); i++) {
Point point = (Point) this.vector.elementAt(i);
strTemp = strTemp + point.x + ";" + point.y;
if (i < this.vector.size() - 1) {
strTemp = strTemp + ";"; // 例如: "123;234;456;444"形式
}
}
}
this.pointstack = strTemp;
}
public void initVector(String pointstack) { // 把pointstack里的x,y坐标转换成vector里的Point对象
String str = new String();
str = pointstack;
int length = 0;
if (str == null || str.equalsIgnoreCase("")) {
} else {
int x = 0;
int y = 0;
int position = 0;
length = str.length();
String strTemp = "";
while (true) {
try {
position = str.indexOf(";");
if (position <= 0) {
break;
}
strTemp = str.substring(0, position);
x = Integer.parseInt(strTemp);
str = str.substring(position + 1, str.length());
position = str.indexOf(";");
if (position <= 0) {
strTemp = str;
y = Integer.parseInt(strTemp);
this.vector.addElement(new Point(x, y));
break;
}
strTemp = str.substring(0, position);
y = Integer.parseInt(strTemp);
this.vector.addElement(new Point(x, y));
str = str.substring(position + 1, str.length());
} catch (Exception e) {
}
}
}
}
public void setCurrentselect(boolean curSelect) {
this.currentselect = curSelect;
}
public boolean getCurrentselect() {
return this.currentselect;
}
public Point getBreakpoint() {
return this.breakpoint;
}
public void setBreakpoint(Point point) {
this.breakpoint = point;
}
public Point getArrowhead(Point p1, Point p2, int d2, int h2) { // 得到箭头坐标
double k = Math.abs((double) (p2.y - p1.y) / (p2.x - p1.x));
double k2 = (double) h2 / d2;
Point arrowhead = new Point();
if (p2.y > p1.y && p2.x > p1.x) {
if (k2 >= k) {
arrowhead.x = p2.x - (int) d2 / 2;
arrowhead.y = p2.y - (int) (k * d2 / 2);
} else {
arrowhead.x = p2.x - (int) (h2 / 2 / k);
arrowhead.y = p2.y - (int) h2 / 2;
}
} else if (p2.y == p1.y && p2.x > p1.x) {
arrowhead.x = p2.x - (int) d2 / 2;
arrowhead.y = p2.y;
} else if (p2.y < p1.y && p2.x > p1.x) {
if (k2 >= k) {
arrowhead.x = p2.x - (int) (h2 / 2);
arrowhead.y = p2.y + (int) (d2 / 2 * k);
} else {
arrowhead.x = p2.x - (int) (h2 / 2 / k);
arrowhead.y = p2.y + (int) h2 / 2;
}
} else if (p2.y < p1.y && p2.x == p1.x) {
arrowhead.x = p2.x;
arrowhead.y = p2.y + (int) h2 / 2;
} else if (p2.y < p1.y && p2.x < p1.x) {
if (k2 >= k) {
arrowhead.x = p2.x + (int) d2 / 2;
arrowhead.y = p2.y + (int) (k * d2 / 2);
} else {
arrowhead.x = p2.x + (int) (h2 / 2 / k);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -