作者: sitinspring
主頁: http://www.aygfsteel.com/sitinspring/
在Swing中繪制二維圖,并有拖曳,縮放,鏈接,輸出功能,主要有幾大技術要點
1.繪畫時的閃爍問題,解決方法是先將所有圖元畫到一張后臺圖上,在將后臺圖一次性畫到面板上,請見public void paint(Graphics g)的處理.
2.鼠標響應:解決方法是添加面板的鼠標點擊,鼠標拖曳處理,以鼠標的位置來確定圖元的處理,請見函數(shù)public void mousePressed(MouseEvent e),public void mouseDragged(MouseEvent e)和public void mouseClicked(MouseEvent e).
3.單個圖元處理:每個圖元繼承Actor2D類,它需要記住當前圖元的起始位置和縮放比例.
4.多個圖元處理:當大圖元移動時,直線/折線圖元需要根據(jù)大圖元確定自己的位置,這時需要訪問圖元列表,以便知道那條直線在自身上.
5.輸出圖片:這個相對簡單,看函數(shù)public boolean saveImage(String imagePath)的處理就可以了.
先寫道這里,細節(jié)以后再整理,大家有興趣先看看代碼吧.
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;

// 構造函數(shù)

public PaintBoard(MakeSqlToolbar toolbar)
{
super();
this.toolbar = toolbar;
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.addKeyListener(this);
}

// 調(diào)整畫面大小時的處理

private void resizePaintBoard()
{
if (myWidth != this.getSize().width

|| myHeight != this.getSize().height)
{
bgImage = null;
myWidth = this.getSize().width;
myHeight = this.getSize().height;
}
}

// 重新調(diào)整背景

private void reArrangeBg()
{

if (bgImage == null)
{
bgImage = this.createImage(myWidth, myHeight);
bg = bgImage.getGraphics();
}
}

// 繪圖的關鍵函數(shù)

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

}
}
主頁: http://www.aygfsteel.com/sitinspring/
在Swing中繪制二維圖,并有拖曳,縮放,鏈接,輸出功能,主要有幾大技術要點
1.繪畫時的閃爍問題,解決方法是先將所有圖元畫到一張后臺圖上,在將后臺圖一次性畫到面板上,請見public void paint(Graphics g)的處理.
2.鼠標響應:解決方法是添加面板的鼠標點擊,鼠標拖曳處理,以鼠標的位置來確定圖元的處理,請見函數(shù)public void mousePressed(MouseEvent e),public void mouseDragged(MouseEvent e)和public void mouseClicked(MouseEvent e).
3.單個圖元處理:每個圖元繼承Actor2D類,它需要記住當前圖元的起始位置和縮放比例.
4.多個圖元處理:當大圖元移動時,直線/折線圖元需要根據(jù)大圖元確定自己的位置,這時需要訪問圖元列表,以便知道那條直線在自身上.
5.輸出圖片:這個相對簡單,看函數(shù)public boolean saveImage(String imagePath)的處理就可以了.
先寫道這里,細節(jié)以后再整理,大家有興趣先看看代碼吧.










































































































































































































































































































































































































































































































































