2012-10-06 104 views
6

我有一個擴展JComponent的自定義組件,它覆蓋了paintComponent(Graphics g)方法,但是當我嘗試將它添加到我的JPanel中時,它不起作用,什麼也沒有繪製。 這裏是我的代碼:JComponent not to JPanel

public class SimpleComponent extends JComponent{ 

int x, y, width, height; 

public SimpleComponent(int x, int y, int width, int height){ 
    this.x = x; 
    this.y = y; 
} 

@Override 
public void paintComponent(Graphics g){ 
    Graphics2D g2 = (Graphics2D) g; 
    g2.setColor(Color.BLACK); 
    g2.fillRect(x, y, width, height); 
} 
} 


public class TestFrame{ 
public static void main(String[] args){ 
    JFrame frame = new JFrame(); 
    JPanel panel = new JPanel(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    panel.setPreferredSize(new Dimension(400, 400)); 
    frame.add(panel); 
    frame.pack(); 
    frame.setResizable(false); 

    SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
    panel.add(comp); 
    frame.setVisible(true); 
} 
} 

回答

4

它工作正常 - 組件被添加到JPanel的,但有多大呢?如果選中該圖形用戶界面已經呈現後,你可能會發現,你的組件的大小爲0,0。

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
panel.add(comp); 
frame.setVisible(true); 

System.out.println(comp.getSize()); 

請考慮您的JComponent覆蓋getPreferredSize並返回一個維度是有道理的:

public Dimension getPreferredSize() { 
    return new Dimension(width, height); 
} 

如果您想使用x和y,您也可以優先重寫getLocation()

編輯
您還需要設置寬度和高度字段!

public SimpleComponent(int x, int y, int width, int height) { 
    this.x = x; 
    this.y = y; 
    this.width = width; // *** added 
    this.height = height; // *** added 
} 
+0

這真的很奇怪,我在windows和mac上覆制了這個問題,它總是一模一樣 – lilroo

+0

啊,寬度和高度都設置爲零 – lilroo

+0

記住設置寬度和高度字段後仍然不起作用,但當我重寫了它的getPreferredSize()方法。 – lilroo

-2

Whoaa!絕對不是正確答案!

第一個絕對CARDINAL SIN你已經承諾的是在非EDT線程中做所有這些!這裏沒有空間來解釋這個......網絡上只有大約300億個地方可以瞭解它。

一旦所有這些代碼是在Runnable在EDT(事件指派線程)執行的,則:

需要重寫preferredSize(雖然你可以的,如果你想)......但你確實需要設置它。

你絕對不應直接設置大小(heightwidth,或setSize())!

做什麼需要做的是讓java.awt.Containerpanel,在你的榜樣,「放棄自己了」 ......還有一個方法Container.doLayout(),但因爲它說的API文檔中:

導致此容器佈置其組件。大多數程序應該不會直接調用此方法,而應該調用驗證方法 。

解決方案因此:

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
comp.setPreferredSize(new Dimension(90, 90)); 
panel.add(comp); 

// the key to unlocking the mystery 
panel.validate(); 

frame.setVisible(true); 

順便說一句,請從我的經驗中獲益:我花了幾個小時撕裂我的頭髮試圖瞭解這一切的validate, invalidate, paintComponent, paint等東西......和我仍然覺得我只是抓了表面。

+0

請參閱http://stackoverflow.com/questions/10866762/use-of-overriding-getpreferredsize-instead-of-using-setpreferredsize-for-fix?rq=1 –

+0

好的謝謝...但如果你是這個人誰在這裏低估了我的答案,這對於未來的訪問者來說並不是很有幫助:我的答案遠遠好於接受的答案,並且關於'setPreferredSize' /'getPreferredSize'的細微差別沒有改變。 –

+0

哦......我知道你是接受答案的回答者!但是有了214k的代表,你一定知道我說的每一點都是對的,而且你的答案是真的,呃,我該怎麼說呢,留下了改進的餘地! –