regularline.java
来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,911 行 · 第 1/4 页
JAVA
1,911 行
/**
* Move a specified node to a new position.
* @param nodeIndex Index of the moving node.
* @param x; y A new position of this node.
* @param finishMoving If a move action is finished.
* @return return dragg line if finishMoving is null, return whole moved nodeList if finishMoving is true.
*/
public List getMoveLinePoints(int nodeIndex, double x, double y,boolean finishMoving){
//copy nodes if the first time to move nodes.
if (!m_moveStarted){
m_moveStarted =true;
m_originalIndex =nodeIndex;
}else{
//restore the ACTUAL node index from original index.
nodeIndex =m_originalIndex;
}
clearNodes(m_dragList,true);
clearNodes(m_storeList,true);
//get the node currently moved.
JFPointNode node =getNode(m_nodeList,nodeIndex);
if (node==null) return m_dragList;
JFPointNode priorNode=null, priorPriorNode=null;
JFPointNode nextNode=null, nextNextNode=null;
JFPointNode startNode=null, endNode=null;
int nodeType=node.getNodeType();
switch (nodeType){
case JFPointNode.NODETYPE_END:
//prior and next end node of this end node.
priorNode =getNextNode(m_nodeList,node,true);
if (priorNode!=null)
priorPriorNode =getNextNode(m_nodeList,priorNode,true);
nextNode =getNextNode(m_nodeList,node,false);
if (nextNode!=null)
nextNextNode =getNextNode(m_nodeList,nextNode,false);
startNode =node;
endNode =node;
//drag line from x,y to next end node
if (nextNode!=null || nextNextNode!=null){
if (nextNextNode!=null){
m_storeList.add(newNode(nextNextNode));
endNode =nextNextNode;
}else{
m_storeList.add(newNode(nextNode));
endNode =nextNode;
}
JFPointNode newNode =getUprightFoot(nextNode,nextNextNode,x,y);
if (newNode!=null){
addNodeFinally(m_storeList,newNode.getX(),newNode.getY(),false);
}
addNodeFinally(m_storeList,x,y,false);
m_tempNodeList.add(newNode);
}
//drag line from x,y to prior end node.
if (priorNode!=null || priorPriorNode!=null){
if (priorPriorNode!=null){
m_dragList.add(newNode(priorPriorNode));
startNode =priorPriorNode;
}else{
m_dragList.add(newNode(priorNode));
startNode =priorNode;
}
JFPointNode newNode =getUprightFoot(priorNode,priorPriorNode,x,y);
if (newNode!=null){
addNodeFinally(m_dragList,newNode.getX(),newNode.getY(),false);
}
addNodeFinally(m_dragList,x,y,false);
m_tempNodeList.add(newNode);
}
if (m_storeList.size()>0 && m_dragList.size()>0){
//the last node of m_draglist is equal as the first node of m_storeList.
truncateTail(m_dragList,1,true);
}
saveToList(m_storeList,m_dragList,null,true);
break;
case JFPointNode.NODETYPE_MIDDLE:
case JFPointNode.NODETYPE_SUBMIDDLE:
if (nodeType==JFPointNode.NODETYPE_MIDDLE){
priorNode =getNextNode(m_nodeList,node,true);
nextNode =getNextNode(m_nodeList,node,false);
}else{
priorNode =getNextNode(m_nodeList,node,true,true);
nextNode =getNextNode(m_nodeList,node,false,true);
}
double priorX =priorNode.getX();
double priorY =priorNode.getY();
double nextX =nextNode.getX();
double nextY =nextNode.getY();
double newPriorX=0, newPriorY=0, newNextX=0, newNextY=0;
//while moving a middle node, the middle node will only moved
//on the middle upright line of the line from priorNode to nextNode
if ((float)priorX==(float)nextX){
newPriorX =x;
newPriorY =priorY;
newNextX =x;
newNextY =nextY;
}else{
newPriorX =priorX;
newPriorY =y;
newNextX =nextX;
newNextY =y;
}
if (priorNode!=null)
priorPriorNode =getNextNode(m_nodeList,priorNode,true);
if (nextNode!=null)
nextNextNode =getNextNode(m_nodeList,nextNode,false);
JFPointNode newPrior =newNode(newPriorX,newPriorY,JFPointNode.NODETYPE_END);
if (priorPriorNode!=null){
startNode =priorPriorNode;
m_dragList.add(newNode(priorPriorNode));
if ((priorNode.getNodeType()!=JFPointNode.NODETYPE_MIDDLE) && (newPrior.middleOf(priorNode,priorPriorNode) || priorPriorNode.middleOf(newPrior,priorNode)))
addNodeFinally(m_dragList,newPrior.getX(),newPrior.getY(),false);
else{
addNodeFinally(m_dragList,priorNode.getX(),priorNode.getY(),false);
addNodeFinally(m_dragList,newPrior.getX(),newPrior.getY(),false);
}
}else{
startNode =priorNode;
m_dragList.add(newNode(priorNode));
addNodeFinally(m_dragList,newPrior.getX(),newPrior.getY(),false);
}
m_tempNodeList.add(newPrior); //remove newPrior
//expand line to newNext.
JFPointNode newNext =newNode(newNextX,newNextY,JFPointNode.NODETYPE_END);
addNodeFinally(m_dragList,newNext.getX(),newNext.getY(),false);
if (nextNextNode!=null){
if ((nextNode.getNodeType()!=JFPointNode.NODETYPE_MIDDLE) && (newNext.middleOf(nextNode,nextNextNode) || nextNextNode.middleOf(newNext,nextNode)))
addNodeFinally(m_dragList,nextNextNode.getX(),nextNextNode.getY(),false);
else{
addNodeFinally(m_dragList,nextNode.getX(),nextNode.getY(),false);
addNodeFinally(m_dragList,nextNextNode.getX(),nextNextNode.getY(),false);
}
endNode =nextNextNode;
}else{
endNode =nextNode;
addNodeFinally(m_dragList,nextNode.getX(),nextNode.getY(),false);
}
m_tempNodeList.add(newNext);
break;
}
if (finishMoving){
replaceNodes(m_nodeList,m_dragList,startNode,endNode);
return m_nodeList;
}else{
return m_dragList;
}
}
/**
* Finish drawing, and combine some nodes which are on same line.
*/
private void finishDrawing(){
//the clear method below is not necessary, m_storeList will always be empty here. if not, something wrong happend before.
clearNodes(m_storeList,true);
//reconstruct the whole regular line in storelist.
JFPointNode nextNode =getLastNode(m_nodeList,true);
while (nextNode!=null){
addNode(m_storeList,nextNode.getX(),nextNode.getY(),true);
nextNode =getNextNode(m_nodeList,nextNode,true);
}
clearNodes(m_nodeList,true);
//read from storelist to nodeList:
saveToList(m_storeList,m_nodeList,null,true);
//if finish drawing but only one node, here we added a new node to the list.
if (m_nodeList.size()==1){
JFPointNode node =getNode(0);
m_nodeList.add(new JFPointNode(node.getX()+GeomConst.PICK_OFFSET,node.getY(),JFPointNode.NODETYPE_END));
}
}
/**
* Finish move a specified node to a new position.
* @param nodeIndex Index of the moving node.
* @param x; y A new position of this node.
*/
public void finishMoveNode(int nodeIndex, double x, double y){
if (nodeIndex<0)
return;
getMoveLinePoints(nodeIndex,x,y,true);
m_moveStarted =false;
m_originalIndex =0;
finishDrawing();
}
/**
* Get line type of specified segment of a regular line.
* @param fromNode Start point of a line segment.
* @param toNode End point of a line segment.
* @return the line type
*/
private static int getSegmentType(JFPointNode fromNode, JFPointNode toNode){
if (fromNode==null || toNode==null)
return LINETYPE_NONE;
else{
if ((float)fromNode.getX()==(float)toNode.getX())
return LINETYPE_VERTICAL;
else
return LINETYPE_HORIZONTAL;
}
}
/**
* Cancel last node.
*/
public void cancelLastNode(){
if (m_nodeList.size()==0)
return;
JFPointNode lastNode =getLastNode(m_nodeList,true);
JFPointNode lastSecNode =getLastSecondNode(m_nodeList,true);
if (lastSecNode==null){
try{
m_nodeList.remove(0);
m_tempNodeList.add(lastNode);
}catch(Exception e){
}
}else{
truncateTail(m_nodeList,lastSecNode,true);
}
}
/**
* replace last node. and concurrently adjust the relational points.
* @param x; y A new node.
*/
public void replaceLastNode(double x, double y){
cancelLastNode();
addNode(x,y);
}
/**
* Get a new drag line's points list while appending a new point to Regular line.
* @param x, y A new dragging position.
*/
public List getDragLinePoints(double x, double y){
//we will always consider that a new point x,y will connect to the last point
//of existent regular line.
//clear drag nodes list firstly.
if (m_dragList.size()>0){
try{//node 0 is a valid node for m_nodeList, so it cannot be threw into temporary node list
m_dragList.remove(0);
}catch(Exception e){
}
}
clearNodes(m_dragList,true);
//add last node
JFPointNode lastNode=getLastNode(m_nodeList,true);
JFPointNode lastSecNode=getLastSecondNode(m_nodeList,true);
if (lastSecNode!=null)
m_dragList.add(newNode(lastSecNode));
if (lastNode!=null)
m_dragList.add(newNode(lastNode));
//add new nodes
addNode(m_dragList,x,y,false);
//if last second node is not null, then it's not necessary now in drag list, so remove it.
if (lastSecNode!=null)
removeNode(m_dragList,0,true);
return m_dragList;
}
/**
* Constructor for RegularLine.
*
*/
public RegularLine(){
}
/**
* Constructor for RegularLine.
*
* @param line A regular line.
*
*/
public RegularLine(RegularLine line){
if (line!=null){
setNodeList(line.getNodeList());
}
}
/**
* Constructor for RegularLine
*
* @param xpoints an array of x coordinates
* @param ypoints an array of y coordinates
* @param npoints the total number of points in the Polygon
*
*/
public RegularLine(int[] xpoints, int[] ypoints, int npoints){
setNodeList(xpoints,ypoints,npoints);
}
/**
* Get the bounds of this regular line.
*
* @return The bounds rectangle.
*
*/
public Rect getBounds(){
double minX=GeomConst.LARGE_VALUE;
double minY=GeomConst.LARGE_VALUE;
double maxX=-GeomConst.LARGE_VALUE;
double maxY=-GeomConst.LARGE_VALUE;
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
minX =Math.min(minX,node.getX());
minY =Math.min(minY,node.getY());
maxX =Math.max(maxX,node.getX());
maxY =Math.max(maxY,node.getY());
}
if (minX>maxX) minX =maxX;
if (minY>maxY) minY =maxY;
return new Rect(minX,minY,maxX - minX, maxY - minY);
}
/**
* Get a center point on this line.
*
* @return The center point.
*
*/
public JFPoint getCenter(){
Rect rect =getBounds();
return new JFPoint(rect.getX()+rect.getWidth()/2, rect.getY()+rect.getHeight()/2);
}
/**
* Move this line by specific x and y coordinates.
*
* @param x X coordiate to moveby.
*
* @param y Y coordiate to moveby.
*
*/
public void moveBy(double x, double y){
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
node.moveBy(x,y);
}
}
/**
* Rotate this line by an angle theta.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(double theta){
//the center point on this line
JFPoint center =getCenter();
rotateBy(center,theta);
}
/**
* Rotate this line by a specified point and an angle theta.
*
* @param pnt A rotate center point.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(JFPoint pnt, double theta){
if (pnt==null)
return;
rotateBy(pnt.getX(),pnt.getY(),theta);
}
/**
* Rotate this line 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){
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
node.rotateBy(baseX,baseY,theta);
}
}
/**
* Mirror this line by a central x coordinate of this line. We make a up-down reverse here.
*/
public void mirrorBy(){
JFPoint center =getCenter();
mirrorBy(center.getX());
}
/**
* Mirror this line by a x coordinate. We make a left-right mirror here.
*
* @param baseX A mirror base x coordinate.
*
*/
public void mirrorBy(double baseX){
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
node.mirrorBy(baseX);
}
}
/**
* Reverse this line by a central y coordinate of this line. We make a up-down flip here.
*/
public void flipBy(){
JFPoint center =getCenter();
flipBy(center.getY());
}
/**
* Reverse this line by a y coordinate. We make a up-down flip here.
*
* @param baseY A flip base y coordinate.
*
*/
public void flipBy(double baseY){
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
node.flipBy(baseY);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?