web-dev-qa-db-ja.com

JPanelの機能に関する懸念:paintcomponent()

こんにちは、私はJavaプログラミングの新人です。私はこれらのコード行を説明してくれる人が必要です:

_ public class drawpanel extends JPanel
 {
     public void paintComponent(Graphics g)
     { 
         super.paintComponent(g);
         ...
     }
 }
_

public void paintComponent(Graphics g)という行が理解できません。JPanelで事前定義されている場合、そのような関数を宣言する必要があるのはなぜですか?

そして、この行super.paintComponent(g):まったく理解できません。ご協力ありがとうございました。

19
jose gabriel

基本構造:

extendsキーワードは、DrawPanelJPanelから継承することを意味します。つまり、DrawPanel "is a" JPanelです。そのため、そのメソッド(finalとマークされていないメソッド)をオーバーライドできます。いくつかの理由でそれを実行したい場合があります。たとえば、パネルのGraphicsクラスにアクセスしたい場合があります。これを使用して、パネル、棒グラフ、またはテキストの文字列に円を描くことができます。

メソッドをオーバーライドしない場合、JPanelを拡張すると、次のようになります。

_public class DrawPanel extends JPanel {
    //TODO not much
}
_

ただし、これはあまり役に立ちません...JPanelという名前が気に入らず、代わりにAwesomePanelと呼びたい場合を除きます(注:しないでくださいtそれを行う)。それだけの場合は、次のようにJPanelの-​​instanceを作成することをお勧めします:JPanel drawPanel = new JPanel();


paintComponent:

JPanelを拡張する目的は、paintComponentメソッドをオーバーライドすることです。 JPanelは、paintComponentをオーバーライドするまで非表示です(注:非表示であることは、ボタンやその他のコンポーネントの便利なコンテナになります)。 paintComponentメソッドが事前に定義されている(あなたが疑問に思っている場合はJComponentクラスにある)ことは正しいですが、そのメソッドが行うことはすべて空のJPanelを作成することです。パネルに何かを描画したい場合は、次のようにオーバーライドする必要があります。

_public class DrawPanel extends JPanel {
    @Override public void paintComponent(Graphics g) { // <-- HERE!
        //TODO draw stuff
    }
}
_

注:the_@Override_の部分は厳密には必要ありませんが、減少するため、含めることをお勧めしますランタイムエラーの数とコードの可読性の向上

これで、パネルのGraphicsオブジェクトgにアクセスできます。 Graphicsは、パネルに次のように描画できるヘルパークラスです。

_public class DrawPanel extends JPanel {
    @Override public void paintComponent(Graphics g) {
        g.drawOval(50, 50, 50, 50); // <-- draws an oval on the panel
    }
}
_

super.paintComponent:

役立つメタファー(私が作成したばかり):TheJPanelはキャンバス、theGraphicsオブジェクトはペイントブラシであり、super.paintComponent(g)は消しゴムです。 (また、JFrameはイーゼルです。)

したがって、super.paintComponent(g)は、paintComponentJPanelクラス)のスーパークラスからJComponentメソッドを呼び出し、現在パネルに描画されているものをすべて消去します。 これはアニメーションに役立ちます。

たとえば、パネルにアナログ時計を描くことを検討してください。毎秒更新する必要があるため、毎秒前の時計を消去して時計を再描画し、秒針を調整する必要があります。時計を再描画する前にsuper.paintComponent(g)を呼び出さない場合、古い時計の上に新しい時計が描画され続けるだけで、60秒以内に円で塗りつぶされます。 。

もう1つだけ覚えておかなければなりません。次のように、常にpaintComponentメソッドの最初にsuper.paintComponent(g)を呼び出します。

_public class DrawPanel extends JPanel {
    public void paintComponent(Graphics g) {
        super.paintComponent(g); // <-- HERE!
        g.drawOval(50, 50, 50, 50);
    }
}
_

それでおしまい。自由に連絡してください。


例:

これらの概念を使用して、パネル(フレーム内に配置)にテキストの文字列を表示する簡単な例を作成しました。 IDE as TestPanel.Javaに保存します。

_import Java.awt.*;
import Java.util.*;
import javax.swing.*;

/**
 * A frame containing a panel that is sometimes red and sometimes 
 * blue. Also, it displays the Word to go with it. 
 * 
 * Inspired by www.sometimesredsometimesblue.com.
 *
 */
public class TestPanel extends JPanel {

    private Random random = new Random();
    private boolean isRed;
    private String s = "";

    public TestPanel() {
        //randomly determine whether the background should be red
        isRed = random.nextBoolean();

        //set the background to blue
        setBackground(Color.BLUE);
        s = "BLUE";

        //if 'isRed' is true, set the background to red
        if (isRed) {
            setBackground(Color.RED);
            s = "RED";
        }
    }

    @Override 
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        //write either "RED" or "BLUE" using graphics
        g.setColor(Color.WHITE);
        g.setFont(new Font("serif", Font.BOLD, 60));
        g.drawString(s, getWidth() / 2 - g.getFontMetrics().stringWidth(s) / 2,
                getHeight() / 2 + g.getFontMetrics().getHeight() / 2);
    }

    //main method: create an instance of TestPanel and output it on a JFrame
    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setSize(500, 500);
        f.setTitle("Sometimes Red, Sometimes Blue");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setContentPane(new TestPanel());
        f.setVisible(true);
    }
}_
51
TheBlackKeys

paintComponent() は、元は抽象クラスJComponentで定義されたメソッドです。 JComponentを直接間接的に拡張するコンポーネント(公開されている場合)には、paintComponent()をオーバーライドするオプションがあります。 super.paintComponent(g)の呼び出しは、スーパークラスのpaintComponent()の実装を呼び出します(あなたの場合はJPanelの実装です)。 JPanelがすでに行っている以外に、_Graphics g_で他のことを実行したい場合は、paintComponent()をオーバーライドする必要があります。

2
Bala R

コンポーネントの描画方法を変更したい場合にのみ、クラスでpaintComponent()を定義する必要があります。カスタム実装では、super.paintComponent(g);、つまりpaintComponent()の基本クラスバージョンを呼び出す必要があります。これは、描画用のコンポーネントを準備するために必要な作業を行うためです。

1
pajton