jfline.java
来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,258 行 · 第 1/3 页
JAVA
1,258 行
if (isInvisible())
return getBounds().intersects(rect);
else
return m_polyLine.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){
startMoveNode(null);
m_polyLine.scaleBy(basePoint,refPoint1,refPoint2,scale);
JFPoint center =m_polyLine.getCenter();
m_portList.scaleBy(center,basePoint,refPoint1,refPoint2,scale);
initNodes();
finishMoveNode(null,0,0,null);
}
/**
* 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){
startMoveNode(null);
m_polyLine.scaleBy(basePoint,xScale,yScale);
m_portList.scaleBy(basePoint,xScale,yScale);
initNodes();
finishMoveNode(null,0,0,null);
}
/**
* Move current object by an x and y offset.
*
* @param x, y Moving offsets.
*
*/
public void moveBy(double x, double y){
m_polyLine.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_polyLine.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_polyLine.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_polyLine.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_polyLine.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_polyLine.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_polyLine.flipBy(baseY);
initNodes();
m_portList.flipBy(baseY);
finishMoveLabel();
}
/**
* Init all ports of this line.
* An object will always has its one or more stable ports and some customized ports,
* for JFLine, it will has two stable ports as below,
* port1 at start point of the line.
* port2 at end point of the line.
*/
protected void initPorts(){
try{
m_portList.clear();
//only allowed add default ports to polyline, a polygon will has no initiative ports.
if (m_polyLine.isPolygon())
return;
int nodeCount =m_polyLine.getNodeCount();
if (nodeCount<2) return;
JFPoint startPoint1 =m_polyLine.getNode(0);
JFPoint startPoint2 =m_polyLine.getNextNode(0,false);
JFPoint endPoint1 =m_polyLine.getNode(nodeCount-1);
JFPoint endPoint2 =m_polyLine.getNextNode(nodeCount-1,true);
//port at start point1
m_portList.addPort(new Port(this,Port.PORTTYPE_DEFAULT,startPoint1,startPoint2,startPoint1));
//port at end point1
m_portList.addPort(new Port(this,Port.PORTTYPE_DEFAULT,endPoint1,endPoint2,endPoint1));
m_portList.setZoomScale(getZoomScale());
}catch(Exception e){
}
}
/**
* Set a port list of this shape.
*
* @param portList A new port list.
* @param shapeList All shape objects in a list.
*
*/
public void setPortList(ObjectList portList,ObjectList shapeList){
if (portList==null)
return;
try{
m_portList =(PortList)portList.clone();
//re-set parent.
Iterator it =m_portList.getList().iterator();
while (it!=null && it.hasNext()){
Port port =(Port)it.next();
port.setParent(this);
port.attachRealPort(shapeList);
}
}catch(Exception e){
m_logger.error("setPortList:"+e);
}
}
/**
* Add a new port to this shape.
* @param x,y Current picking position.
*
*/
public Port addPort(double x,double y){
JFPoint startPoint =new JFPoint();
JFPoint endPoint =new JFPoint();
JFPoint portPoint =new JFPoint();
if (!m_polyLine.canAddPort(x,y,startPoint,endPoint,portPoint))
return null;
Port newPort =m_portList.addPort(new Port(this,Port.PORTTYPE_CUSTOM,startPoint,endPoint,portPoint));
m_portList.setZoomScale(getZoomScale());
return newPort;
}
/**
* 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;
switch (moveCase){
case ShapeConst.MOVEMENT_NORMAL:
return movePos;
case ShapeConst.MOVEMENT_SHIFTDOWN:
case ShapeConst.MOVEMENT_CTRLDOWN:
int index =m_nodeList.getIndexByObjectId(node.getObjectId());
if (index<0)
return movePos;
JFPoint moveNode=m_polyLine.getNode(index);
JFPoint nextNode=m_polyLine.getNextNode(index,false);
JFPoint priorNode=m_polyLine.getNextNode(index,true);
JFPoint baseNode;
if (nextNode==null || priorNode==null){
//force this node will move on vertical or horizontal line by according to the baseNode.
if (nextNode==null && priorNode==null)
return movePos;
baseNode =(nextNode!=null?nextNode:priorNode);
//offset between current moving position and baseNode
double x =movePos.getX() - baseNode.getX();
double y =movePos.getY() - baseNode.getY();
if (Math.abs(x)>Math.abs(y)){
movePos.setY(baseNode.getY());
}else{
movePos.setX(baseNode.getX());
}
return movePos;
}else{
//force this node will move on vertical or horizontal line by according to the baseNode.
//another two points built by prior node and next node within a rectangle.
double x1 =priorNode.getX();
double y1 =nextNode.getY();
double x2 =nextNode.getX();
double y2 =priorNode.getY();
//according to the smaller distance node
if (movePos.distance(x1,y1)<movePos.distance(x2,y2))
movePos.setValue(x1,y1);
else
movePos.setValue(x2,y2);
return movePos;
}
}
return movePos;
}
/**
* Start move a node.
*
* @param node The node will be moved.
*
*/
public void startMoveNode(Node node){
try{
startMoveLabel();
int nodeCount =m_polyLine.getNodeCount();
if (nodeCount<2) return;
int index =m_nodeList.getIndexByObjectId(node.getObjectId());
if (index<0) return;
JFPointNode moveNode=m_polyLine.getNode(index);
JFPointNode refNode1=m_polyLine.getNextNode(index,false);
JFPointNode refNode2=m_polyLine.getNextNode(index,true);
m_portList.startMoveNode(moveNode,refNode1,refNode2,null,moveNode.getNodeType());
}catch(Exception e){
}
}
/**
* When move polyline node, all of its relational ports will be moved concurrently,
*
* @param newMoveNode Currently moving node.
*
*/
public void finishMovePolyLineNode(JFPoint newMoveNode){
/**
* For moving poly line node, we need to consider following situations so we can
* correctly adjust the relational ports.
*
* 1. a port is always between two END points(not mid points!), sometimes the port position
* has the same position as one of the two END points,
*
* 2. when a node is moved to a new position, consider the polyline's constructing rules,
* automatically combining the same slope lines, so this node, or its relational nodes will
* no longer exist(will disappear) sometimes.
*
* 3. a mid node can be moved into an END point, so we must make a decision that if the port between the two
* relational END points will lie on left or right side of this new END point.
*
*/
JFPoint lastMoveNode=m_portList.getMoveNode();
JFPoint lastRefNode1=m_portList.getRefNode1();
JFPoint lastRefNode2=m_portList.getRefNode2();
//Node type of currently moving node.
int nodeType=m_portList.getMoveNodeType();
List portList =m_portList.getList();
Iterator it;
Port port;
JFPoint firstPoint;
JFPoint secondPoint;
JFPoint portPoint;
//firstly, simply change all ports' position
if (nodeType==JFPointNode.NODETYPE_END){
//move node has changed to a new position, but the two reference points have not changed.
m_portList.finishMoveNode(newMoveNode,null,null,null);
}else if (nodeType==JFPointNode.NODETYPE_MIDDLE && (!lastMoveNode.equals(newMoveNode,true))){
it =portList.iterator();
while (it!=null && it.hasNext()){
port =(Port)it.next();
firstPoint =port.getFirstPoint();
secondPoint =port.getSecondPoint();
if ((firstPoint.equals(lastRefNode1) && secondPoint.equals(lastRefNode2))||
(firstPoint.equals(lastRefNode2) && secondPoint.equals(lastRefNode1))){
portPoint =port.getPortPoint();
//two length from moveNode to two end points.
double len1 =firstPoint.distance(newMoveNode);
double len2 =secondPoint.distance(newMoveNode);
if (len1<1) len1=1;
if (len2<1) len2=1;
//two length from last portPoint to two end points.
double dist1 =firstPoint.distance(portPoint);
double dist2 =secondPoint.distance(portPoint);
//middle length of the line from firstpoint to secondpoint.
double midLen =firstPoint.distance(secondPoint)/2;
if (midLen<1) midLen=1;
double scale=0;
double newDist=0;
//now we move this port to the new line from firstPoint to moveNode,
//or the new line from second point to moveNode.
if (dist1<dist2){
secondPoint.setValue(newMoveNode);
scale =dist1/midLen;
newDist =len1*scale;
port.setPortPoint(firstPoint.nearPoint(newMoveNode,newDist));
}else{
firstPoint.setValue(newMoveNode);
scale =dist2/midLen;
newDist =len2*scale;
port.setPortPoint(secondPoint.nearPoint(newMoveNode,newDist));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?