jfline.java

来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,258 行 · 第 1/3 页

JAVA
1,258
字号
   	if (isInvisible())
   		return getBounds().intersects(rect);
   	else
   		return m_polyLine.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){
   	startMoveNode(null);
	m_polyLine.scaleBy(basePoint,refPoint1,refPoint2,scale);   	

	JFPoint center	=m_polyLine.getCenter();
	m_portList.scaleBy(center,basePoint,refPoint1,refPoint2,scale);
	initNodes();
   	finishMoveNode(null,0,0,null);
   }

   /**
    *   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){
   	startMoveNode(null);
	m_polyLine.scaleBy(basePoint,xScale,yScale);
	m_portList.scaleBy(basePoint,xScale,yScale);
	initNodes();
   	finishMoveNode(null,0,0,null);
  }
  
  

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

   /**
    *   Rotate this object by an angle theta.
    *
    *   @param theta A rotate angle.
    *
    */ 	
   public void rotateBy(double theta){
	JFPoint center		=m_polyLine.getCenter();
	rotateBy(center.getX(),center.getY(),theta);   	
   }

   /**
    *   Rotate current object by a specified point and an angle theta.
    *
    *   @param baseX,&nbsp;baseY A rotate center coordinates.
    *
    *   @param theta A rotate angle.
    *
    */ 	
   public void rotateBy(double baseX,double baseY, double theta){  
   	startMoveLabel();
   	m_polyLine.rotateBy(baseX,baseY,theta);
   	initNodes();
   	m_portList.rotateBy(baseX,baseY,theta);
   	finishMoveLabel();
   }


   /**
    *   Mirror this object by a central x coordinate of this object. We make a left-right flip here.
    */ 	
   public void mirrorBy(){
	JFPoint center		=m_polyLine.getCenter();
	mirrorBy(center.getX());
   }

   /**
    *   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_polyLine.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_polyLine.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_polyLine.flipBy(baseY);
   	initNodes();
   	m_portList.flipBy(baseY);

   	finishMoveLabel();
   	
   }

   /**
    *   Init all ports of this line.
    *   An object will always has its one or more stable ports and some customized ports,
    *   for JFLine, 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();

   		//only allowed add default ports to polyline, a polygon will has no initiative ports.
   		if (m_polyLine.isPolygon())
   			return;
		
   		int nodeCount	=m_polyLine.getNodeCount();
   			
   		if (nodeCount<2) return;
   			
		JFPoint  startPoint1   	=m_polyLine.getNode(0);
		JFPoint  startPoint2  	=m_polyLine.getNextNode(0,false);
		JFPoint  endPoint1   	=m_polyLine.getNode(nodeCount-1);
		JFPoint  endPoint2   	=m_polyLine.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));
                
                m_portList.setZoomScale(getZoomScale());
		

   	}catch(Exception e){
   	}
   }

   /**
    *   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){
   		m_logger.error("setPortList:"+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_polyLine.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 moving a node, in some cases, e.g. ctrl key or shift key pressed to force preserving 
    * the form of a shape, or force equilateral shapes, we need to recalculate the actual moving
    * node's position.
    *
    *  @param movePos Desire moving position of a node.
    *  @param moveCase Move case of a node, normal, shift key pressed or ctrl key pressed
    *  @return The actual moving position of a node.
    *
    */	  
   public JFPoint getMoveNodePos(Node node,JFPoint movePos,int moveCase){
   	if (node==null || movePos==null)
   		return null;
   	
   	switch (moveCase){
   		case ShapeConst.MOVEMENT_NORMAL:
   			return movePos;

   		case ShapeConst.MOVEMENT_SHIFTDOWN:
   		case ShapeConst.MOVEMENT_CTRLDOWN:
			int index	=m_nodeList.getIndexByObjectId(node.getObjectId());
			if (index<0)
				return movePos;

			JFPoint 	moveNode=m_polyLine.getNode(index);
			JFPoint		nextNode=m_polyLine.getNextNode(index,false);
			JFPoint		priorNode=m_polyLine.getNextNode(index,true);
			JFPoint		baseNode;
   		        
   		        if (nextNode==null || priorNode==null){
   				//force this node will move on vertical or horizontal line by according to the baseNode.
   		        	if (nextNode==null && priorNode==null)
   		        		return movePos;
   		        	
   		        	baseNode	=(nextNode!=null?nextNode:priorNode);

   				//offset between current moving position and baseNode
   				double x	=movePos.getX() - baseNode.getX();
   				double y	=movePos.getY() - baseNode.getY();
   				if (Math.abs(x)>Math.abs(y)){
   					movePos.setY(baseNode.getY());
   				}else{
   					movePos.setX(baseNode.getX());
   				}
   				return movePos;

   			}else{  
		
   				//force this node will move on vertical or horizontal line by according to the baseNode.
   				
   				//another two points built by prior node and next node within a rectangle.
   				double x1		=priorNode.getX();
   				double y1		=nextNode.getY();
				
   				double x2		=nextNode.getX();
   				double y2		=priorNode.getY();
   				
   				//according to the smaller distance node
   				if (movePos.distance(x1,y1)<movePos.distance(x2,y2))
					movePos.setValue(x1,y1);
				else
					movePos.setValue(x2,y2);
				
				return movePos;
   			}




   	}

   	
   	return movePos;
   }



   /**
    *   Start move a node.
    * 
    *   @param  node The node will be moved.
    *
    */ 	
   public void  startMoveNode(Node node){
	try{     
		startMoveLabel();
		
   		int nodeCount	=m_polyLine.getNodeCount();
   		if (nodeCount<2) return;

		int index	=m_nodeList.getIndexByObjectId(node.getObjectId());
		if (index<0) return;

		JFPointNode 	moveNode=m_polyLine.getNode(index);

		JFPointNode	refNode1=m_polyLine.getNextNode(index,false);
		JFPointNode	refNode2=m_polyLine.getNextNode(index,true);

		m_portList.startMoveNode(moveNode,refNode1,refNode2,null,moveNode.getNodeType());

	}catch(Exception e){
	}
   }


   /**
    *   When move polyline node, all of its relational ports will be moved concurrently,
    * 
    *   @param  newMoveNode Currently moving node.
    *
    */ 	
   public void finishMovePolyLineNode(JFPoint newMoveNode){
	
	
	/**
	 *  For moving poly 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!), sometimes the port position 
	 *     has the same position as one of the two END points,
	 *
	 *  2. when a node is moved to a new position, consider the polyline's constructing rules,
	 *     automatically combining the same slope lines, so this node, or its relational nodes will
	 *     no longer exist(will disappear) sometimes. 
	 *
	 *  3. a mid node can be moved into an 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.
	 *
	 */

	JFPoint 	lastMoveNode=m_portList.getMoveNode();
	JFPoint		lastRefNode1=m_portList.getRefNode1();
	JFPoint		lastRefNode2=m_portList.getRefNode2();
	//Node type of currently moving node.
	int nodeType=m_portList.getMoveNodeType();
	
	List portList	=m_portList.getList();
	Iterator it;
	Port port;
	JFPoint firstPoint;
	JFPoint secondPoint;
	JFPoint portPoint;
	

	//firstly, simply change all ports' position
	if (nodeType==JFPointNode.NODETYPE_END){
		//move node has changed to a new position, but the two reference points have not changed.
		m_portList.finishMoveNode(newMoveNode,null,null,null);
	
	}else if (nodeType==JFPointNode.NODETYPE_MIDDLE &&  (!lastMoveNode.equals(newMoveNode,true))){
				   		
		it	=portList.iterator();
		while (it!=null && it.hasNext()){
			port		=(Port)it.next();
			firstPoint	=port.getFirstPoint();
			secondPoint	=port.getSecondPoint();		

			
			if ((firstPoint.equals(lastRefNode1) && secondPoint.equals(lastRefNode2))||
			    (firstPoint.equals(lastRefNode2) && secondPoint.equals(lastRefNode1))){
			    	portPoint =port.getPortPoint();

			    	//two length from moveNode to two end points.
			    	double len1	=firstPoint.distance(newMoveNode);
			    	double len2	=secondPoint.distance(newMoveNode);
			    	if (len1<1) len1=1;
			    	if (len2<1) len2=1;

				//two length from last portPoint to two end points.
			    	double dist1	=firstPoint.distance(portPoint);
			    	double dist2	=secondPoint.distance(portPoint);
			    	
			    	//middle length of the line from firstpoint to secondpoint.
			    	double midLen	=firstPoint.distance(secondPoint)/2;
			    	if (midLen<1) midLen=1;
			    	
				double scale=0;
				double newDist=0;
			    	//now we move this port to the new line from firstPoint to moveNode,
			    	//or the new line from second point to moveNode.
			    	if (dist1<dist2){
			    		secondPoint.setValue(newMoveNode);
			    		scale	=dist1/midLen;
			    		newDist =len1*scale;
			    		port.setPortPoint(firstPoint.nearPoint(newMoveNode,newDist));	

				}else{
			    		firstPoint.setValue(newMoveNode);
			    		scale	=dist2/midLen;
			    		newDist =len2*scale;
			    		port.setPortPoint(secondPoint.nearPoint(newMoveNode,newDist));	


⌨️ 快捷键说明

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