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