📄 arrow.java
字号:
public static final int ARROWTYPE_DIAMOND_CIRCLE_EMPTY =11;
/** An empty diamond and a solid small circle on the end of line. */
public static final int ARROWTYPE_DIAMOND_CIRCLE =12;
/** An arrow type with two reversed inclined lines on the end of line. */
public static final int ARROWTYPE_TRIANGLELINES_REVERSED =13;
/** An arrow type with one vertical line and two reversed inclined lines on the end of line. */
public static final int ARROWTYPE_VLINE_TRIANGLELINES_REVERSED =14;
/** An arrow type with one small circle and two reversed inclined lines on the end of line. */
public static final int ARROWTYPE_CIRCLE_TRIANGLELINES_REVERSED =15;
/** An arrow type with one small circle and one vertical line on the end of line. */
public static final int ARROWTYPE_CIRCLE_EMPTY_VLINE =16;
/** An arrow type with one vertical line on the end of line. */
public static final int ARROWTYPE_VLINE =17;
/** An arrow type with two vertical lines on the end of line. */
public static final int ARROWTYPE_VLINE_VLINE =18;
/** An arrow type with three vertical lines on the end of line. */
public static final int ARROWTYPE_VLINE_VLINE_VLINE =19;
/** An arrow type with one vertical line and one small empty circle on the end of line. */
public static final int ARROWTYPE_VLINE_CIRCLE_EMPTY =20;
/** An arrow type with two vertical lines and one small empty circle on the end of line. */
public static final int ARROWTYPE_VLINE_VLINE_CIRCLE_EMPTY =21;
/** An arrow type with three vertical lines and one small empty circle on the end of line. */
public static final int ARROWTYPE_VLINE_VLINE_VLINE_CIRCLE_EMPTY=22;
/** An arrow type with one vertical line and one small solid circle on the end of line. */
public static final int ARROWTYPE_VLINE_CIRCLE =23;
/** An arrow type with two vertical lines and one small solid circle on the end of line. */
public static final int ARROWTYPE_VLINE_VLINE_CIRCLE =24;
/** An arrow type with three vertical lines and one small solid circle on the end of line. */
public static final int ARROWTYPE_VLINE_VLINE_VLINE_CIRCLE =25;
/** A two solid triangles on the end of line. */
public static final int ARROWTYPE_TRIANGLE_TRIANGLE =26;
/** An two empty triangles on the end of line. */
public static final int ARROWTYPE_TRIANGLE_TRIANGLE_EMPTY =27;
/** An arrow type with 2 x 2 inclined lines constructed an arrow. */
public static final int ARROWTYPE_TRIANGLELINES_TRIANGLELINES =28;
/** An arrow type with one vertical line and two inclined lines constructed an arrow. */
public static final int ARROWTYPE_VLINE_TRIANGLELINES =29;
/** An arrow type with one vertical line and 2 x 2 inclined lines constructed an arrow. */
public static final int ARROWTYPE_VLINE_TRIANGLELINES_TRIANGLELINES =30;
/** An minimum arrow size */
public static final int ARROWSIZE =5;
/** Get an arrow occupied size on one end of line.
* @param arrowType The type of the arrow to be drawn.
* @param lineWidth The line width, it will effect the shape of arrow.
*/
public static double getArrowOccupiedSize(int arrowType, int lineWidth){
if (arrowType==ARROWTYPE_NONE)
return 0;
//to consider the line width will effect the arrowsize:
int arrowSize =Math.max(ARROWSIZE,lineWidth * 2);
switch (arrowType){
case ARROWTYPE_TRIANGLE:
return arrowSize * 2;
case ARROWTYPE_TRIANGLE_EMPTY:
return arrowSize * 2 + lineWidth;
case ARROWTYPE_TRIANGLE_TRIANGLE:
return arrowSize * 4;
case ARROWTYPE_TRIANGLE_TRIANGLE_EMPTY:
return arrowSize * 4 + lineWidth;
}
return 0;
}
/** arrow type of this arrow
* @param arrowType The type of the arrow to be drawn.
* @param lineWidth The line width, it will effect the shape of arrow.
* @param startPoint The start point of the line.
* @param endPoint The end point of the line. The arrow will be drawn on this end side.
* @param g The graphics context to draw arrow.
*/
public static void drawArrow(int arrowType, int lineWidth,JFPoint startPoint, JFPoint endPoint,Graphics g, Color c){
if (arrowType==ARROWTYPE_NONE || lineWidth<=0)
return;
Graphics2D g2 =(Graphics2D)g;
Stroke s =new BasicStroke(lineWidth,
BasicStroke.CAP_SQUARE,
BasicStroke.JOIN_MITER);
g2.setStroke(s);
//to consider the line width will effect the arrowsize:
int arrowSize =Math.max(ARROWSIZE,lineWidth * 2);
int radius =(int)Math.max(ARROWSIZE,lineWidth * 2);
int offset =0;
JFPoint newEnd=endPoint;
switch (arrowType){
case ARROWTYPE_TRIANGLE:
case ARROWTYPE_TRIANGLE_EMPTY:
if (arrowType==ARROWTYPE_TRIANGLE_EMPTY)
newEnd =newEnd.nearPoint(startPoint,lineWidth);
drawTriangle((arrowType==ARROWTYPE_TRIANGLE_EMPTY),arrowSize,startPoint,newEnd,g,c);
break;
case ARROWTYPE_TRIANGLE_TRIANGLE:
case ARROWTYPE_TRIANGLE_TRIANGLE_EMPTY:
//first triangle
if (arrowType==ARROWTYPE_TRIANGLE_TRIANGLE_EMPTY)
newEnd =newEnd.nearPoint(startPoint,lineWidth);
drawTriangle((arrowType==ARROWTYPE_TRIANGLE_TRIANGLE_EMPTY),arrowSize,startPoint,newEnd,g,c);
//second triangle
if (arrowType==ARROWTYPE_TRIANGLE_TRIANGLE_EMPTY)
newEnd =newEnd.nearPoint(startPoint,lineWidth);
newEnd =newEnd.nearPoint(startPoint,arrowSize * 2);
drawTriangle((arrowType==ARROWTYPE_TRIANGLE_TRIANGLE_EMPTY),arrowSize,startPoint,newEnd,g,c);
break;
case ARROWTYPE_TRIANGLELINES:
case ARROWTYPE_TRIANGLELINES_TRIANGLELINES:
case ARROWTYPE_VLINE_TRIANGLELINES:
case ARROWTYPE_VLINE_TRIANGLELINES_TRIANGLELINES:
//first triangle
newEnd =newEnd.nearPoint(startPoint,lineWidth);
drawTriangleLine(false,arrowSize,startPoint,newEnd,g,c);
//second triangle
newEnd =newEnd.nearPoint(startPoint,arrowSize * 2);
if (arrowType==ARROWTYPE_TRIANGLELINES_TRIANGLELINES || arrowType==ARROWTYPE_VLINE_TRIANGLELINES_TRIANGLELINES){
drawTriangleLine(false,arrowSize,startPoint,newEnd,g,c);
}
//first upright line.
if (arrowType==ARROWTYPE_VLINE_TRIANGLELINES || arrowType==ARROWTYPE_VLINE_TRIANGLELINES_TRIANGLELINES){
if (arrowType==ARROWTYPE_VLINE_TRIANGLELINES_TRIANGLELINES)
newEnd =newEnd.nearPoint(startPoint,arrowSize * 2.5);
else
newEnd =newEnd.nearPoint(startPoint,arrowSize * 0.5);
drawVLine(lineWidth,lineWidth,startPoint,newEnd,g,c);
}
break;
case ARROWTYPE_TRIANGLELINES_REVERSED:
case ARROWTYPE_VLINE_TRIANGLELINES_REVERSED:
case ARROWTYPE_CIRCLE_TRIANGLELINES_REVERSED:
//first triangle
newEnd =newEnd.nearPoint(startPoint,lineWidth);
drawTriangleLine(true,arrowSize,startPoint,newEnd,g,c);
newEnd =newEnd.nearPoint(startPoint,arrowSize * 2);
if (arrowType==ARROWTYPE_VLINE_TRIANGLELINES_REVERSED)
drawVLine(lineWidth,lineWidth * 2,startPoint,newEnd,g,c);
else if (arrowType==ARROWTYPE_CIRCLE_TRIANGLELINES_REVERSED)
drawCircle(true,lineWidth,startPoint,newEnd,g,c);
break;
case ARROWTYPE_LINE_INCLINED:
drawInclinedLine(false,lineWidth,startPoint,newEnd,g,c);
break;
case ARROWTYPE_LINE_INCLINED_INTERSECT:
newEnd =newEnd.nearPoint(startPoint,arrowSize + lineWidth * 2);
drawInclinedLine(true,lineWidth,startPoint,newEnd,g,c);
break;
case ARROWTYPE_CIRCLE:
case ARROWTYPE_VLINE_CIRCLE:
case ARROWTYPE_VLINE_VLINE_CIRCLE:
case ARROWTYPE_VLINE_VLINE_VLINE_CIRCLE:
case ARROWTYPE_CIRCLE_EMPTY:
case ARROWTYPE_VLINE_CIRCLE_EMPTY:
case ARROWTYPE_VLINE_VLINE_CIRCLE_EMPTY:
case ARROWTYPE_VLINE_VLINE_VLINE_CIRCLE_EMPTY:
switch (arrowType){
case ARROWTYPE_CIRCLE_EMPTY:
case ARROWTYPE_VLINE_CIRCLE_EMPTY:
case ARROWTYPE_VLINE_VLINE_CIRCLE_EMPTY:
case ARROWTYPE_VLINE_VLINE_VLINE_CIRCLE_EMPTY:
//circle.
drawCircle(true,lineWidth,startPoint,newEnd,g,c);
break;
case ARROWTYPE_CIRCLE:
case ARROWTYPE_VLINE_CIRCLE:
case ARROWTYPE_VLINE_VLINE_CIRCLE:
case ARROWTYPE_VLINE_VLINE_VLINE_CIRCLE:
//circle.
drawCircle(false,lineWidth,startPoint,newEnd,g,c);
break;
}
if (arrowType==ARROWTYPE_CIRCLE || arrowType==ARROWTYPE_CIRCLE_EMPTY)
break;
//first upright line.
offset =(int)Math.max(ARROWSIZE,lineWidth*2);
newEnd =newEnd.nearPoint(startPoint,radius*2 + lineWidth);
drawVLine(lineWidth,offset,startPoint,newEnd,g,c);
if (arrowType==ARROWTYPE_VLINE_CIRCLE || arrowType==ARROWTYPE_VLINE_CIRCLE_EMPTY)
break;
//second upright line.
newEnd =newEnd.nearPoint(startPoint,offset);
drawVLine(lineWidth,offset,startPoint,newEnd,g,c);
if (arrowType==ARROWTYPE_VLINE_VLINE_CIRCLE || arrowType==ARROWTYPE_VLINE_VLINE_CIRCLE_EMPTY)
break;
//second upright line.
newEnd =newEnd.nearPoint(startPoint,offset);
drawVLine(lineWidth,offset,startPoint,newEnd,g,c);
break;
case ARROWTYPE_CIRCLE_EMPTY_VLINE:
case ARROWTYPE_VLINE:
case ARROWTYPE_VLINE_VLINE:
case ARROWTYPE_VLINE_VLINE_VLINE:
offset =(int)Math.max(ARROWSIZE,lineWidth*2);
//first upright line.
drawVLine(lineWidth,offset,startPoint,newEnd,g,c);
if (arrowType==ARROWTYPE_VLINE)
break;
//second upright line or first circle.
newEnd =newEnd.nearPoint(startPoint,offset);
if (arrowType==ARROWTYPE_CIRCLE_EMPTY_VLINE){
newEnd =newEnd.nearPoint(startPoint,offset);
//circle.
drawCircle(true,lineWidth,startPoint,newEnd,g,c);
break;
}
drawVLine(lineWidth,offset,startPoint,newEnd,g,c);
if (arrowType==ARROWTYPE_VLINE_VLINE)
break;
//third upright line or first circle.
newEnd =newEnd.nearPoint(startPoint,offset);
drawVLine(lineWidth,offset,startPoint,newEnd,g,c);
break;
case ARROWTYPE_RECTANGLE_EMPTY:
newEnd =newEnd.nearPoint(startPoint,lineWidth);
drawRectangle(true,lineWidth,startPoint,newEnd,g,c);
break;
case ARROWTYPE_RECTANGLE:
drawRectangle(false,lineWidth,startPoint,newEnd,g,c);
break;
case ARROWTYPE_DIAMOND_EMPTY:
newEnd =newEnd.nearPoint(startPoint,lineWidth);
drawDiamond(true,arrowSize,startPoint,newEnd,g,c);
break;
case ARROWTYPE_DIAMOND_CIRCLE_EMPTY:
case ARROWTYPE_DIAMOND_CIRCLE:
if (arrowType==ARROWTYPE_DIAMOND_CIRCLE_EMPTY)
drawCircle(true,lineWidth,startPoint,newEnd,g,c);
else
drawCircle(false,lineWidth,startPoint,newEnd,g,c);
newEnd =newEnd.nearPoint(startPoint,radius *2 + lineWidth*2);
drawDiamond(true,arrowSize,startPoint,newEnd,g,c);
break;
}
}
/** get the slope of the upright line of this line.
* @param startPoint The start point of the line.
* @param endPoint The end point of the line. The arrow will be drawn on this end side.
* @return the upright line slope.
*/
private static double getUprightLineSlope(JFPoint startPoint, JFPoint endPoint){
//slope of the line from start point to end point.
double slope =startPoint.getSlope(endPoint);
//slope of the vertical line of the line above.
double vSlope =0;
if (slope==0)
vSlope =GeomConst.LARGE_VALUE;
else if (slope==GeomConst.LARGE_VALUE)
vSlope =0;
else
vSlope =-1/slope;
return vSlope;
}
/** draw triangle arrows.
* @param empty If is an empty or solid triangle, true if empty, false solid.
* @param arrowSize A reference arrow size.
* @param startPoint The start point of the line.
* @param endPoint The end point of the line. The arrow will be drawn on this end side.
* @param g The graphics context to draw arrow.
* @param c The color of current arrow.
*/
private static void drawTriangle(boolean empty, int arrowSize,JFPoint startPoint, JFPoint endPoint,Graphics g, Color c){
if (startPoint==null || endPoint==null)
return;
//slope of the vertical line of the line above.
double slope =getUprightLineSlope(startPoint,endPoint);
JFPoint end1, end2, end3,interPoint;
end1 =endPoint;
//the point that vertical side of triangle intersects the line
interPoint =end1.nearPoint(startPoint,arrowSize*2);
//the two point on the vertical line across the interpoint.
end2 =interPoint.nearPoint(slope,arrowSize,startPoint,true);
end3 =interPoint.nearPoint(slope,arrowSize,startPoint,false);
//draw first triangle.
GeneralPath path= new GeneralPath(GeneralPath.WIND_EVEN_ODD);
path.moveTo((float)end1.getX(), (float)end1.getY());
path.lineTo((float)end2.getX(), (float)end2.getY());
path.lineTo((float)end3.getX(), (float)end3.getY());
path.closePath();
Graphics2D g2 =(Graphics2D)g;
if (empty){
//clear firstly
g2.setColor(Color.white);
g2.fill(path);
//draw arrow
g2.setColor(c);
g2.draw(path);
}else{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -