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;&nbsp;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,&nbsp;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,&nbsp;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 + -
显示快捷键?