2016-05-23 40 views
1

我想爲基本的繪圖程序創建一個撤消方法。目前,您可以更改筆刷的大小和顏色,然後抹掉。我試圖通過將前一個屏幕保存爲圖像(最後一個)來撤消,並在調用撤消時繪製該圖像。我嘗試了一些東西,但沒有任何工作。簡單地將圖像繪製爲「最後」會對清晰方法產生相同的效果。是否有任何想法?:撤消繪圖程序的方法(Java)

import java.applet.*; 
import java.util.*; 
import java.awt.*; 
import java.lang.Object.*; 

public class Paint extends Applet 
{ 
private int x; 
private int y; 
private int size = 10; 
private int sides = 200; 
private int color = 0; 
private Rectangle red, orange, yellow, green, blue, purple, pink, black; 
private Rectangle triangle, square, pentagon, hexagon, octagon, circle; 
private Rectangle small, medium, large; 
private Rectangle eraser, clear, undo; 
private Rectangle menuBar; 
private Image last; 
private Graphics g2; 

//defines rectangles 
public void init() 
{ 
    setSize(400,600); 

    red = new Rectangle(0,0,25,25); 
    orange = new Rectangle(0,25,25,25); 
    yellow = new Rectangle(0,50,25,25); 
    green = new Rectangle(0,75,25,25); 
    blue = new Rectangle(0,100,25,25); 
    purple = new Rectangle(0,125,25,25); 
    pink = new Rectangle(0,150,25,25); 
    black = new Rectangle(0,175,25,25); 

    triangle = new Rectangle(0,200,25,25); 
    square = new Rectangle(0,225,25,25); 
    pentagon = new Rectangle(0,250,25,25); 
    hexagon = new Rectangle(0,275,25,25); 
    octagon = new Rectangle(0,300,25,25); 
    circle = new Rectangle(0,325,25,25); 

    small = new Rectangle(0,355,25,25); 
    medium = new Rectangle(0,370,50,50); 
    large = new Rectangle(0,420,100,100); 

    eraser = new Rectangle(0,520,50,25); 
    clear = new Rectangle(0,545,60,30); 
    undo = new Rectangle(0,575,60,30); 

    menuBar = new Rectangle(0,0,70,650); 
} 

//paints the blocks of color in the menu bar 
public void paintColors(Graphics g) 
{ 
    g.setColor(Color.red); 
    g.fillRect(0,0,25,25); 
    g.setColor(Color.orange); 
    g.fillRect(0,25,25,25); 
    g.setColor(Color.yellow); 
    g.fillRect(0,50,25,25); 
    g.setColor(Color.green); 
    g.fillRect(0,75,25,25); 
    g.setColor(Color.blue); 
    g.fillRect(0,100,25,25); 
    g.setColor(new Color(160,32,240)); 
    g.fillRect(0,125,25,25); 
    g.setColor(Color.pink); 
    g.fillRect(0,150,25,25); 
    g.setColor(Color.black); 
    g.fillRect(0,175,25,25); 
} 

//paints the shapes, eraser, clear, and undo in the menu bar 
public void paintShapes(Graphics g) 
{ 
    g.setColor(Color.black); 
    Utility.fillTri(g,12,212,25); 
    g.fillRect(2,227,20,20); 
    Utility.fillPent(g,12,262,25); 
    Utility.fillHex(g,12,287,25); 
    Utility.fillOct(g,12,312,25); 
    Utility.fillPoly(g,12,337,25,300); 

    g.fillOval(2,355,10,10); 
    g.fillOval(2,370,50,50); 
    g.fillOval(2,420,100,100); 

    g.setColor(Color.black); 
    g.drawRect(1,521,52,26); 
    g.setColor(Color.pink); 
    g.fillRect(2,522,40,25); 

    g.setColor(Color.black); 
    g.setFont(new Font("Arial",Font.PLAIN,20)); 
    g.drawString("CLEAR",2,580); 
    g.drawString("UNDO",2,610); 
} 

public void paint(Graphics g) 
{ 
    g2 = getGraphics(); 

    g2.setColor(Color.white); 
    g2.fillRect(0,0,60,getHeight()); 
    paintColors(g2); 
    paintShapes(g2); 

    draw(g2); 
} 

public void draw(Graphics g) 
{ 
    getColor(g); 

    Utility.fillPoly(g,x,y,size,sides); //fills a regular polygon with specified center, size, and number of sides 
} 

public boolean mouseDown(Event e, int xx, int yy) 
{ 
    x = xx; 
    y = yy; 

    if(red.inside(xx,yy)) 
    color = 0; 
    else if(orange.inside(xx,yy)) 
    color = 1; 
    else if(yellow.inside(xx,yy)) 
    color = 2; 
    else if(green.inside(xx,yy)) 
    color = 3; 
    else if(blue.inside(xx,yy)) 
    color = 4; 
    else if(purple.inside(xx,yy)) 
    color = 5; 
    else if(pink.inside(xx,yy)) 
    color = 6; 
    else if(black.inside(xx,yy)) 
    color = 7; 

    if(triangle.inside(xx,yy)) 
    sides = 3; 
    else if(square.inside(xx,yy)) 
    sides = 4; 
    else if(pentagon.inside(xx,yy)) 
    sides = 5; 
    else if(hexagon.inside(xx,yy)) 
    sides = 6; 
    else if(octagon.inside(xx,yy)) 
    sides = 7; 
    else if(circle.inside(xx,yy)) 
    sides = 200; 

    if(small.inside(xx,yy)) 
    size = 10; 
    else if(medium.inside(xx,yy)) 
    size = 50; 
    else if(large.inside(xx,yy)) 
    size = 100; 

    if(eraser.inside(xx,yy)) 
    color = 8; 

    if(clear.inside(xx,yy)) 
    clear(g2); 
    else if(undo.inside(xx,yy)) 
    undo(g2); 

    if(!menuBar.inside(xx,yy)) 
    last = createImage(getWidth(),getHeight()); 

    return true; 
} 

public boolean mouseDrag(Event e, int xx, int yy) 
{ 
    x = xx; 
    y = yy; 
    if(!menuBar.inside(xx,yy)) 
    repaint(); 

    return true; 
} 

public void update(Graphics g) 
{ 
    paint(g); 
} 

public void clear(Graphics g) 
{ 
    color = 8; 
    getColor(g); 
    g.fillRect(0,0,getWidth(),getHeight()); 
    color = 0; 
    repaint(); 
} 

public void undo(Graphics g) 
{ 

{ 

public int getColor(Graphics g) 
{ 
    switch(color){ 
    case 0: g.setColor(Color.red); 
    break; 
    case 1: g.setColor(Color.orange); 
    break; 
    case 2: g.setColor(Color.yellow); 
    break; 
    case 3: g.setColor(Color.green); 
    break; 
    case 4: g.setColor(Color.blue); 
    break; 
    case 5: g.setColor(new Color(160,32,240)); 
    break; 
    case 6: g.setColor(Color.pink); 
    break; 
    case 7: g.setColor(Color.black); 
    break; 
    case 8: g.setColor(new Color(238,238,238)); 
    break; 
    } 

    return color; 
} 
} 
+1

關於代碼質量的備註:您的long long if/else狀態...只是可怕的代碼。擺脫它,否則維修將很快變成你的噩夢。對於實際問題:你可能想研究* Command *模式。而不是保存整個圖像(聽起來像是一個非常耗費資源的想法),你可能想要確保每個「改變」到一幅繪畫......實際上是某種命令對象;記得:你畫了一個圓,x,y,半徑,顏色。您將所有「應用」命令保留在隊列中;和「撤消」意味着放棄最後一個條目。 – GhostCat

+0

不,它可以工作,你必須包括所有的東西 – gpasch

+0

gpasch,它確實有效。我現在在我的電腦上運行它。它編譯並運行,但撤消方法有邏輯錯誤。 – MJ31

回答

0

即使mousedown未更改圖像,您也會添加到每個mousedown的撤消列表中。

因此,當您單擊撤消選項時,首先保存圖像,然後恢復同一圖像。

您應該只在圖像實際上被用戶修改之前保存到撤消列表。

+0

好的,謝謝。這確實有幫助。但是,撤消方法目前只是完全清除屏幕。 – MJ31

1

我強烈建議使用Command模式的某些變體來處理歷史記錄。

Swing有一個簡單的歷史管理器,名爲UndoManager。通常它與文本編輯器一起使用,但它也適用於自定義命令。

如果您不想使用Swing或UndoManager不符合您的要求,請嘗試使用其他獨立解決方案或實施您自己的解決方案。 I also implemented my own適用於大型跨平臺應用程序。因此,您應該將所有編輯方法包裝到實現通用接口(例如CommandUndoableEdit)的命令類中,並且具有「執行」和「撤消」的方法。

對於需要存儲關於編輯的最少信息的文本文檔,很難實現圖形命令。將更改區域的矩形從原始圖像存儲在「do」上並在「撤消」上恢復。