7

メソッド paintComponent(Graphics g) をオーバーライドする 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

2 に答える 2

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
}
于 2012-10-06T11:17:08.610 に答える
-2

おっ! 絶対に正しい答えではありません!

あなたが犯した最初の絶対的な大罪は、これらすべてを EDT 以外のスレッドで行うことです!!! これについてここで説明するスペースはありません... ネット上には約 300 億の場所しかありません。

このコードがすべてRunnableEDT (イベント ディスパッチ スレッド) で実行されると、次のようになります。

オーバーライドする必要はありませ(ただし、必要に応じてオーバーライドpreferredSizeできます)...ただし、設定する必要があります。

サイズ (および、または) を直接設定しないでくださいheightwidthsetSize()

あなたがする必要があるのはjava.awt.Containerpanelあなたの例では、「それ自体をレイアウトする」ことです...メソッドがありますContainer.doLayout()が、APIドキュメントに記載されているように:

このコンテナにそのコンポーネントをレイアウトさせます。ほとんどのプログラムは、このメソッドを直接呼び出すべきではなく、代わりに validate メソッドを呼び出す必要があります。

したがって、解決策は次のとおりです。

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...そして、私はまだ表面を傷つけただけだと感じています.

于 2016-02-18T19:27:57.297 に答える