|  | 
				
					
	
		
			
 			Posted on 2007-07-23 09:30 Matthew Chen  阅读(594) 评论(5)  编辑  收藏   所属分类: Swing and AWT   作者: sitinspring   主页: http://www.blogjava.net/sitinspring/ 在Swing中绘制二维图,并有拖曳,缩放,链接,输出功能,主要有几大技术要点 1.绘画时的闪烁问题,解决方法是先将所有图元画到一张后台图上,在将后台图一次性画到面板上,请见public void paint(Graphics g)的处理. 2.鼠标响应:解决方法是添加面板的鼠标点击,鼠标拖曳处理,以鼠标的位置来确定图元的处理,请见函数public void mousePressed(MouseEvent e),public void mouseDragged(MouseEvent e)和public void mouseClicked(MouseEvent e). 3.单个图元处理:每个图元继承Actor2D类,它需要记住当前图元的起始位置和缩放比例. 4.多个图元处理:当大图元移动时,直线/折线图元需要根据大图元确定自己的位置,这时需要访问图元列表,以便知道那条直线在自身上. 5.输出图片:这个相对简单,看函数public boolean saveImage(String imagePath)的处理就可以了. 先写道这里,细节以后再整理,大家有兴趣先看看代码吧.
  public class PaintBoard extends JPanel implements MouseListener, 
   MouseMotionListener, KeyListener  { 
  
  // 背景图 
  private Image bgImage; 
  private Graphics bg; 
  
  // 画板上的二维图元列表 
  private ArrayList drawList=new ArrayList(); 
  
  // 画板几何尺寸 
  private int myWidth; 
  private int myHeight; 
     
  // 绘画图元时的偏移尺寸 
  private int xOffset, yOffset; 
  
  // 构造函数 
   public PaintBoard(MakeSqlToolbar toolbar)  { 
  super(); 
  this.toolbar = toolbar; 
  this.addMouseListener(this); 
  this.addMouseMotionListener(this); 
  this.addKeyListener(this); 
  } 
  
  // 调整画面大小时的处理 
   private void resizePaintBoard()  { 
  if (myWidth != this.getSize().width 
   || myHeight != this.getSize().height)  { 
  bgImage = null; 
  myWidth = this.getSize().width; 
  myHeight = this.getSize().height; 
  } 
  } 
  
  // 重新调整背景 
   private void reArrangeBg()  { 
   if (bgImage == null)  { 
  bgImage = this.createImage(myWidth, myHeight); 
  bg = bgImage.getGraphics(); 
  } 
  } 
  
  // 绘图的关键函数 
   public void paint(Graphics g)  { 
  resizePaintBoard(); 
  reArrangeBg(); 
  
  // 设置背景 
  bg.setColor(Color.white); 
  bg.fillRect(0, 0, myWidth, myHeight); 
  
  // 在背景图绘画图元 
   if (drawList != null)  { 
   for (Iterator it = drawList.iterator(); it.hasNext();)  { 
  Actable actor = (Actable) it.next(); 
  actor.paint(bg); 
  } 
  } 
  
  // 将背景图画在面板上 
  g.drawImage(bgImage, 0, 0, this); 
  } 
  
   private boolean mousePressActorTest(Actor2D actor, int x, int y)  { 
   if (actor.isInRect(x, y))  { 
  actor.setStatus(Actor2D.Status_Active); 
  xOffset = x - actor.getLeft(); 
  yOffset = y - actor.getTop(); 
  
   if(!(actor instanceof ActorTable))  { 
  return true; 
  } 
  ActorTable actorTable=(ActorTable)actor; 
   
   for (Iterator it = drawList.iterator(); it.hasNext();)  { 
  Actor2D actorTmp = (Actor2D) it.next(); 
  
   if (actorTmp instanceof ActorLine)  { 
  ActorLine actorLine = (ActorLine) actorTmp; 
  ActorPoint currPoint; 
   
  currPoint=actorLine.getStartPt(); 
  currPoint.setInner(actorTable.isInColumns(currPoint.getLeft(),currPoint.getTop())); 
   
  currPoint=actorLine.getEndPt(); 
  currPoint.setInner(actorTable.isInColumns(currPoint.getLeft(),currPoint.getTop())); 
  } 
  } 
  
  return true; 
  } 
   
  return false; 
  } 
  
   public void mousePressed(MouseEvent e)  { 
   for (Iterator it = drawList.iterator(); it.hasNext();)  { 
  Actor2D actor = (Actor2D) it.next(); 
  
   if (actor instanceof ActorLine)  { 
  ActorLine actorLine = (ActorLine) actor; 
  actorLine.setStatus(Actor2D.Status_Sleep); 
   } else  { 
  actor.setStatus(Actor2D.Status_Sleep); 
  } 
  } 
  
   for (Iterator it = drawList.iterator(); it.hasNext();)  { 
  Actor2D actor = (Actor2D) it.next(); 
  
   if (actor instanceof ActorLine)  { 
  ActorLine actorLine = (ActorLine) actor; 
  if (mousePressActorTest(actorLine.getStartPt(), e.getX(), e 
  .getY())) 
  break; 
  if (mousePressActorTest(actorLine.getEndPt(), e.getX(), e 
  .getY())) 
  break; 
   } else  { 
  if (mousePressActorTest(actor, e.getX(), e.getY())) 
  break; 
  } 
  } 
  
  repaint(); 
  } 
  
   private boolean mouseClickActorTest(Actor2D actor, int x, int y)  { 
   if (actor.isInRect(x, y))  { 
  actor.setStatus(Actor2D.Status_Active); 
  return true; 
   } else  { 
  return false; 
  } 
  } 
  
   public void mouseClicked(MouseEvent e)  { 
  this.requestFocusInWindow(); 
  
   for (Iterator it = drawList.iterator(); it.hasNext();)  { 
  Actor2D actor = (Actor2D) it.next(); 
  
   if (actor instanceof ActorLine)  { 
  ActorLine actorLine = (ActorLine) actor; 
  actorLine.setStatus(Actor2D.Status_Sleep); 
   } else  { 
  actor.setStatus(Actor2D.Status_Sleep); 
  } 
  } 
  
   for (Iterator it = drawList.iterator(); it.hasNext();)  { 
  Actor2D actor = (Actor2D) it.next(); 
  
   if (actor instanceof ActorLine)  { 
  ActorLine actorLine = (ActorLine) actor; 
  if (mouseClickActorTest(actorLine.getStartPt(), e.getX(), e 
  .getY())) 
  break; 
  if (mouseClickActorTest(actorLine.getEndPt(), e.getX(), e 
  .getY())) 
  break; 
   } else  { 
  if (mouseClickActorTest(actor, e.getX(), e.getY())) 
  break; 
  } 
  } 
  
  repaint(); 
  } 
  
   private void mouseDragActorTest(Actor2D actor, int x, int y)  { 
  if (!actor.isActive()) return; 
   
  Actor2D actorTest=new Actor2D(actor.getLeft(),actor.getTop(),actor.getWidth(),actor.getHeight()); 
  actorTest.setLeft(x - xOffset); 
  actorTest.setTop(y - yOffset); 
  makeActorInBound(actorTest); 
   
  int xChanged=actor.getLeft()-actorTest.getLeft(); 
  int yChanged=actor.getTop()-actorTest.getTop(); 
   
   if(actor instanceof ActorTable)  { 
  ActorTable actorTable = (ActorTable) actor; 
   
   for (Iterator it = drawList.iterator(); it.hasNext();)  { 
  Actor2D actorTmp = (Actor2D) it.next(); 
   
   if(actorTmp instanceof ActorLine)  { 
  ActorLine actorLine=(ActorLine)actorTmp; 
  ActorPoint currPoint; 
   
  currPoint=actorLine.getStartPt(); 
   if(actorTable.isInColumns(currPoint.getLeft(),currPoint.getTop()) && currPoint.isInner())  { 
  currPoint.setLeft(currPoint.getLeft()-xChanged); 
  currPoint.setTop(currPoint.getTop()-yChanged); 
  } 
   
  currPoint=actorLine.getEndPt(); 
   if(actorTable.isInColumns(currPoint.getLeft(),currPoint.getTop()) && currPoint.isInner())  { 
  currPoint.setLeft(currPoint.getLeft()-xChanged); 
  currPoint.setTop(currPoint.getTop()-yChanged); 
  } 
  } 
  } 
  } 
   
  actor.setLeft(actor.getLeft()-xChanged); 
  actor.setTop(actor.getTop()-yChanged); 
  } 
  
   public void mouseDragged(MouseEvent e)  { 
   for (Iterator it = drawList.iterator(); it.hasNext();)  { 
  Actor2D actor = (Actor2D) it.next(); 
  
   if (actor instanceof ActorLine)  { 
  ActorLine actorLine = (ActorLine) actor; 
  mouseDragActorTest(actorLine.getStartPt(), e.getX(), e.getY()); 
  mouseDragActorTest(actorLine.getEndPt(), e.getX(), e.getY()); 
   } else  { 
  mouseDragActorTest(actor, e.getX(), e.getY()); 
  } 
  } 
  
  repaint(); 
  } 
  
   private void keyPressedActorTest(Actor2D actor, int x, int y)  { 
   if (actor.isActive())  { 
  actor.setLeft(actor.getLeft() + x); 
  actor.setTop(actor.getTop() + y); 
  makeActorInBound(actor); 
  } 
  } 
  
   public void keyPressed(KeyEvent e)  { 
  int keyCode = e.getKeyCode(); 
  
  int xMicroOffset = 1, yMicroOffset = 1; 
  
   if (keyCode == KeyEvent.VK_RIGHT)  { 
  yMicroOffset = 0; 
   } else if (keyCode == KeyEvent.VK_LEFT)  { 
  xMicroOffset = -xMicroOffset; 
  yMicroOffset = 0; 
   } else if (keyCode == KeyEvent.VK_UP)  { 
  yMicroOffset = -yMicroOffset; 
  xMicroOffset = 0; 
   } else if (keyCode == KeyEvent.VK_DOWN)  { 
  xMicroOffset = 0; 
  } 
  
   for (Iterator it = drawList.iterator(); it.hasNext();)  { 
  Actor2D actor = (Actor2D) it.next(); 
  
   if (actor instanceof ActorLine)  { 
  ActorLine actorLine = (ActorLine) actor; 
  keyPressedActorTest(actorLine.getStartPt(), xMicroOffset, 
  yMicroOffset); 
  keyPressedActorTest(actorLine.getEndPt(), xMicroOffset, 
  yMicroOffset); 
   } else  { 
  keyPressedActorTest(actor, xMicroOffset, yMicroOffset); 
  } 
  } 
  
   if (keyCode == KeyEvent.VK_DELETE)  { 
   for (int i = 0; i < drawList.size(); i++)  { 
  Actor2D actor = (Actor2D) drawList.get(i); 
  
   if (actor instanceof ActorLine)  { 
  ActorLine actorLine = (ActorLine) actor; 
  
   if (actorLine.getStartPt().isActive())  { 
  if (ComDlgUtils 
  .popupConfirmCancelDialog("Do you wanna remove the Line:" 
   + actor.getName() + "?") == true)  { 
  drawList.remove(i); 
  } 
  } 
  
   if (actorLine.getEndPt().isActive())  { 
  if (ComDlgUtils 
  .popupConfirmCancelDialog("Do you wanna remove the Line:" 
   + actor.getName() + "?") == true)  { 
  drawList.remove(i); 
  } 
  } 
   } else  { 
   if (actor.isActive())  { 
  if (ComDlgUtils 
  .popupConfirmCancelDialog("Do you wanna remove the table:" 
   + actor.getName() + "?") == true)  { 
  drawList.remove(i); 
  } 
  } 
  } 
  } 
  } 
  
  repaint(); 
  } 
  
   private void makeActorInBound(Actor2D Actor)  { 
   if (Actor.getLeft() < 0)  { 
  Actor.setLeft(0); 
  } 
  
   if (Actor.getTop() < 0)  { 
  Actor.setTop(0); 
  } 
  
   if (Actor.getRight() > myWidth)  { 
  Actor.setLeft(myWidth - Actor.getWidth()); 
  } 
  
   if (Actor.getBottom() > myHeight)  { 
  Actor.setTop(myHeight - Actor.getHeight()); 
  } 
  } 
  
   public void mouseMoved(MouseEvent e)  { 
  toolbar.setMousePos(e.getX(), e.getY()); 
  } 
  
   public boolean saveImage(String imagePath)  { 
   try  { 
  FileOutputStream out = new FileOutputStream(imagePath); 
  JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 
  BufferedImage tag = new BufferedImage(myWidth, myHeight, 
  BufferedImage.TYPE_INT_RGB); 
  tag.getGraphics().drawImage(bgImage, 0, 0, myWidth, myHeight, null); 
  encoder.encode(tag); 
  out.close(); 
  return true; 
   } catch (Exception e)  { 
  ComDlgUtils.popupErrorDialog(e.getMessage()); 
  return false; 
  } 
  } 
   
   public ArrayList getDrawList()  { 
  return drawList; 
  } 
  
   public void setDrawList(ArrayList drawList)  { 
  this.drawList = drawList; 
  } 
  
   public void keyTyped(KeyEvent e)  { 
  } 
  
   public void keyReleased(KeyEvent e)  { 
  
  } 
  
   public void mouseEntered(MouseEvent e)  { 
  } 
  
   public void mouseExited(MouseEvent e)  { 
  } 
  
   public void mouseReleased(MouseEvent e)  { 
  
  } 
  } 
	    
    
Feedback
				
					
						# re: 在Swing中绘制二维图[zz]  回复  更多评论
						  
					
					2007-07-23 12:46 by 
				 
				
					
						# re: 在Swing中绘制二维图[zz]  回复  更多评论
						  
					
					2007-07-24 08:56 by 
				 sorry,平时很少上,刚看到你的评论,已经加上出处了。 
				
					
						# re: 在Swing中绘制二维图[zz]  回复  更多评论
						  
					
					2007-07-25 08:44 by 
				 感谢楼主转载. 
				
					
						# re: 在Swing中绘制二维图[zz]  回复  更多评论
						  
					
					2007-11-16 01:43 by 
				 不好意思,有完整可以执行的代码吗?谢谢 
				
					
						# re: 在Swing中绘制二维图[zz]  回复  更多评论
						  
					
					2012-03-23 23:23 by 
				 而且这个耗内存,无论内存多大都是不能容忍的。 |