继往开来 吐故纳新
日历
网志分类
· 所有网志 (990)
· 个人作品 (62)
· 软件设计 (33)
· 面向对象编程 (22)
· JavaAPI (39)
· Java开源工具 (31)
· Swing (34)
· Java语法细节 (39)
· 样式表CSS (12)
· XML (10)
· J2EE(JavaEE) (23)
· 算法数据结构 (64)
· 正则表达式 (4)
· 软件知识 (6)
· Java线程 (9)
· Web开发.Jsp/Servlet/Struts (20)
· 程序随想录 (7)
· Spring (5)
· Hibernate (7)
· J2SE 高级 (2)
· J2SE 高级 (0)
· Web开发.Ajax (16)
· Web开发.JavaScript (43)
· DB4O (2)
· Web开发.CSS/Html (22)
· C# (20)
· ERP (4)
· JDBC (1)
· 编程资源 (16)
· 编程感悟 (29)
· DB/Sql (13)
· VB (29)
· VC (2)
· 桌面脚本 (3)
· 新兴软件 (3)
· 英语学习 (21)
· 网文转载 (159)
· 职场风云 (39)
· 诗词歌赋 (32)
· 生活感言 (77)
· 奇文共赏 (13)
· 财经纵横 (6)
· 未分类 (11)
站内搜索
友情链接
· 歪酷博客
· 我的歪酷 非非共享界
· 偶要雷锋
· 豆瓣
· nczonline
· 当当网
· easyjf中文站
· Donews
· 天极Java文章列表
· W3CSchool
· taiten的BLOG
· Dojo中国
· Dojo
· Extjs.com
· Lifehack中文网志
· JaveEye的一个AS专题
· Banq's JDon
· Java 中文网址大全
· 梦想Java
· 360Doc个人图书馆
· java开源大全
· 我在硅谷动力的软件下载站
· 站长中国
· 随意贴
· CSS教学素材站
· java 参考中文站
· 面向构件与SOA社区
· 彩字生成
· 派派小说论坛
· 如坐春风
· 英语学习网
· BBC CHina
· www.dlbang.com
· 古文竖排格式在线转化工具
· 免费家谱
· 图片上传基地
· 风景壁纸
· 和风细雨
· MyC#BlogInCsdn

订阅 RSS

0207491

歪酷博客

开此博一为经验积累,二为资料收集,三为同道交流,四为资源共享.
« 上一篇: 【转贴】李亚平评<<本草纲目>>的诞生 下一篇: 【整理】开发随想 »
Junglesong @ 2007-02-23 13:51

本文系原创文章,转载请注明出处(jungleosng.yculblog.com)

在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) {

  }
}





评论 / 个人网页 / 扔小纸条
* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 


 

分类小组论坛
杂谈 , 娱乐、八卦 , 文学、艺术 , 体育 , 旅游、同城 , 象牙塔 , 情感 , 时尚、生活 , 星座 , 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定