|
Posted on 2007-07-23 09:30 Matthew Chen 阅读(557) 评论(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
而且这个耗内存,无论内存多大都是不能容忍的。
|