jfregularline.java
来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,295 行 · 第 1/3 页
JAVA
1,295 行
/**
* Mirror this object by a x coordinate. We make a left-right mirror here.
*
* @param baseX A mirror base x coordinate.
*
*/
public void mirrorBy(double baseX){
startMoveLabel();
m_regularLine.mirrorBy(baseX);
initNodes();
m_portList.mirrorBy(baseX);
finishMoveLabel();
}
/**
* Reverse this object by a central y coordinate of this object. We make a up-down flip here.
*/
public void flipBy(){
JFPoint center =m_regularLine.getCenter();
flipBy(center.getY());
}
/**
* Reverse this object by a y coordinate. We make a up-down flip here.
*
* @param baseY A flip base y coordinate.
*
*/
public void flipBy(double baseY){
startMoveLabel();
m_regularLine.flipBy(baseY);
initNodes();
m_portList.flipBy(baseY);
finishMoveLabel();
}
/**
* Draw current object's arrows.
*/
protected void drawArrow(Graphics g){
double zoom =getZoomScale();
int lineWidth =m_lineFormat.getLineWidth();
Color c =m_lineFormat.getLineColor();
int startArrow =m_arrow.getStartArrow();
int endArrow =m_arrow.getEndArrow();
int nodeCount =m_regularLine.getNodeCount();
JFPoint startPoint1 =m_regularLine.getNode(0);
JFPoint startPoint2 =m_regularLine.getNextNode(0,false);
JFPoint endPoint1 =m_regularLine.getNode(nodeCount-1);
JFPoint endPoint2 =m_regularLine.getNextNode(nodeCount-1,true);
if (zoom!=1.0){
startPoint1 =new JFPoint(startPoint1.getX() * zoom, startPoint1.getY() * zoom);
startPoint2 =new JFPoint(startPoint2.getX() * zoom, startPoint2.getY() * zoom);
endPoint1 =new JFPoint(endPoint1.getX() * zoom, endPoint1.getY() * zoom);
endPoint2 =new JFPoint(endPoint2.getX() * zoom, endPoint2.getY() * zoom);
}
Arrow.drawArrow(startArrow,lineWidth,startPoint2,startPoint1,g,c);
Arrow.drawArrow(endArrow,lineWidth,endPoint2,endPoint1,g,c);
}
/**
* Draw a node list.
*
* @param nodeList A node list to be drawn.
*
* @param g current drawing canvas.
* @param isXorMode If is in xor mode now.
*
*/
private void drawList(List nodeList,Graphics g,boolean isXorMode){
double zoom =getZoomScale();
int i=0;
float x=0;
float y=0;
float lastx=0;
float lasty=0;
//pick up each nodes of line, and draw them as a poly line.
GeneralPath line= new GeneralPath(GeneralPath.WIND_EVEN_ODD);
Iterator it=nodeList.iterator();
while (it!=null && it.hasNext()){
Object obj=it.next();
if (obj instanceof JFPointNode){
if (((JFPointNode)obj).getNodeType()==JFPointNode.NODETYPE_END){
x =(float)((JFPointNode)obj).getX();
y =(float)((JFPointNode)obj).getY();
}else{
continue;
}
}else if (obj instanceof RegularNode){
if (((RegularNode)obj).getNodeType()==JFPointNode.NODETYPE_END){
x =(float)((RegularNode)obj).getXOffset();
y =(float)((RegularNode)obj).getYOffset();
}else{
continue;
}
}else{
continue;
}
x =(float)(x * zoom);
y =(float)(y * zoom);
i++;
if (i==1)
line.moveTo(x,y);
else{
//line segment from last point to this point must be a vertical or horizontal line!
if ((int)Math.abs(lastx-x)!=0 && (int)Math.abs(lasty-y)!=0)
line.moveTo(x,y);
else
line.lineTo(x,y);
}
lastx =x;
lasty =y;
}
if (!isXorMode)
m_lineFormat.setGraphics(g);
((Graphics2D)g).draw(line);
//set the default graphics stroke and color.
if (!isXorMode)
m_lineFormat.initGraphics(g);
}
/**
* Draw current object on graphic canvas.
*
* @param g A graphic canvas.
* @param isXorMode If is in xor mode now.
*
*/
public void draw(Graphics g,boolean isXorMode){
if (g==null)
return;
//if user hide this shape, we'll draw an 'invisible' bounds here.
if (isInvisible()){
drawInvisibleBounds(g,isXorMode);
return;
}
if (!isXorMode)
setTransparencyComposite(g);
//A JFRegularLine should always consisted by it's nodes.
ObjectList nodeList = getNodeList();
drawList(nodeList.getList(),g,isXorMode);
if (!isXorMode)
restoreTransparencyComposite(g);
if (!isXorMode){
drawPort(g);
drawArrow(g);
drawLabel(g);
}
}
/**
* Init all ports of this regular line.
* An object will always has its one or more stable ports and some customized ports,
* for JFRegularLine, it will has two stable ports as below,
* port1 at start point of the line.
* port2 at end point of the line.
*/
protected void initPorts(){
try{
m_portList.clear();
int nodeCount =m_regularLine.getNodeCount();
if (nodeCount<2) return;
JFPoint startPoint1 =m_regularLine.getNode(0);
JFPoint startPoint2 =m_regularLine.getNextNode(0,false);
JFPoint endPoint1 =m_regularLine.getNode(nodeCount-1);
JFPoint endPoint2 =m_regularLine.getNextNode(nodeCount-1,true);
//port at start point1
m_portList.addPort(new Port(this,Port.PORTTYPE_DEFAULT,startPoint1,startPoint2,startPoint1));
//port at end point1
m_portList.addPort(new Port(this,Port.PORTTYPE_DEFAULT,endPoint1,endPoint2,endPoint1));
}catch(Exception e){
}
m_portList.setZoomScale(getZoomScale());
}
/**
* Set a port list of this shape.
*
* @param portList A new port list.
* @param shapeList All shape objects in a list.
*
*/
public void setPortList(ObjectList portList,ObjectList shapeList){
if (portList==null)
return;
try{
m_portList =(PortList)portList.clone();
//re-set parent.
Iterator it =m_portList.getList().iterator();
while (it!=null && it.hasNext()){
Port port =(Port)it.next();
port.setParent(this);
port.attachRealPort(shapeList);
}
}catch(Exception e){
}
}
/**
* Add a new port to this shape.
* @param x,y Current picking position.
*
*/
public Port addPort(double x,double y){
JFPoint startPoint =new JFPoint();
JFPoint endPoint =new JFPoint();
JFPoint portPoint =new JFPoint();
if (!m_regularLine.canAddPort(x,y,startPoint,endPoint,portPoint))
return null;
Port newPort =m_portList.addPort(new Port(this,Port.PORTTYPE_CUSTOM,startPoint,endPoint,portPoint));
m_portList.setZoomScale(getZoomScale());
return newPort;
}
/**
* When move a node, we have some important nodes here.
*/
private JFPoint m_moveNode =new JFPoint();
private JFPoint m_priorNode1 =new JFPoint();
private JFPoint m_priorNode2 =new JFPoint();
private JFPoint m_nextNode1 =new JFPoint();
private JFPoint m_nextNode2 =new JFPoint();
private int m_moveNodeType =0;
private int m_endNodeCount =0;
/**
* Start move a node.
*
* @param node The node will be moved.
*
*/
public void startMoveNode(Node node){
try{
startMoveLabel();
//initiate move nodes paramters.
m_moveNode.setValue(GeomConst.LARGE_VALUE,GeomConst.LARGE_VALUE);
m_priorNode1.setValue(GeomConst.LARGE_VALUE,GeomConst.LARGE_VALUE);
m_priorNode2.setValue(GeomConst.LARGE_VALUE,GeomConst.LARGE_VALUE);
m_nextNode1.setValue(GeomConst.LARGE_VALUE,GeomConst.LARGE_VALUE);
m_nextNode2.setValue(GeomConst.LARGE_VALUE,GeomConst.LARGE_VALUE);
m_moveNodeType =0;
m_endNodeCount =0;
int nodeCount =m_regularLine.getNodeCount();
if (nodeCount<2) return;
int index =m_nodeList.getIndexByObjectId(node.getObjectId());
if (index<0) return;
JFPointNode moveNode =m_regularLine.getNode(index);
JFPointNode priorNode1 =m_regularLine.getNextNode(index,true);
JFPointNode priorNode2 =m_regularLine.getNextNode(priorNode1,true);
JFPointNode nextNode1 =m_regularLine.getNextNode(index,false);
JFPointNode nextNode2 =m_regularLine.getNextNode(nextNode1,false);
m_moveNodeType =moveNode.getNodeType();
m_endNodeCount =m_regularLine.getNodeCount(JFPointNode.NODETYPE_END);
if (moveNode!=null) m_moveNode.setValue(moveNode);
if (priorNode1!=null) m_priorNode1.setValue(priorNode1);
if (priorNode2!=null) m_priorNode2.setValue(priorNode2);
if (nextNode1!=null) m_nextNode1.setValue(nextNode1);
if (nextNode2!=null) m_nextNode2.setValue(nextNode2);
}catch(Exception e){
}
}
/**
* Draw and drag last point to specified position.
* This method will be called while dragging and drawing a new node for regularline.
*
* @param x, y A new dragging position.
*
* @param g current drawing canvas.
*
*/
public void drawNewNodeTo(double x, double y,Graphics g){
List nodeList =m_regularLine.getDragLinePoints(x,y);
drawList(nodeList,g,true);
}
/**
* Move/adjust a node of current object.
*
* @param node Currently moving node.
*
* @param x, y Moving offsets.
*
* @param g current drawing canvas.
*
*/
public void moveNode(Node node, double x, double y,Graphics g){
if (node!=null && node instanceof RegularNode){
int index =m_nodeList.getIndexByObjectId(node.getObjectId());
if (index<0) return;
List moveList =m_regularLine.getMoveLinePoints(index,x,y,false);
if (g!=null)
drawList(moveList,g,true);
node.setXOffset(x);
node.setYOffset(y);
}
}
/**
* 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){
if (port==null || port.getParentId()!=getObjectId())
return false;
//not allowed to move customized ports.
if (port.getPortType()==Port.PORTTYPE_CUSTOM)
return false;
int portIndex =m_portList.getIndex(port);
RegularNode node;
RegularNode bakNode; //baknode is the opposite node of node above.
JFPoint bakNodePos=new JFPoint();
try{
if (portIndex==0){
//the start node.
node =(RegularNode)m_nodeList.getByIndex(0);
bakNode =(RegularNode)m_nodeList.getByIndex(m_nodeList.size()-1);
bakNodePos.setValue(bakNode.getNodePoint());
}else if (portIndex==1){
//the end node.
node =(RegularNode)m_nodeList.getByIndex(m_nodeList.size()-1);
bakNode =(RegularNode)m_nodeList.getByIndex(0);
bakNodePos.setValue(bakNode.getNodePoint());
}else{
return false;
}
}catch(Exception e){
return false;
}
//move the port relative nodes will move both nodes and ports.
startMoveNode(node);
moveNode(node,x,y,null);
finishMoveNode(node,x,y,null);
//if the bak node(opposite node of the node above) was moved, here to move back it.
if (!bakNode.getNodePoint().equals(bakNodePos,true)){
startMoveNode(bakNode);
moveNode(bakNode,bakNodePos.getX(),bakNodePos.getY(),null);
finishMoveNode(bakNode,bakNodePos.getX(),bakNodePos.getY(),null);
}
return true;
}
/**
* When move regularLine node, all of its relational ports will be moved concurrently,
*
* @param x,y new position of moving node.
*
*/
public void finishMoveRegularLineNode(double x, double y){
/**
* For moving regular line node, we need to consider following situations so we can
* correctly adjust the relational ports.
*
* 1. a port is always between two END points(not mid points or sub middle points!), sometimes the port position
* has the same position as one of the two END points(e.g. start port and end port),
*
* 2. when a node is moved to a new position, consider the regularLine's constructing rules,
* automatically combining the same slope lines(same slope and continous lines, same slope here means
* continuous vertical or horizontal lines), so this node, or its relational nodes will
* no longer exist(will disappear) sometimes.
*
* 3. the movement of a mid node will move itself and the relational two end points.
*
* 4. a sub middle node can be moved into an new END point, so we must make a decision that if the port between the two
* relational END points will lie on left or right side of this new END point.
*
*/
if (!m_priorNode1.isValid() && !m_nextNode1.isValid())
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?