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