2012-02-11 106 views
4

我基本上試圖做一些經典的「Paint」(微軟的程序)。但是我想在繪畫時使用圖層。我以爲我可以使用JPanel組件作爲圖層。在java上分層繪畫?

我正在測試下面的代碼。目標是用鼠標繪製一個矩形。在拖動鼠標的同時繪製一個臨時層(temp),並在鼠標釋放時繪製實際的圖層(區域)。但每次我開始繪製一個新的矩形,舊的都消失了。此外,如果我執行setVisible(false)並再次爲true,則一切消失。

MouseInputAdapter mia = new MouseInputAdapter() { 
    private int startx = 0, starty = 0, stopx = 0, stopy = 0; 

    public void mousePressed(MouseEvent evt) { 
     startx = evt.getX(); 
     starty = evt.getY(); 
    } 

    public void mouseDragged(MouseEvent evt) { 
     Graphics2D tempg = (Graphics2D) temp.getGraphics(); 

     int width = Math.abs(startx - evt.getX()); 
     int height = Math.abs(starty - evt.getY()); 
     int x = evt.getX(), y = evt.getY(); 
     if(x > startx) 
      x = startx; 
     if(y > starty) 
      y = starty; 

     Rectangle r = new Rectangle(x, y, width, height); 
     tempg.clearRect(0, 0, getWidth(), getHeight()); 
     tempg.draw(r); 
    } 

    public void mouseReleased(MouseEvent evt) { 
     Graphics2D g = (Graphics2D) area.getGraphics(); 
     stopx = evt.getX(); 
     stopy = evt.getY(); 

     int width = Math.abs(startx - stopx); 
     int height = Math.abs(starty - stopy); 
     int x = startx, y = starty; 
     if(x > stopx) 
      x = stopx; 
     if(y > stopy) 
      y = stopy; 

     Rectangle r = new Rectangle(x, y, width, height); 
     g.draw(r); 
    } 
}; 
area.addMouseListener(mia); 
area.addMouseMotionListener(mia); 
temp.addMouseListener(mia); 
temp.addMouseMotionListener(mia); 

該代碼有什麼問題?

+1

問:該代碼有什麼問題?答:getGraphics() – kleopatra 2012-02-12 09:34:32

回答

0

這就是我一直在尋找; http://www.leepoint.net/notes-java/examples/mouse/paintdemo.html

我的錯誤;使用paintComponent()中的getGraphics()方法並期望保持更改。

爲什麼@ Keilly的回答不適合我;因爲如果我把形狀放在列表或數組中,當形狀發生變化時(例如,刪除一個圓的1/4),我無法更新列表中的元素。因爲它不再是相同的形狀。所以我必須保持圖形的形狀,我不必(並不想)分開保存它們。

+0

如果形狀在列表中,則可以從任何地方對其進行修改。該列表只是指向您提供的對象,因此請保留對它們的引用,並對每個單獨的形狀執行您喜歡的操作。 – Keilly 2013-05-30 01:32:04

6

每次重繪時,都無法保證在您離開它的狀態下會得到相同的圖形。

兩個兩步來代替:

  • 在你的類創建矩形列表。
  • 在您的鼠標偵聽器中,而不是繪製到圖形,添加一個矩形列表。
  • 覆蓋paintComponent並在那裏將矩形列表繪製到傳遞的圖形上。

使用列表很不錯,因爲在列表的開始處的項目將被繪製在最後的項目之下。

+0

但我不是隻處理矩形。將會有很多隨機形狀,也許我會刪除可以包含這些形狀的一部分的圖層的一部分。如果每次發佈都可以保留整個圖層,那麼對於我認爲的內存來說,編碼和打火會更容易。但我不知道該怎麼做。 – 2012-02-11 23:11:26

+0

+1用於在'paintComponent()'中渲染圖層。 – trashgod 2012-02-12 01:40:37

1

這裏有一個總體思路:(我假設你的意思層,比如在Photoshop)

設置繪圖單一的JPanel。

製作一個數據結構,其中包含繪製所需的所有可繪製對象。

在這個數據結構中,還要創建一個包含整數的字段,該整數表示特定可繪製對象綁定到哪個圖層。

在你的paintComponent()方法中,檢查哪個圖層當前處於活動狀態,只繪製該圖層或下方的數據。