regularline.java

来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,911 行 · 第 1/4 页

JAVA
1,911
字号
/**
 *    $Id:RegularLine.java $
 *
 *    Copyright 2004 ~ 2005  JingFei International Cooperation LTD. All rights reserved. *
 */
package com.jfimagine.jfgraph.geom;


import java.awt.Graphics;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

import com.jfimagine.jfgraph.geom.JFPointNode;
import com.jfimagine.jfgraph.geom.LineSeg;
import com.jfimagine.jfgraph.geom.GeomConst;

 
 /**
 * A RegularLine class used to represents a continuous vertical or horizontal or both line.
 *
 *   <p> Attention: Here we used a clockwise quadrant system.
 *   And the first quadrant is under right bottom corner.
 *
 * @author     CookieMaker    
 *
 * @version $Revision: 1.00 $
 */  
 public class RegularLine implements Cloneable {

   /** An none line segment*/
   private static final int LINETYPE_NONE	=0;

   /** An vertical line segment*/
   private static final int LINETYPE_VERTICAL	=1;

   /** A horizontal line segment*/
   private static final int LINETYPE_HORIZONTAL	=2;
  	  
   /**
    *   A point node list for constructing a whole regular line.
    */
   private	List	m_nodeList	=new ArrayList();


   /**
    *   A temperary point node list for dragging.
    */
   private	List	m_dragList	=new ArrayList();


   /**
    *   A temperary point node list for storing point nodes object.
    */
   private	List	m_tempNodeList	=new ArrayList();

   /**
    *   Get point node list
    *
    *   @return  The point node list.
    *
    */ 	
   public List getNodeList(){
   	return m_nodeList;
   }

   /**
    *   Set point node list
    *
    *   @param val  A new point node list.
    *
    */ 	
   private void setNodeList(List nodeList){
   	//clear existent nodes.
   	clearNodes();
	
	for (int i=0; i<nodeList.size(); i++){  
		try{ 		
   			Object obj 	=nodeList.get(i);
   			if (obj!=null && obj instanceof JFPointNode)
   				m_nodeList.add(((JFPointNode)obj).clone());
   		}catch(Exception e){
   		}
   	}
   }


   /**
    *   Set point node list
    *
    *   @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 void setNodeList(int[] xpoints, int[] ypoints, int npoints){
   	clearNodes();
   	
   	int x=0,y=0;
   	int lastX=0, lastY=0;
   	for (int i=0; i<npoints; i++){
   		if (xpoints.length<i+1)
   			break;
   		if (ypoints.length<i+1)
   			break;
   		
   		x	=xpoints[i];
   		y	=ypoints[i];
   		if (i>0){  
   			if (x!=lastX && y!=lastY){
   				//to adjust line segment which is not vertical or horizontal
   				double xDiffer	=Math.abs(x-lastX);
   				double yDiffer	=Math.abs(y-lastY);
   				if (xDiffer<yDiffer){
   					x	=lastX;
   				}else{
   					y	=lastY;
   				}
   			}
   		}
   	        lastX	=x;
   	        lastY	=y;
   		
   		addNode(x,y);
   	}
   }


   /**
    *   Clear all nodes of this regular line.
    */ 	
   public void clearNodes(){
   	clearNodes(m_nodeList,true);
   }

   /**
    *   Clear all nodes of this regular line.
    */ 	
   private void clearNodes(List nodeList, boolean saveToTemporary){
   	
   	for (int i=nodeList.size()-1; i>=0; i--){
   		try{
   			if (saveToTemporary){
   				Object obj	=nodeList.get(i);
   				m_tempNodeList.add(obj);
   			}
   			nodeList.remove(i);
   		}catch(Exception e){
   		}
   	}
   }

   /**
    *   Get node count of regular line.
    *   @return node count.
    */ 	
   public int getNodeCount(){
   	return m_nodeList.size();
   }

   /**
    *   Get node count of regular line.
    *   @param nodeType The specified node type to be measured.
    *   @return node count.
    */ 	
   public int getNodeCount(int nodeType){
   	int ret=0;
	Iterator it	=m_nodeList.iterator();
	while (it!=null && it.hasNext()){
		JFPointNode node=(JFPointNode)it.next();
		if (node.getNodeType()==nodeType)
			ret++;
	}
	
	return ret;
   }


   /**
    *   Get a specified node of this regular line.
    *   @param nodeIndex A node index.
    *   @return the specified node.
    */ 	
   public JFPointNode  getNode(int nodeIndex){
   	return getNode(m_nodeList,nodeIndex);
   }


   /**
    *   Get a specified node of a node list.
    *   @param nodeList a specified node list.
    *   @param nodeIndex A node index.
    *   @return the specified node.
    */ 	
   private static JFPointNode  getNode(List nodeList,int nodeIndex){
   	int size=nodeList.size();
	if (nodeIndex<0 || nodeIndex>size-1)
		return null;
	else
		try{
			return (JFPointNode)nodeList.get(nodeIndex);
		}catch(Exception e){
			return null;
		}
   }

   /**
    *   Get a node's index inside a node list.
    *   @param nodeList A reference nodes list.
    *   @param node A specified node to be found.
    */ 	
   private static int getNodeIndex(List nodeList,JFPointNode node){
   	if (nodeList==null || nodeList.size()==0 || node==null)
   		return -1;
   	
   	for (int i=0; i<nodeList.size(); i++){
   		try{
   			JFPointNode newNode	=(JFPointNode)nodeList.get(i);
   			if (newNode.equals(node))
   				return i;
   		}catch(Exception e){
   			return -1;
   		}
   	}
   	
   	return -1;
   }

   /**
    *   Remove a specified node.
    *   @param nodeList A node list.
    *   @param node A node in the node list to be removed.
    *   @param storeToTemp if store the node removed to temporary list.
    */ 	
   private void removeNode(List nodeList,JFPointNode node, boolean storeToTemp){
   	if (nodeList==null || nodeList.size()==0 || node==null)
   		return;
   	
   	int ind	=getNodeIndex(nodeList,node);
   	removeNode(nodeList,ind,storeToTemp);
   }

   /**
    *   Remove a specified node.
    *   @param nodeList A node list.
    *   @param nodeIndex The index of specified node.
    *   @param storeToTemp if store the node removed to temporary list.
    */ 	
   private void removeNode(List nodeList,int nodeIndex, boolean storeToTemp){
   	if (nodeList==null || nodeIndex<0 || nodeIndex >nodeList.size()-1)
   		return;

   	if (storeToTemp){
   		try{
   			m_tempNodeList.add(nodeList.get(nodeIndex));
   		}catch(Exception e){
   		}
   	}

   	try{
   		nodeList.remove(nodeIndex);
	}catch(Exception e){
	}
   }


   /**
    *   Replace a specified node with a new node.
    *   @param nodeList A node list.
    *   @param node A node in the node list to be replaced.
    *   @param newNode A new node to replace the old node in the list.
    *   @param storeToTemp if store the node replaced to temporary list.
    */ 	
   private void replaceNode(List nodeList,JFPointNode node, JFPointNode newNode, boolean storeToTemp){
   	if (nodeList==null || nodeList.size()==0 || node==null)
   		return;
   	
   	int ind	=getNodeIndex(nodeList,node);
   	try{
   		nodeList.set(ind,newNode);
	}catch(Exception e){
	}
   	
   	if (storeToTemp){
   		m_tempNodeList.add(node);
   	}
   }


   /**
    *   Get last node of a regular line.
    *   @param refNodeList A reference node list.
    *   @param reverse True if get last node of this node list, False get first.
    *   @return the last node.
    */ 	
   private static JFPointNode  getLastNode(List refNodeList, boolean reverse){
   	if (refNodeList==null || refNodeList.size()==0)
   		return null;
	
	try{   		
   		if (reverse)
   			return (JFPointNode)refNodeList.get(refNodeList.size()-1);
   		else
   			return (JFPointNode)refNodeList.get(0);
   	}catch(Exception e){
   		return null;
   	}
   }

   /**
    *   Get last second node of a regular line. The last second node must be a corner/end point.
    *   @param refNodeList A reference node list.
    *   @param reverse True if get next second node of this node list, False get prior second one.
    *   @return the last second node.
    */ 	
   private static JFPointNode  getLastSecondNode(List refNodeList, boolean reverse){
   	JFPointNode lastNode	=getLastNode(refNodeList,reverse);
   	if (lastNode==null)
   		return null;
	else   		
   		return getNextNode(refNodeList,lastNode,reverse);
   }

   /**
    *   Get next node of a regularLine.
    *   @param node The node to start finding.
    *   @param reverse False if get next node of this node, true if get prior node of this node.
    *   @return the next node.
    */ 	
   public JFPointNode  getNextNode(JFPointNode node,boolean reverse){
   	if (node==null)
   		return null;
	return getNextNode(m_nodeList,node,reverse);   		
   }

   /**
    *   Get next node of a regularLine.
    *   @param nodeIndex The node index to start finding.
    *   @param reverse False if get next node of this node, true if get prior node of this node.
    *   @return the next node.
    */ 	
   public JFPointNode  getNextNode(int nodeIndex,boolean reverse){
   		try{
   			JFPointNode  node=(JFPointNode)m_nodeList.get(nodeIndex);
   			return getNextNode(node,reverse);
   		}catch(Exception e){
   		}
   		return null;
   }


   /**
    *   Get next end node of a regular line. 
    *   @param refNodeList A reference node list.
    *   @param refNode A reference node of reference node list.
    *   @param reverse True if get next end node of this node list, False get prior.
    *   @return the next end node.
    */ 	
   private static JFPointNode  getNextNode(List refNodeList, JFPointNode refNode,boolean reverse){
   	return getNextNode(refNodeList,refNode,reverse,false);
   }


   /**
    *   Get next end node of a regular line. 
    *   @param refNodeList A reference node list.
    *   @param refNode A reference node of reference node list.
    *   @param reverse True if get next end node of this node list, False get prior.
    *   @param midNodeAlso Not only an END node matches, also a MIDDLE node.
    *   @return the next end node.
    */ 	
   private static JFPointNode  getNextNode(List refNodeList, JFPointNode refNode,boolean reverse,boolean midNodeAlso){
   	if (refNodeList==null)
   		return null;
   		
   	int size	=refNodeList.size();
   	if (size==0)
   		return null;
   
   	boolean foundStart	=false;
   	if (refNode==null)
   		foundStart	=true;

   	int start	=0;
   	int end		=0;
   	if (reverse){
   		start	=size;
   	}else{
   		start	=-1;
   		end	=size-1;
   	}
   	
   	while (true){
   		if (reverse){
   			start--;
   			if (start<end) break;
   		}else{
   			start++;
   			if (start>end) break;
   		}

   		
   		try{
   			JFPointNode  newNode=(JFPointNode)refNodeList.get(start);
   			if (!foundStart){
   				if (newNode.equals(refNode))	
   					foundStart	=true;
   			}else if (newNode.getNodeType()==JFPointNode.NODETYPE_END ||
   			        (midNodeAlso && newNode.getNodeType()==JFPointNode.NODETYPE_MIDDLE)){
   					return newNode;
   			}
   		}catch(Exception e){
   			return null;
   		}
   	}
   	
   	return null;
   }



   /**
    *   Truncate the tail of node list to specified position.
    *   @param nodeList A node list that will be truncated.
    *   @param node A node indicates the node to stop truncating.
    *   @param storeToTemp if store the nodes truncated to temporary list.
    */ 	
   private void truncateTail(List nodeList,JFPointNode node, boolean storeToTemp){

	if (nodeList==null || nodeList.size()==0)
		return;
	
	int size = nodeList.size();
	for (int i=size-1; i>=0; i--){
		try{
			JFPointNode newNode=(JFPointNode)nodeList.get(i);
			if (node!=null && newNode.equals(node))
				break;
			else{
				if (storeToTemp)
					m_tempNodeList.add(newNode);
				nodeList.remove(i);
			}
		}catch(Exception e){
			break;		
		}
	}
  	
   }  


   /**
    *   Truncate the tail of node list to specified position.
    *   @param nodeList A node list that will be truncated.
    *   @param num The number of nodes to be truncated.
    *   @param storeToTemp if store the nodes truncated to temporary list.
    */ 	
   private void truncateTail(List nodeList,int num, boolean storeToTemp){

	if (nodeList==null || nodeList.size()==0 || num<=0)
		return;
	
	int size = nodeList.size();
	for (int i=size-1; i>=0; i--){
		try{
			num--;
			if (num<0) break;
			
			JFPointNode newNode=(JFPointNode)nodeList.get(i);
			if (storeToTemp)
				m_tempNodeList.add(newNode);
			nodeList.remove(i);
		}catch(Exception e){
			break;		
		}
	}
  	
   }  

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?