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

??}
}