20

JPanel をサブクラス化して paintComponent(Graphics) を上書きします。jframe の jpanel に画像を描画したいと考えています。

しかし、jframe のサイズを変更するまで、私の画像は表示されません。これは私のコードです:

public class ImagePanel extends JPanel{

    public void setImage(BufferedImage bi)
    {
        image = bi;
        revalidate();
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if(image != null)
        {
            g.drawImage(image, 0, 0, this);
        }
    }
}
4

5 に答える 5

21

この関連で説明されているように、コンポーネントを追加して を呼び出しsetVisible() た後に呼び出していることを確認してください。また、適切なレイアウトを採用する必要がある場合もあります。ここで提案されているようにを呼び出すと、症状は解決するかもしれませんが、根本的な原因は解決しないかもしれません。pack()repaint()

于 2012-06-17T16:52:37.607 に答える
8

から継承するのドキュメントを見てください。JPanel.add()java.awt.Container

指定されたコンポーネントをこのコンテナーの末尾に追加します。これは addImpl(java.awt.Component, java.lang.Object, int) の簡易メソッドです。このメソッドは、レイアウト関連の情報を変更するため、コンポーネント階層を無効にします。コンテナーが既に表示されている場合は、追加されたコンポーネントを表示するために、その後階層を検証する必要があります。

強調が追加されました。

したがって、コンテナが表示された後にコンテナを変更する場合は、コンテナを表示するために呼び出す必要があります。validate()呼び出すだけrepaint()では不十分です。setVisible(true)呼び出しも機能することに気付いたかもしれません。これは、内部的に呼び出すvalidate()ためです。

于 2015-08-22T11:34:40.097 に答える
8

JPanel を「リフレッシュ」したい場合は、repaint() を呼び出す必要があります。これにより、paintComponent() が呼び出されます。これで問題が解決するはずです:

public void setImage(BufferedImage bi)
{
    image = bi;
    EventQueue.invokeLater(new Runnable()
    {
        public void run()
        {
            repaint();
        }
    });
}

EDT を使用して GUI を更新および変更することをお勧めします。興味のある方は、EDT に関する詳細情報をご覧ください。

イベントディスパッチスレッドはどのように機能しますか?

repaintEDT から呼び出す必要はありません。テキストを JLabel に設定するなど、GUI を変更する場合は、EDT 内にある必要があります。EDT の外部で何を呼び出すことができるかについての詳細情報を次に示します (nIcE cOw の厚意による)。

EDT 外で Component.repaint() を使用しても安全ですか?

于 2012-06-17T08:20:01.790 に答える
1

私も同じ問題を抱えていましたが、解決策を見つけました。jframe上部にオブジェクトを作成し、そのフレームに追加されたすべての UI の下部に 、 、 のようなメソッドを呼び出すだけで、うまくjframe機能することがわかります。jf.pack()jf.setVisible()jf.setSize()jf.setDefaultCloseOpetion()

于 2018-06-01T02:04:04.580 に答える