| 
			
		 | 
		
			
				
					
	
		
			
 			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 
				  
				而且这个耗内存,无论内存多大都是不能容忍的。 
			 
		
 
				
			 
		 |