2012-10-06 31 views
6

paintComponent(Graphics g)のメソッドをオーバーライドするJComponentを拡張するカスタムコンポーネントがありますが、これをJPanelに追加しようとするとJPanelが機能しないだけで何も描画されません。ここ は私のコードです:JComponentが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に追加されているが、それはどのように大きなですか? GUIがレンダリングされた後にこれをチェックすると、あなたは、コンポーネントのサイズが0である可能性があります、0

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

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

は、JComponentがgetPreferredSizeメソッドをオーバーライドし、理にかなっているDimensionを返すことを検討:

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!絶対に正しい答えではありません!

最初の絶対カーディナルSINあなたがコミットしたのは、EDT以外のスレッドでこれを行うことです!これについてここで説明するスペースはありません。それについて知るには約300億の場所しかありません。

すべてこのコードは、その後、EDT(イベントディスパッチスレッド)にRunnableに実行されたら:

(必要に応じことができますが)あなたはpreferredSizeをオーバーライドする必要はありません...しかし、あなたはそれを設定する必要があります。

あなたは絶対には直接サイズ(heightwidth、またはsetSize())を設定しないでください!あなたがする必要性をDO

は方法Container.doLayout()がある... java.awt.Containerpanelは、あなたの例では、「自分自身をレイアウト」してもらうことですが、それは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の担当者は、私が述べたすべての点が正しいことを本当に知っていなければなりません。本当にあなたの答えは、どうすればよいでしょうか? –

関連する問題