📄 abstractshape.java
字号:
/**
* Draw an invisible bounds when user hides this shape.
*
* @param g A graphic canvas.
*
* @param isXorMode If is in xor mode now.
*/
public void drawInvisibleBounds(Graphics g, boolean isXorMode){
double zoom =getZoomScale();
//start to draw bounds in dash or dot lines only.
Rect rect =getBounds();
JFPoint leftTop =rect.getVertex(Rect.VERTEXTYPE_LEFTTOP);
JFPoint rightBottom =rect.getVertex(Rect.VERTEXTYPE_RIGHTBOTTOM);
GeneralPath path= new GeneralPath(GeneralPath.WIND_EVEN_ODD);
path.moveTo((float)(leftTop.getX()*zoom), (float)(leftTop.getY()*zoom));
path.lineTo((float)(rightBottom.getX()*zoom), (float)(leftTop.getY()*zoom));
path.lineTo((float)(rightBottom.getX()*zoom), (float)(rightBottom.getY()*zoom));
path.lineTo((float)(leftTop.getX()*zoom), (float)(rightBottom.getY()*zoom));
path.closePath();
if (!isXorMode){
if (isShowDesign()){
LineFormat lineFormat =LineFormat.getInvisibleLineFormat();
lineFormat.draw(g,path);
}
}else{
Graphics2D g2=(Graphics2D)g;
g2.setStroke(new BasicStroke(1));
g2.setColor(Color.black);
g2.draw(path);
}
}
/**
* Get which node of current shape that intersects with point pnt.
*
* @param pnt A JFPoint used to test intersection.
* @param usage Purpose to get a node intersected, e.g. move or rotate.
*
* @return A node of current shape.
*
*/
public Node nodeIntersects(JFPoint pnt,int usage){
if (isInvisible())
return null;
else
return m_nodeList.nodeIntersects(pnt,usage);
}
/**
* Get which port of current shape that intersects with point pnt.
*
* @param pnt A JFPoint used to test intersection.
* @param avoidParent A specified avoided parent to avoid connected to self.
*
* @return A port of current shape.
*
*/
public Port portIntersects(JFPoint pnt,AbstractObject avoidParent){
if (avoidParent!=null && this.equals(avoidParent))
return null;
return m_portList.portIntersects(pnt);
}
/**
* Get if current internal label of this shape intersects with point pnt.
*
* @param g A graphics context used to measure current text size on this graphics context.
* @param pnt A JFPoint used to test intersection.
* @return Internal label of this shape if intersected, null otherwise.
*
*/
public Label labelIntersects(Graphics g,JFPoint pnt){
if (isInvisible())
return null;
else{
if (m_label.intersects(g,pnt))
return m_label;
else
return null;
}
}
/**
* Get if current internal label of this shape intersects with point pnt.
*
* @param g A graphics context used to measure current text size on this graphics context.
* @param rect A rectangle used to test intersection.
* @return Internal label of this shape if intersected, null otherwise.
*
*/
public Label labelIntersects(Graphics g,Rect rect){
if (isInvisible()){
return null;
}else{
if (m_label.intersects(g,rect))
return m_label;
else
return null;
}
}
/**
* Move/adjust a port of current object.
* A move port event will always occured by relative objects' moving event.
*
* @param port Currently moving port.
* @param x, y new position of this port.
* @return True if successfully moved, false otherwise.
*
*/
public boolean movePort(Port port, double x, double y){
return false;
}
/**
* move relational ports while moving this object.
* @param movedList An object list that has already processed, so don't change them further.
*/
public void moveRelationalPorts(ObjectList movedList){
m_portList.moveRelationalPorts(movedList);
}
/**
* unbound broken ports
*/
public void unboundBrokenPorts(){
m_portList.unboundBrokenPorts();
}
/**
* Convert this object to String <br>
*
* @return An string represents the content of the object
*
*/
public String toString(){
StringBuffer buf=new StringBuffer();
buf.append(super.toString());
buf.append("\n<Label>\n");
buf.append(m_label.toString());
buf.append("disable scaling:"+m_disableScaling+"\n");
buf.append("disable modifying properties:"+m_disableModifyingProperties+"\n");
buf.append("disable motion:"+m_disableMotion+"\n");
buf.append("invisible:"+m_invisible+"\n");
buf.append("transparency:"+m_transparency+"\n");
buf.append("\n<FontFormat>\n");
buf.append(m_fontFormat.toString());
buf.append("\n<NodeList>\n");
buf.append(m_nodeList.toString());
buf.append("\n<PortList>\n");
buf.append(m_portList.toString());
buf.append("\n<PropertyList>\n");
buf.append(m_propertyList.toString());
buf.append("\n");
return buf.toString();
}
/**
* 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{
AbstractObject obj = (AbstractObject) super.clone();
AbstractShape newShape =(AbstractShape) obj;
newShape.m_nodeList =(NodeList)this.m_nodeList.clone();
newShape.m_portList =(PortList)this.m_portList.clone();
newShape.m_propertyList =(PropertyList)this.m_propertyList.clone();
newShape.m_label.setValue(this.m_label);
newShape.m_fontFormat.setValue(this.m_fontFormat);
newShape.m_disableScaling =this.m_disableScaling;
newShape.m_disableModifyingProperties =this.m_disableModifyingProperties;
newShape.m_disableMotion =this.m_disableMotion;
newShape.m_invisible =this.m_invisible;
newShape.m_transparency =this.m_transparency;
return newShape;
}
/**
* Returns the hashcode for this Object.
*
* @return hash code for this Point2D.
*
*/
public int hashCode(){
return super.hashCode()^
m_nodeList.hashCode() ^
m_portList.hashCode() ^
m_propertyList.hashCode()^
m_label.hashCode() ^
m_fontFormat.hashCode()^
(m_disableScaling?1:0) ^
(m_disableModifyingProperties?1:0) ^
(m_disableMotion?1:0)^
(m_invisible?1:0) ^
m_transparency
;
}
/**
* 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 Port 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 AbstractShape))
return false;
AbstractShape newShape= (AbstractShape)obj;
return
(m_nodeList.equals(newShape.m_nodeList)) &&
(m_portList.equals(newShape.m_portList)) &&
(m_propertyList.equals(newShape.m_propertyList)) &&
(m_label.equals(newShape.m_label)) &&
(m_fontFormat.equals(newShape.m_fontFormat))&&
m_disableScaling==newShape.m_disableScaling &&
m_disableModifyingProperties==newShape.m_disableModifyingProperties &&
m_disableMotion==newShape.m_disableMotion &&
m_invisible==newShape.m_invisible &&
m_transparency == newShape.m_transparency
;
}
/**
* 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);
m_nodeList.toDOM(element,version);
m_portList.toDOM(element,version);
m_propertyList.toDOM(element,version);
m_label.toDOM(element,version);
m_fontFormat.toDOM(element,version);
element.addChild(new Element(XML_DISABLESCALING,m_disableScaling));
element.addChild(new Element(XML_DISABLEMODIFYINGPROPERTIES,m_disableModifyingProperties));
element.addChild(new Element(XML_DISABLEMOTION,m_disableMotion));
element.addChild(new Element(XML_INVISIBLE,m_invisible));
element.addChild(new Element(XML_TRANSPARENCY,m_transparency));
}
/**
* 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_nodeList.fromDOM(element.getChild(m_nodeList.getXMLTag()),version);
m_portList.fromDOM(element.getChild(m_portList.getXMLTag()),version);
m_propertyList.fromDOM(element.getChild(m_propertyList.getXMLTag()),version);
m_label.fromDOM(element.getChild(m_label.getXMLTag()),version);
m_fontFormat.fromDOM(element.getChild(m_fontFormat.getXMLTag()),version);
m_disableScaling =Element.getBooleanValue(element.getChild(XML_DISABLESCALING));
m_disableModifyingProperties =Element.getBooleanValue(element.getChild(XML_DISABLEMODIFYINGPROPERTIES));
m_disableMotion =Element.getBooleanValue(element.getChild(XML_DISABLEMOTION));
m_invisible =Element.getBooleanValue(element.getChild(XML_INVISIBLE));
if (!version.lowerVersionOf(JFVersion.VERSIONID_170)){
m_transparency =Element.getIntValue(element.getChild(XML_TRANSPARENCY));
}
m_label.setFont(m_fontFormat.getFont());
m_nodeList.setParent(this);
m_portList.setParent(this);
m_label.setParent(this);
}
/**
* Save this object 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);
m_nodeList.saveToStream(stream,version);
m_portList.saveToStream(stream,version);
m_propertyList.saveToStream(stream,version);
m_label.saveToStream(stream,version);
m_fontFormat.saveToStream(stream,version);
stream.writeBoolean(m_disableScaling);
stream.writeBoolean(m_disableModifyingProperties);
stream.writeBoolean(m_disableMotion);
stream.writeBoolean(m_invisible);
stream.writeInt(m_transparency);
}
/**
* Load object 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_nodeList.loadFromStream(stream,false,version); //don't skip head here
m_portList.loadFromStream(stream,false,version); //don't skip head here
m_propertyList.loadFromStream(stream,false,version); //don't skip head here
m_label.loadFromStream(stream,false,version);
m_fontFormat.loadFromStream(stream,false,version);
if (version!=null && !version.lowerVersionOf(JFVersion.VERSIONID_111)){
m_disableScaling =stream.readBoolean();
m_disableModifyingProperties =stream.readBoolean();
m_disableMotion =stream.readBoolean();
}
if (version!=null && !version.lowerVersionOf(JFVersion.VERSIONID_160)){
m_invisible =stream.readBoolean();
}
if (version!=null && !version.lowerVersionOf(JFVersion.VERSIONID_170)){
m_transparency =stream.readInt();
}
m_label.setFont(m_fontFormat.getFont());
m_nodeList.setParent(this);
m_portList.setParent(this);
m_label.setParent(this);
}
//*****************************************************************
//***************** abstract methods *****************************
//*****************************************************************
/**
* Draw current object on graphic canvas.
*
* @param g A graphic canvas.
* @param isXorMode If is in xor mode now.
*
*/
public abstract void draw(Graphics g,boolean isXorMode);
/**
* Test if current object intersects with a specified point.
*
* @param pnt A JFPoint used to test intersection.
*
*/
public abstract boolean intersects(JFPoint pnt);
/**
* Test if current object intersects with a specified rectangle.
*
* @param rect A Rect used to test intersection.
*
*/
public abstract boolean intersects(Rect rect);
/**
* Move current object by an x and y offset.
*
* @param x, y Moving offsets.
*
*/
public abstract void moveBy(double x, double y);
/**
* 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 abstract void scaleBy(JFPoint basePoint, JFPoint refPoint1, JFPoint refPoint2, double scale);
/**
* 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>
* There would be some restrictions in this scale method:<br><br>
* Lines,regularlines,labellines,polygons, curves, arcs/chords/pies can be scaled in any situations.<br><br>
* Rectangles,diamonds,parallelograms,trapezoids,images,ellipses, hexagons and isoscelesTriangles
* can be scaled before they are rotated.<br><br>
* Rectangles,diamonds,parallelograms,trapezoids,images,ellipses, hexagons and isoscelesTriangles
* can only be scaled under a same x/y scale percentage after they are rotated. We will choose a smaller
* value between the xScale and yScale values for instead under this situation<br><br>
*
*
* @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 abstract void scaleBy(JFPoint basePoint,double xScale, double yScale);
/**
* Rotate current object by an angle theta.
*
* @param theta A rotate angle.
*
*/
public abstract void rotateBy(double theta);
/**
* Rotate current object by a specified point and an angle theta.
*
* @param baseX, baseY A rotate center coordinates.
*
* @param theta A rotate angle.
*
*/
public abstract void rotateBy(double baseX,double baseY, double theta);
/**
* Mirror this object by a central x coordinate of this object. We make a left-right flip here.
*/
public abstract void mirrorBy();
/**
* Mirror this object by a x coordinate. We make a left-right mirror here.
*
* @param baseX A mirror base x coordinate.
*
*/
public abstract void mirrorBy(double baseX);
/**
* Reverse this object by a central y coordinate of this object. We make a up-down flip here.
*/
public abstract void flipBy();
/**
* Reverse this rectangle by a y coordinate. We make a up-down flip here.
*
* @param baseY A flip base y coordinate.
*
*/
public abstract void flipBy(double baseY);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -