jfregularline.java

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

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


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;
import java.awt.Color;

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

import com.jfimagine.jfdom.Document;
import com.jfimagine.jfdom.Element;

import com.jfimagine.jfgraph.shape.base.AbstractObject;
import com.jfimagine.jfgraph.shape.base.AbstractShape;
import com.jfimagine.jfgraph.shape.base.ShapeConst;
import com.jfimagine.jfgraph.shape.base.ObjectList;
import com.jfimagine.jfgraph.shape.base.JFVersion;

import com.jfimagine.jfgraph.shape.line.RegularNode;
import com.jfimagine.jfgraph.shape.base.Node;
import com.jfimagine.jfgraph.shape.base.NodeList;
import com.jfimagine.jfgraph.shape.base.Port;
import com.jfimagine.jfgraph.shape.base.PortList;
import com.jfimagine.jfgraph.shape.decorate.LineFormat;
import com.jfimagine.jfgraph.shape.decorate.Arrow;

import com.jfimagine.jfgraph.geom.JFPoint;
import com.jfimagine.jfgraph.geom.Rect;
import com.jfimagine.jfgraph.geom.LineSeg;
import com.jfimagine.jfgraph.geom.JFPointNode;
import com.jfimagine.jfgraph.geom.RegularLine;
import com.jfimagine.jfgraph.geom.GeomConst;
 
import com.jfimagine.utils.log.*;
 
 /**
 * JFRegularLine class.  
 * A regular line should be constructed by one or more vertical or horizontal line segments.
 *
 * @author     CookieMaker    
 *
 * @version $Revision: 1.00 $
 */  
 public class JFRegularLine extends AbstractShape{

   /**
    *   A XML string tag represents a Line
    */
   public  static final String	 XML_REGULARLINE		="RegularLine";

   /**an internal log utility*/
   private JFLogger m_logger=JFLogManager.getLogger(this.getClass());
   
   /**
    *   arrow format of current line.
    */ 
   protected Arrow  m_arrow	=new Arrow();
   
   /**
    *   line format of current line.
    */ 
   protected LineFormat  m_lineFormat = new LineFormat();

   /**
    *   Internal RegularLine object.
    */ 
   private RegularLine  m_regularLine = new RegularLine();

   
   /**
    *   Constructor for Regular Line
    */
   public JFRegularLine(){
   	setObjectType(ShapeConst.SHAPETYPE_REGULARLINE);
   	setXMLTag(XML_REGULARLINE);
   }	

   /**
    *   Constructor for Regular Line
    *
    *   @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 JFRegularLine(int[] xpoints, int[] ypoints, int npoints){   	
   	setObjectType(ShapeConst.SHAPETYPE_REGULARLINE);
   	setXMLTag(XML_REGULARLINE);
   	m_regularLine	=new RegularLine(xpoints,ypoints,npoints);
	finishDrawing();
   }  



   /**
    *   Get the arrow format of current object.
    * 
    *   @return  The arrow format.
    *
    */ 	
   public Arrow getArrow(){
   	return m_arrow;
   }

   /**
    *   Set the arrow format of current object.
    *
    *   @param arrow  A new arrow format object.
    *
    */ 	
   public void setArrow(Arrow arrow){
   	m_arrow.setValue(arrow);
   }
   
   
   /**
    *   Get the line format of current line.
    * 
    *   @return  The line format.
    *
    */ 	
   public LineFormat getLineFormat(){
   	return m_lineFormat;
   }

   /**
    *   Set the line format of current line.
    *
    *   @param lineFormat A new line format.
    *
    */ 	
   public void setLineFormat(LineFormat lineFormat){
   	m_lineFormat	=lineFormat;
   }

   /**
    *   Get the bounds of this rectangle.
    *
    *   @return The bounds rectangle of current rectangle.
    *
    */ 	
   public Rect getBounds(){
   	return m_regularLine.getBounds();
   }
   /**
    *   Ask if this object is an open shape,e.g. line,curve,arc,etc.
    *
    *   @return true if open,false closed.
    *
    */ 	
   public boolean isOpenShape(){
   	return true;
   }

   /**
    *   Init all nodes of this regular line.
    */ 	
   private void initNodes(){
   	int size	=m_regularLine.getNodeCount();
   	while (m_nodeList.size()<size){
   		try{	m_nodeList.add(new RegularNode());  }catch(Exception e){break;}
   	}
   	while (m_nodeList.size()>size){
   		try{    m_nodeList.removeByIndex(0); }catch(Exception e){  break; }
   	}

       JFPointNode srcNode;
       RegularNode destNode;
       
       for (int i=0; i<size; i++){
       		try{
       			srcNode		=m_regularLine.getNode(i);
       			destNode	=(RegularNode)m_nodeList.getByIndex(i);
       			destNode.setXOffset(srcNode.getX());
       			destNode.setYOffset(srcNode.getY());
       			destNode.setNodeType(srcNode.getNodeType());
       			destNode.setParent(this);
       		}catch(Exception e){
       			break;
       		}
       }	       
        
       m_nodeList.setZoomScale(getZoomScale()); 
   }

   /**
    *   Set a node list of this shape. 
    * 
    *   @param nodeList  A new node list.
    *
    */ 	
   public void setNodeList(ObjectList nodeList){
   	if (nodeList==null)
   		return;
   		
   	try{
   		m_nodeList	=(NodeList)nodeList.clone();

		//re-set parent.
   		Iterator it	=m_nodeList.getList().iterator();
   		while (it!=null && it.hasNext()){
			Node node	=(Node)it.next();
			node.setParent(this);
   		}
   		
   		recallNodes();
   	}catch(Exception e){
   	}
   }


   /**
    *   Recall point nodes of regularLine from m_nodesList.
    *   when restore nodes from xml documents or binary files, we will
    *   call this method for recovering point nodes.
    */ 	
   private void recallNodes(){
   	int size	=m_nodeList.size();
   	
   	m_regularLine.clearNodes();
   	List pointNodeList=m_regularLine.getNodeList();

       RegularNode srcNode;
       JFPointNode destNode;
       
       for (int i=0; i<size; i++){
       		try{
       			srcNode	=(RegularNode)m_nodeList.getByIndex(i);
       			destNode	=new JFPointNode(srcNode.getXOffset(),srcNode.getYOffset(),srcNode.getNodeType());
			pointNodeList.add(destNode);
       		}catch(Exception e){
       			break;
       		}
       }	       

	m_nodeList.setZoomScale(getZoomScale());	
   }

   /**
    *   Add a new node for current node list.
    *   here this method will always be called by DrawState class or any drawing class.
    * 
    *   @param x,&nbsp;y Coordinates of a new node.
    *
    */ 	
   public void addNode(double x, double y){
   	m_regularLine.addNode(x,y);
   	initNodes();
   }

   /**
    *   Finish drawing object.
    *
    */ 	
   public boolean finishDrawing(){
   	initNodes();
	initPorts();   	
	initLabel();
   	return true;
   }
  
   
   /**
    *   Remove last node added by addNode method.
    *   @return Last node that remained.
    *
    */ 	
   public Node removeLastNode(){
   	m_regularLine.cancelLastNode();
   	initNodes();
   	
   	if (m_nodeList.size()==0)
   		return null;
   	else{
   		try{
			return (Node)m_nodeList.getByIndex(m_nodeList.size()-1);   				
		}catch(Exception e){
			return null;
		}
	}
   }  

   /**
    *   If a regularline has been drew.
    *   @return True when complete, false otherwise.
    *
    */ 	
   public boolean ifCompleteDrawing(){
   	//two nodes added will decide a regularline.
   	return (m_regularLine.getNodeCount()>=2);
   }
      

   /**
    *   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_regularLine.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_regularLine.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_regularLine.scaleBy(basePoint,refPoint1,refPoint2,scale);   	

	JFPoint center	=m_regularLine.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_regularLine.scaleBy(basePoint,xScale,yScale);
	m_portList.scaleBy(basePoint,xScale,yScale);
	initNodes();
   	finishMoveLabel();
  }
  
  
  
   /**
    *   Move current object by an x and y offset.
    * 
    *   @param  x,&nbsp;y Moving offsets.
    *
    */ 	
   public void  moveBy(double x, double y){
   	m_regularLine.moveBy(x,y);
   	initNodes();
	m_portList.moveBy(x,y);   	
	m_label.moveBy(x,y);
   }

   /**
    *   Ask if this object is rotatable.
    *
    *   @return true if rotatable, false otherwise.
    *
    */ 	
   public boolean isRotatable(){
   	return false;
   }

   /**
    *   Rotate this object by an angle theta.
    *
    *   @param theta A rotate angle.
    *
    */ 	
   public void rotateBy(double theta){
   	//a rotateBy action to JFRegularLine will do nothing.
   }

   /**
    *   Rotate current object 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){
   	//a rotateBy action to JFRegularLine will only move the regular line.
   	JFPoint center		=m_regularLine.getCenter();
   	JFPoint newCenter	=new JFPoint(center);
   	newCenter.rotateBy(baseX,baseY,theta);
   	moveBy(newCenter.getX()-center.getX(),newCenter.getY()-center.getY());
   }


   /**
    *   Mirror this object by a central x coordinate of this object. We make a left-right flip here.
    */ 	
   public void mirrorBy(){
   	JFPoint center	=m_regularLine.getCenter();
   	mirrorBy(center.getX());
   }


⌨️ 快捷键说明

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