2011-11-28 88 views
3

我還沒有使用過Swing/G2D,所以請耐心等待。 我有以下類,這是對我的GUI組件(意味着是一個樣的畫布上繪製):Graphics2D和JComponent

import javax.swing.*; 
import java.awt.*; 

public class DrawPanel extends JComponent{ 
public void paintComponent(Graphics g){ 
    Graphics2D g2 = (Graphics2D) g; 

    g2.setPaint(Color.black); 
    g2.fillRect(0, 0, getWidth(), getHeight()); 

    BrushStroke bs = new BrushStroke();  
    add(bs); 
} 
} 

我一直在試圖添加以下上面的JComponent:

import javax.swing.*; 
import java.awt.*; 

public class BrushStroke extends JComponent{ 
public void paintComponent(Graphics g){ 
    Graphics2D g2 = (Graphics2D) g; 
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
           RenderingHints.VALUE_ANTIALIAS_ON); 

    g2.setPaint(Color.red); 
    g2.fillOval(0, 0, 10, 10);   
} 
} 

BrushStroke不顯示在DrawPanel上。

我一直在尋找答案,我看到的每個例子似乎都是矛盾的。

如果有人嘗試過我的話,那麼我們將不勝感激。另外,如果我採取完全錯誤的做法,請說。

+0

您不應該爲畫筆描邊使用「JComponent」。 –

+0

@ChrisDennett,使用JComponent進行自定義繪畫沒有任何問題。默認情況下,該組件將是透明的。如果你想要一個不透明的組件,那麼,你可能會擴展JPanel,所以你不必擔心背景畫。 – camickr

回答

2

JComponent.add法,documentation說:

注:如果一個組件已被添加到已經 顯示的容器中,驗證必須調用該容器上,以顯示 新組件。如果添加了多個組件,則在添加了所有組件 後,您只需調用一次驗證,就可以提高 的效率。

添加一個元素後,你應該刷新你的DrawPanel。注意不要在painComponent方法中做到這一點,您將以無限遞歸結束。

執行以下操作來代替:

DrawPanel drawPanel = new DrawPanel(); 
drawPanel.add(new BrushStroke()); 
drawPanel.repaint(); 

編輯 這裏是一個完全工作的解決方案(延長JPanels代替的JComponent)

public static void main(String[] args){ 
    JFrame frame = new JFrame(); 
    DrawPanel drawPanel = new DrawPanel(); 
    drawPanel.add(new BrushStroke()); 
    frame.getContentPane().add(drawPanel); 
    frame.pack(); 
    frame.setVisible(true); 
} 
class DrawPanel extends JPanel{ 
    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setPaint(Color.black); 
     g2.fillRect(0, 0, getWidth(), getHeight()); 
    } 
    @Override 
    public Dimension getPreferredSize(){ 
     return new Dimension(100, 100); 
    } 
} 
class BrushStroke extends JPanel{ 
    public void paintComponent(Graphics g){ 
     this.setOpaque(false); 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setPaint(Color.red); 
     g2.fillOval(0, 0, 10, 10); 
    } 
    @Override 
    public Dimension getPreferredSize(){ 
     return new Dimension(10, 10); 
    } 
} 

的輸出提供了以下:

enter image description here

+0

嗨,謝謝你的回覆。我會試試這個。我確實有一個問題。我做了我最初的實現,並將DrawPanel轉儲到緩衝區中。有了這個新的原理圖,我將如何實現這一目標?謝謝。 –

+0

沒問題。將DrawPanel轉儲到緩衝區意味着什麼? – GETah

+0

-1,不,你不應該在paintComponent()的末尾做一個super.paint()。這將導致無限循環,因爲paint()調用paintComponent()。另外,您不應該直接在組件上調用paint()。你應該使用repaint()來告訴Swing組件需要重繪。 – camickr

3
  1. 您不應該在任何繪畫方法中將組件添加到面板。每當Swing確定組件需要着色時,繪畫方法都會被調用。因此,您將多次將組件添加到面板。

  2. 當你做自定義繪畫時,你負責重寫getPreferredSize()方法來給出組件的大小。這樣佈局管理員可以正確定位組件。如果你不這樣做,那麼首選的大小是0,所以沒有東西可以畫。

有關更多信息和示例,請參閱Swing教程中關於Custom Painting的部分。