📄 node.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, 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 + -