⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 node.java

📁 用Java开发的、实现类似Visio功能的应用程序源码
💻 JAVA
字号:
/**
 *    $Id:Node.java $
 *
 *    Copyright 2004 ~ 2005  JingFei International Cooperation LTD. All rights reserved. *
 */
package com.jfimagine.jfgraph.shape.base;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

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

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

import com.jfimagine.jfgraph.geom.GeomConst;
import com.jfimagine.jfgraph.geom.JFPoint;
import com.jfimagine.jfgraph.geom.Rect;
import com.jfimagine.jfgraph.shape.decorate.Arrow;


/**
 * Node Class. A node is used to construct, adjust or transform a shape, 
 * especially for a line object, it should always have two or more nodes
 * to modify its shape
 *
 * @author     CookieMaker    
 *
 * @version $Revision: 1.00 $
 */  
 public class Node extends AbstractObject {

   /**
    *   A XML string tag represents a jfnode
    */
   public  static final String	 XML_NODE		="Node";

   /**
    *   A XML string tag represents the x coordinate offset of this node
    */
   public  static final String   XML_XOFFSET		="xOffset";
   /**
    *   A XML string tag represents the y coordinate offset of this node
    */
   public  static final String   XML_YOFFSET		="yOffset";



   /** A node used to move its parent object */
   public static final int NODEUSAGE_MOVE	=0;
   /** A node used to rotate its parent object */
   public static final int NODEUSAGE_ROTATE	=1;
   
   
   /**
    *   A point for x,y coordinates.
    */
   protected	JFPoint	m_nodePoint	=new JFPoint();

   /**
    *   A parent object of this node.
    */
   protected	AbstractObject	m_parent;
   

   /**
    *   Constructor for Node
    */
   public Node(){
   	setObjectType(ShapeConst.SHAPETYPE_NODE);
   	setXMLTag(XML_NODE);
   }	

   /**
    *   Constructor for Node
    */
   public Node(double x,double y){
   	setObjectType(ShapeConst.SHAPETYPE_NODE);
   	setXMLTag(XML_NODE);
   	m_nodePoint.setX(x);
   	m_nodePoint.setY(y);
   }	

   /**
    *   Constructor for Node
    */
   public Node(JFPoint pnt){
   	setObjectType(ShapeConst.SHAPETYPE_NODE);
   	setXMLTag(XML_NODE);
   	m_nodePoint.setValue(pnt);
   }	


   /**
    *   Get parent object of this node.
    *   @return parent object.
    */
   public	AbstractObject	getParent(){
   	return m_parent;
   }

   /**
    *   Set parent object of this node.
    *   @param obj A new parent object.
    */
   public void	setParent(AbstractObject obj){
   	m_parent	=obj;
   }


   /**
    *   Get the x offset of current node. <br>
    *
    *   @return  The x offset of current node.
    *
    */ 	
   public double getXOffset(){
   	return m_nodePoint.getX();
   }

   /**
    *   Set the x offset of current node. <br>
    *
    *   @param  xOffset The x offset of current node.
    *
    *   @return  No return.
    *
    */ 	
   public void setXOffset(double xOffset){
   	m_nodePoint.setX(xOffset);
   }
   	


   /**
    *   Get the y offset of current node. <br>
    *
    *   @return  The y offset of current node.
    *
    */ 	
   public double getYOffset(){
   	return  m_nodePoint.getY();
   }

   /**
    *   Set the y offset of current node. <br>
    *
    *   @param  yOffset The y offset of current node.
    *
    */ 	
   public void setYOffset(double yOffset){
   	m_nodePoint.setY(yOffset);
   }

   /**
    *   Get the point of current node. <br>
    *
    *   @return  The x offset of current node.
    *
    */ 	
   public JFPoint getNodePoint(){
   	return m_nodePoint;
   }

   /**
    *   Set the point of current node. <br>
    *
    *   @param  pnt  The point of current node.
    *
    */ 	
   public void setNodePoint(JFPoint pnt){
   	m_nodePoint.setValue(pnt);
   }


   /**
    *   Draw current node rectangle on graphic canvas.
    * 
    *   @param  g  A graphic canvas.	
    *   @param  interColor  Interior color to fill the node rectangle.
    *   @param  exterColor  Exterior color to draw the outline of node rectangle.
    *
    */ 	
   protected void  drawNodeRect(Graphics g, Color interColor, Color exterColor){
   	if (g==null)
   		return;

	Graphics2D g2	=(Graphics2D)g;
	
  	double zoom	=getZoomScale();
	//width/height of a node.
	int nodeSize	=GeomConst.NODE_SIZE;

	g2.setColor(interColor);
	g2.fillRect((int)(m_nodePoint.getX() * zoom - nodeSize/2),(int)(m_nodePoint.getY() * zoom - nodeSize/2), nodeSize,nodeSize); 

	g2.setColor(exterColor);
	g2.drawRect((int)(m_nodePoint.getX() * zoom - nodeSize/2),(int)(m_nodePoint.getY() * zoom - nodeSize/2), nodeSize,nodeSize); 
   	
   }

   /**
    *   Draw current node circle on graphic canvas.
    * 
    *   @param  g  A graphic canvas.	
    *   @param  interColor  Interior color to fill the node rectangle.
    *   @param  exterColor  Exterior color to draw the outline of node rectangle.
    *
    */ 	
   protected void  drawNodeCircle(Graphics g, Color interColor){
	Graphics2D g2	=(Graphics2D)g;
	
  	double zoom	=getZoomScale();
	//width/height of a node.
	int nodeSize	=(int)Math.round(GeomConst.NODE_SIZE/2);

	g2.setColor(interColor);
	g2.fillOval((int)(m_nodePoint.getX() * zoom - nodeSize/2),(int)(m_nodePoint.getY() * zoom - nodeSize/2), nodeSize,nodeSize); 
   }

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

	
   /**
    *  Draw a rotation arrow on current node.
    */	
   protected  void drawRotateSign(Graphics g){
   	if (g==null)
   		return;

  	double zoom	=getZoomScale();
  	Arrow.drawRotateArrow(getXOffset()*zoom,getYOffset()*zoom,g);
   }

   /**
    *   Draw current object on graphic canvas.
    * 
    *   @param  g  A graphic canvas.	
    *   @param ifRotate If user's operation or other actions force objects to be rotated.
    *
    */ 	
   public void  draw(Graphics g, boolean ifRotate){
   	if (g==null)
   		return;

   	if (ifRotate){
   		drawNodeCircle(g,Color.white);
   		drawRotateSign(g);
   	}else{
   		drawNodeRect(g,Color.yellow,Color.black);
   	}
   }



   /**
    *   Test if current object intersects with a specified point.
    * 
    *   @param  pnt A JFPoint used to test intersection.
    *
    */ 	
   public boolean  intersects(JFPoint pnt){
	//if point is close to the node center, then return true
	//return pnt.contains(m_nodePoint.getX(),m_nodePoint.getY(), GeomConst.NODE_SIZE/2 + GeomConst.PICK_OFFSET);
	return pnt.contains(m_nodePoint.getX(),m_nodePoint.getY(),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 any vertex of the node rectangle is inside this rectangle, then return true.   	
   	return 	rect.contains(m_nodePoint.getX() - GeomConst.NODE_SIZE/2,m_nodePoint.getY() - GeomConst.NODE_SIZE/2) ||
   		rect.contains(m_nodePoint.getX() + GeomConst.NODE_SIZE/2,m_nodePoint.getY() - GeomConst.NODE_SIZE/2) ||
   		rect.contains(m_nodePoint.getX() - GeomConst.NODE_SIZE/2,m_nodePoint.getY() + GeomConst.NODE_SIZE/2) ||
   		rect.contains(m_nodePoint.getX() + GeomConst.NODE_SIZE/2,m_nodePoint.getY() + GeomConst.NODE_SIZE/2);
   }

   /**
    *   Move current object by an x and y offset.
    * 
    *   @param  x,&nbsp;y Moving offsets.
    *
    */ 	
   public void  moveBy(double x, double y){
   	m_nodePoint.moveBy(x,y);
   }

   /**
    *   Convert this node to String <br>
    * 
    *   @return  An string represents the content of the node
    *
    */ 	
   public String toString(){
   	StringBuffer	buf	=new StringBuffer();

   	buf.append(super.toString());
   	buf.append(";xOffset=");	buf.append(m_nodePoint.getX());
   	buf.append(";yOffset=");	buf.append(m_nodePoint.getY());
   	
   	return buf.toString();
   }

   /**
    *   Creates a new AbstractObject of the same class and with the same contents as this object.
    *   This method implements the method defined in AbstractObject.
    * 
    *   @return  A clone of this class.
    *
    */ 	
  protected AbstractObject cloneMe() throws CloneNotSupportedException{
  	return new Node();
  }
  
   /**
    *   Creates a new object of the same class and with the same contents as this object.
    * 
    *   @return  A clone of this instance.
    *
    */ 	
  public Object clone() throws CloneNotSupportedException{
  	try{
  		Node	node =(Node) super.clone();
		
		node.m_nodePoint.setValue(this.m_nodePoint);
  		
  		return node;
  		
	}catch(Exception e){
		throw new CloneNotSupportedException(e.getMessage());
	}
  }


   /**
    *   Returns the hashcode for this Object.
    * 
    *   @return hash code for this Node.
    *
    */ 	
  public int hashCode(){
  	long  x   =Double.doubleToLongBits(m_nodePoint.getX());
  	long  y   =Double.doubleToLongBits(m_nodePoint.getY());
  	
  	return 	super.hashCode() ^ (int)(x ^ (x >>> 32)) ^ (int)(y ^ (y >>> 32));
  }


   /**
    *   Determines whether or not two objects are equal. 
    * 
    * 	@param obj  an object to be compared with this object 
    * 
    *   @return true if the object to be compared is an instance of Node and has the same values; false otherwise.
    *
    */ 	
  public boolean equals(Object obj){
      if (!super.equals(obj))
      		return false;	
      if (obj == this)
             	return true;
      if (!(obj instanceof Node))
            	return false;
            	
      Node  node= (Node)obj;
      return  (Double.doubleToLongBits(m_nodePoint.getX())==Double.doubleToLongBits(node.m_nodePoint.getX())) &&
              (Double.doubleToLongBits(m_nodePoint.getY())==Double.doubleToLongBits(node.m_nodePoint.getY()))
              ;
  }
   

   /**
    *   Append necessary xml child for current element,
    *   this method will be called internally by toDOM.
    * 
    *   @param  element A XML element to append child xml nodes
    *   @param version A file version notification so this object can obey the rules to save data.
    *
    */ 	
  protected void appendChildToDOM(Element element,JFVersion version){
  	if (element==null)
  		return;
		
	super.appendChildToDOM(element,version);
    	element.addChild(new Element(XML_XOFFSET, m_nodePoint.getX()));
    	element.addChild(new Element(XML_YOFFSET, m_nodePoint.getY()));
  }


   /**
    *   Extract needed xml child from current element,
    *   this method will be called internally by fromDOM.
    * 
    *   @param  element An element used to extract needed xml child
    *   @param version A file version notification so this object can obey the rules to fetch data.
    *
    */ 	
  protected void extractChildFromDOM(Element element,JFVersion version){
      	if (element==null)
      		return;
      
      	super.extractChildFromDOM(element,version);
      	m_nodePoint.setX(Element.getDoubleValue(element.getChild(XML_XOFFSET)));
      	m_nodePoint.setY(Element.getDoubleValue(element.getChild(XML_YOFFSET)));
  }

   /**
    *   Save this node to a binary stream <br>
    * 
    *   @param stream An binary output stream
    *
    *   @param version A file version notification so this object can obey the rules to save data.
    *   @exception  java.io.IOException
    *
    */ 	
  public void saveToStream(com.jfimagine.utils.io.JFWriter stream,JFVersion version) throws IOException{
  	
  	super.saveToStream(stream,version);	
	stream.writeDouble(m_nodePoint.getX());
	stream.writeDouble(m_nodePoint.getY());	

  }


   /**
    *   Load node data from a binary stream <br>
    * 
    *   @param stream An binary input stream
    *
    *   @param skipHead Skip head 'TYPE' check, an shape object should always 
    *   has its own shape-type stored, if this shape-type has already been readed,
    *   this loadFromStream should/could not read the type anymore.
    *
    *   @param version A file version notification so this object can obey the rules to fetch data.
    *   @exception  java.io.IOException
    *
    */ 	
  public void loadFromStream(com.jfimagine.utils.io.JFReader stream, boolean skipHead, JFVersion version) throws IOException{
  	super.loadFromStream(stream,skipHead,version);
    	m_nodePoint.setX(stream.readDouble());
	m_nodePoint.setY(stream.readDouble());
  }


 	
 }

⌨️ 快捷键说明

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