和风细雨

世上本无难事,心以为难,斯乃真难。苟不存一难之见于心,则运用之术自出。

在Swing中实现动态二维图元处理

在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(
00, myWidth, myHeight);

   
// 在背景图绘画图元 
   if (drawList != null{
      
for (Iterator it = drawList.iterator(); it.hasNext();) {
        Actable actor 
= (Actable) it.next();
        actor.paint(bg);
      }

    }


    
// 将背景图画在面板上
    g.drawImage(bgImage, 00this);
  }


  
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, 
00, 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) {

  }

}

posted on 2007-02-24 04:38 和风细雨 阅读(583) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: