2011-09-13 54 views
1

我只是在玩Swing,我正在研究一個非常簡單的Swing組件。我有一個繼承自JComponent類的組件,它的UI從ComponentUI繼承。該paint()方法是這樣的:簡單的自定義Swing JComponent總是平坦的

public void paint(Graphics g, JComponent c) { 
    int x = c.getX(); 
    int y = c.getY(); 
    c.setBounds(x, y, 100, 25); 
    int width = c.getWidth(); 
    int height = c.getHeight(); 
    Rectangle r = g.getClipBounds(); 
    g.fillRect(0, 0, 10, 10); 
    g.drawString("Baf!", 3, 3); 
} 

但它是完全不可能得到的r.height另一個值大於1給出的成分是寬度,但高度只有一個百達點。有沒有人經歷過類似的組件?不幸的是,沒有任何簡單的教程。所有的教程都是不可理解的複雜(或過時的)。

看起來,佈局管理器將此組件的總長度調整爲1高度(無論最小值)。

+0

你真的想爲你的組件提供一個UI,或者你只需​​要重寫'JComponent.paintComponent(Graphics)'?在許多情況下,不會爲特定組件創建UI,因爲這是額外的工作。 – jfpoilpret

+0

這是一個教育性的例子。所以我用這種先進的方式來做。 'c.setBounds(x,y,100,25)'這一行是多餘的。從剪貼板粘貼代碼時,我忘了刪除它。 –

回答

5

永遠不要在繪畫方法中調用setBound()。這是佈局經理的工作,而不是您的繪畫代碼。

我猜想主要問題(除了Heisenbug的觀點)是你不給你一個組件的大小。這是通過重寫getPreferredSize()來返回適合於組件的大小來完成的。

閱讀Swing教程中有關Custom Painting的部分以獲取更多信息和工作示例。

+0

謝謝,原因是:缺少首選大小。 –

5

有幾個問題與您的代碼:

爲了什麼關注類擴展JComponent的:

  1. public void paint(Graphics g, JComponent c) {}

    不是一個有效的簽名這樣你就不會覆蓋方法油漆,但創建一個新的繪畫方法。

  2. 您應該重寫paintComponent(Graphics g)方法而不是paint。

  3. 因爲要擴展一個JComponent您需要重寫的paintComponent方法裏面第一次調用super.paintComponent方法(G):

    public class JPanelExtended{ public void paintComponent(Graphics g){ super.paintComponent(g); ... } }

對於什麼關係擴展的ComponentUI類,你應該即使有顯式調用在超類中的方法漆:

public void paint(Graphics g, JComponent c) { 
    super.paint(g,c); 
} 

編輯: 一點建議:當你想覆蓋的方法,這是非常有用把@override符號簽名之前:

@Override 
public void superMethodToBeOverridden(){} 

這樣,您將通過一個錯誤消息編譯器通知,在案件您正在定義一種新方法,而不是覆蓋現有方法。

+0

你的觀點是不正確的:OP討論'ComponentUI.paint(Graphics,JComponent)',他已經重寫了,而不是'JComponent.paint(Graphics)'。 – jfpoilpret

+0

@jfpoilpret:你說得對。無論如何,對油漆內超級方法的調用仍然有效。我會解決我的答案。謝謝 – Heisenbug

+0

好吧,我明白了。這是調用超級方法的標準。然而,正確的原因是失去了首選的大小。 –