jfcurve.java
来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,212 行 · 第 1/3 页
JAVA
1,212 行
*
* @return A node of current shape.
*
*/
public Node nodeIntersects(JFPoint pnt,int usage){
Node node=super.nodeIntersects(pnt,usage);
//when under rotation sitation, the rotate node must be start or end node.
if (node!=null && usage==Node.NODEUSAGE_ROTATE){
try{
Node startNode =(Node)m_nodeList.getByIndex(0);
Node endNode =(Node)m_nodeList.getByIndex(3);
if (!node.equals(startNode) && !node.equals(endNode)){
return null;
}
}catch(Exception e){
return null;
}
}
return node;
}
/**
* Draw current object's arrows.
*/
protected void drawArrow(Graphics g){
double zoom =getZoomScale();
int lineWidth =m_lineFormat.getLineWidth();
Color c =m_lineFormat.getLineColor();
int startArrow =m_arrow.getStartArrow();
int endArrow =m_arrow.getEndArrow();
JFPoint startPoint =m_curve.getStartPoint();
JFPoint controlPoint1 =m_curve.getControlPoint1();
JFPoint controlPoint2 =m_curve.getControlPoint2();
JFPoint endPoint =m_curve.getEndPoint();
startPoint =new JFPoint(startPoint.getX() * zoom, startPoint.getY() * zoom);
controlPoint1 =new JFPoint(controlPoint1.getX() * zoom, controlPoint1.getY() * zoom);
controlPoint2 =new JFPoint(controlPoint2.getX() * zoom, controlPoint2.getY() * zoom);
endPoint =new JFPoint(endPoint.getX() * zoom, endPoint.getY() * zoom);
Arrow.drawArrow(startArrow,lineWidth,controlPoint1,startPoint,g,c);
Arrow.drawArrow(endArrow,lineWidth,controlPoint2,endPoint,g,c);
}
/**
* Draw current object on graphic canvas.
*
* @param g A graphic canvas.
* @param isXorMode If is in xor mode now.
*
*/
public void draw(Graphics g,boolean isXorMode){
if (g==null)
return;
//if user hide this shape, we'll draw an 'invisible' bounds here.
if (isInvisible()){
drawInvisibleBounds(g,isXorMode);
return;
}
if (!isXorMode)
setTransparencyComposite(g);
double zoom =getZoomScale();
Graphics2D g2 =(Graphics2D)g;
g2.setColor(m_lineFormat.getLineColor());
int x1 = (int)(m_curve.getX1() * zoom);
int y1 = (int)(m_curve.getY1() * zoom);
int x2 = (int)(m_curve.getX2() * zoom);
int y2 = (int)(m_curve.getY2() * zoom);
int x3 = (int)(m_curve.getX3() * zoom);
int y3 = (int)(m_curve.getY3() * zoom);
int x4 = (int)(m_curve.getX4() * zoom);
int y4 = (int)(m_curve.getY4() * zoom);
GeneralPath curve= new GeneralPath(GeneralPath.WIND_EVEN_ODD);
curve.moveTo(x1,y1);
curve.curveTo(x2,y2,x3,y3,x4,y4);
if (!isXorMode){
//m_lineFormat.setGraphics(g);
m_lineFormat.draw(g2,curve);
}else{
g2.setStroke(new BasicStroke(1));
g2.setColor(Color.black);
g2.draw(curve);
}
//set the default graphics stroke and color.
if (!isXorMode)
m_lineFormat.initGraphics(g);
if (!isXorMode)
restoreTransparencyComposite(g);
if (!isXorMode){
drawPort(g);
drawArrow(g);
drawLabel(g);
}
}
/**
* Draw two control handles internally.
*
* @param g A graphic canvas.
*/
private void drawControlHandles(Graphics g,boolean xorMode){
double zoom =getZoomScale();
Graphics2D g2 =(Graphics2D)g;
if (xorMode){
g2.setXORMode(Color.white);
}else{
g2.setPaintMode();
float dash1[]={4f};
BasicStroke bs_line=new BasicStroke(1f,BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER,10f,dash1,0f);
g2.setStroke(bs_line);
g2.setColor(Color.blue);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
int x1 = (int)(m_curve.getX1() * zoom);
int y1 = (int)(m_curve.getY1() * zoom);
int x2 = (int)(m_curve.getX2() * zoom);
int y2 = (int)(m_curve.getY2() * zoom);
int x3 = (int)(m_curve.getX3() * zoom);
int y3 = (int)(m_curve.getY3() * zoom);
int x4 = (int)(m_curve.getX4() * zoom);
int y4 = (int)(m_curve.getY4() * zoom);
g2.drawLine(x1,y1,x2,y2);
g2.drawLine(x4,y4,x3,y3);
}
/**
* Draw picked state of current object on graphic canvas.
*
* @param g A graphic canvas.
* @param ifRotate If user's operation or other actions force objects to be rotated.
*
*/
public void drawPicked(Graphics g, boolean ifRotate){
//if this shape is invisible, so draw virtual nodes
if (isInvisible()){
initBoundsNodeList();
m_boundsNodeList.draw(g,false);
return;
}
double zoom =getZoomScale();
((Graphics2D)g).setStroke(new BasicStroke(1));
//A AbstractArc should always consisted by it's nodes.
ObjectList nodeList = getNodeList();
Node node1;
//pick up each nodes,then draw them.
for (int i=0; i<nodeList.size(); i++){
try{
//when rotate, the two control nodes, 2 and 3 will not be drawn.
if (i==0 || i==3 ||!ifRotate){
node1 =(Node)nodeList.getByIndex(i);
node1.draw(g,ifRotate);
}
}catch(Exception e){
break; //slient break loop here.
}
}
drawControlHandles(g,false);
drawPort(g);
if (!ifRotate)
drawLabelPicked(g);
}
/**
* Test if current object intersects with a specified point.
*
* @param pnt A JFPoint used to test intersection.
*
*/
public boolean intersects(JFPoint pnt){
if (isInvisible())
return getBounds().contains(pnt);
else
return m_curve.contains(pnt,GeomConst.PICK_OFFSET);
}
/**
* Test if current object intersects with a specified rectangle.
*
* @param rect A Rect used to test intersection.
*
*/
public boolean intersects(Rect rect){
if (isInvisible())
return getBounds().intersects(rect);
else
return m_curve.intersects(rect);
}
/**
* Scale current object by specified points and scale percent.
* We only support a concurrent width-height scale here, suppose width as the length from
* basePoint to refPoint1, height as the length from basePoint to refPoint2, and
* one scale percent acts on both width and height.
*
* @param basePoint A base point that is unmovable.
* @param refPoint1 A 'width' reference point.
* @param refPoint2 A 'height' reference point.
* @param scale A reference scale percent.
*
*/
public void scaleBy(JFPoint basePoint, JFPoint refPoint1, JFPoint refPoint2, double scale){
startMoveLabel();
m_curve.scaleBy(basePoint,refPoint1,refPoint2,scale);
JFPoint center =m_curve.getCenter();
m_portList.scaleBy(center,basePoint,refPoint1,refPoint2,scale);
initNodes();
finishMoveLabel();
}
/**
* Scale current object by a specified x and y scale.<br>
* This is a special scale method used to scale a shape in arbitrary x and y scale.<br>
* Please see AbstractShape.scaleBy for detailed description.
*
* @param basePoint A base scale point for scaling reference.
* @param xScale A scale percentage in x coordinate, default to 1.0
* @param yScale A scale percentage in y coordinate, default to 1.0
*
*/
public void scaleBy(JFPoint basePoint,double xScale, double yScale){
startMoveLabel();
m_curve.scaleBy(basePoint,xScale,yScale);
m_portList.scaleBy(basePoint,xScale,yScale);
initNodes();
finishMoveLabel();
}
/**
* Move current object by an x and y offset.
*
* @param x, y Moving offsets.
*
*/
public void moveBy(double x, double y){
m_curve.moveBy(x,y);
initNodes();
m_portList.moveBy(x,y);
m_label.moveBy(x,y);
}
/**
* Rotate this object by an angle theta.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(double theta){
JFPoint center =m_curve.getCenter();
rotateBy(center.getX(),center.getY(),theta);
}
/**
* Rotate current object by a specified point and an angle theta.
*
* @param baseX, baseY A rotate center coordinates.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(double baseX,double baseY, double theta){
startMoveLabel();
m_curve.rotateBy(baseX,baseY,theta);
initNodes();
m_portList.rotateBy(baseX,baseY,theta);
finishMoveLabel();
}
/**
* Mirror this object by a central x coordinate of this object. We make a left-right flip here.
*/
public void mirrorBy(){
JFPoint center =m_curve.getCenter();
mirrorBy(center.getX());
}
/**
* Mirror this object by a x coordinate. We make a left-right mirror here.
*
* @param baseX A mirror base x coordinate.
*
*/
public void mirrorBy(double baseX){
startMoveLabel();
m_curve.mirrorBy(baseX);
initNodes();
m_portList.mirrorBy(baseX);
finishMoveLabel();
}
/**
* Reverse this object by a central y coordinate of this object. We make a up-down flip here.
*/
public void flipBy(){
JFPoint center =m_curve.getCenter();
flipBy(center.getY());
}
/**
* Reverse this object by a y coordinate. We make a up-down flip here.
*
* @param baseY A flip base y coordinate.
*
*/
public void flipBy(double baseY){
startMoveLabel();
m_curve.flipBy(baseY);
initNodes();
m_portList.flipBy(baseY);
finishMoveLabel();
}
/**
* Add a new port to this shape.
* @param x,y Current picking position.
*
*/
public Port addPort(double x,double y){
JFCurvePoint portPoint =m_curve.intersectsAt(x,y,GeomConst.PICK_OFFSET);
if (m_curve==null)
return null;
Port newPort =new CurvePort(this,Port.PORTTYPE_CUSTOM,portPoint,portPoint.getTimeInterval());
newPort =m_portList.addPort(newPort);
m_portList.setZoomScale(getZoomScale());
return newPort;
}
/**
* finish move all ports of this curve.
*/
public void finishMovePort(){
//re-set all ports by values of m_curve
Iterator it =m_portList.getList().iterator();
while (it!=null && it.hasNext()){
CurvePort port =(CurvePort)it.next();
JFPoint portPoint =m_curve.getPoint(port.getTimeInterval());
port.setPortPoint(portPoint);
}
}
/**
* When moving a node, in some cases, e.g. ctrl key or shift key pressed to force preserving
* the form of a shape, or force equilateral shapes, we need to recalculate the actual moving
* node's position.
*
* @param movePos Desire moving position of a node.
* @param moveCase Move case of a node, normal, shift key pressed or ctrl key pressed
* @return The actual moving position of a node.
*
*/
public JFPoint getMoveNodePos(Node node,JFPoint movePos,int moveCase){
if (node==null || movePos==null)
return null;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?