SwingのpaintComponent()メソッドについて

このQ&Aのポイント
  • Swingのコンポーネントでは、paintメソッドの使用は推奨されていません。代わりに、paintComponentをオーバーライドしたクラスのrepaint()メソッドを呼び出すべきです。
  • Swingでは、描画するために継承したクラスでpaintComponent(Graphics g)メソッドをオーバーライドし、Graphicsクラスのメソッドを使用して描画を行います。
  • オーバーライドしたpaintComponentメソッドの先頭で、super.paintComponent(g)を呼び出しておくことで、コンポーネントの土台を描画することができます。
回答を見る
  • ベストアンサー

SwingのpaintComponent()メソッドについて

 JAVA初心者です、宜しくお願いします。  参考書で、Swingについて以下のようなコメントを見つけました、ただ何故そうなのかの理由を書いていません。  以下の内容はどのような理由からそうなるのでしょうか。  「Swing コンポーネントでは、メソッドpaintは推奨されていません。  paintComponentをプログラムから呼び出してはいけません。描画をしたい場合は、 paintComponent をオーバー ライドしたクラスの repaint() メソッドを呼び出します。  Swing コンポーネント上に描画するには、 描画したいコンポーネントのクラスを継承したクラスで、 メソッド paintComponent(Graphics g) をオーバーライドし、 パラメータで渡された g に対して Graphics クラスのメソッドで描画をします。  オーバーライドした paintComponent の先頭で、このコンポーネントの土台を描画するために、 super.paintComponent(g) を呼び出しておきます。」  宜しくお願いします。

  • Java
  • 回答数1
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
noname#94983
noname#94983
回答No.1

Swingでは、コンポーネントの描画はかなり複雑になっている。AWTでは、repaintが呼ばれると、updateが呼ばれた後、paintが呼ばれる。が、Swingでは、paing内で更にpaintComponentによってコンポーネントが描画され、それからpaintBorderでボーダーが描画され、最後にpaintChildrenによって内包するコンポーネントの描画が呼び出される、という仕組みになっている。 したがって、paintをオーバーライドしてしまうとその中で呼ばれる各種描画メソッドが呼ばれなくなり、コンポーネントの描画が正しく行われなくなる可能性がある。このため、何かを描画したい場合には、paint内の、コンポーネント描画のために用意されているpaintComponentをオーバーライドして描画を行う。ただし、これもsuperにメソッドを送るのを忘れると本来の描画が正しくなされないため、かならずsuper.paintComponentしないといけない。 また、このように複雑に描画が行われるため、全体を再描画する場合にはかならずrepaintしないといけない。途中のメソッドを呼び出すと、全体の描画が正しく行われない可能性がある。 要するに、AWTの場合は、paintは描画処理の末端のメソッドであり、「プログラマが勝手に使っていいメソッド」として用意されていて、そこではコンポーネントのクラスでは何も処理が実装されていなかった。ところがSwingでは、paintは末端の何もしていないメソッドではなくなり、その内部でコンポーネントの描画に必要なメソッドの呼び出しなどが細かく実行されるようになった。このために、すべてのメソッドが正しく実行されるように注意してコードを書かないといけなくなった、ということ。やれ、「このメソッドはオーバーライドするな」とか「これは最初にsuperに送れ」とかというのは、すべて「あらかじめ設計されたとおり、描画のためのメソッドが正しい順にすべてきちんと実行される」ようにするためのマナー、ということ。

eiji_0035
質問者

お礼

logger_manさん、有り難うございました、今後とも宜しくお願いします

関連するQ&A

  • paintメソッドについて

    repaintメソッドはpaintをすぐに呼び出すのではなく、イベントが終了するまで再描画されないと聞きました。そこで、イベント中でもpaintを即座に呼び出せるメソッドはないでしょうか? どなたかご回答お願いします。

    • ベストアンサー
    • Java
  • paint()メソッドが呼ばれない

     swingを使って多角形を表示するプログラムを作成しています.polygonクラスを配列に格納して,順番に表示しているのですが,配列中のひとつのpolygonオブジェクトを削除して,再描画を行おうとして,repaint()で一旦画面をクリアして,その後my_paint()で配列中のpolygonを描画させようとしているのですが,    ・  repaint();  my_paint();    ・ my_paint()メソッが呼ばれずに画面がクリアされた状態になってしまいます. どなたか,解決方法をご存知でしたら,ヒントでもいただけるとありがたいです.よろしくお願いします.

    • ベストアンサー
    • Java
  • Swingで別のクラスのrepaintをしたい

    paintメソッドが別のクラスにあるときにrepaint();をしたいのですが、やり方がわかりません。 教えてください。

    • ベストアンサー
    • Java
  • JPanelで宣言したメソッドについて

    JPanelを継承したクラスで、引数をもらってその引数を表示するメソッドを作成します。そして別のJFrameを継承したクラスの中で、さきほど作成したメソッドを利用したいのですが、どうすればできるのでしょうか?そもそもこのやり方できちんと表示されるのでしょうか? ぜひともご教授のほど宜しくお願いします。 以下はプログラムになります。 import java.awt.*; import java.awt.event.*; import javax.swing.*; class Ptest extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("よろしく", 50, 50); } public void draw(String s) { Graphics g = getGraphics(); g.drawString(s, 100, 100); } } class Ftest extends JFrame { JLabel jlb; public Ftest() { setSize(350, 300); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); Container c = getContentPane(); Ptest p = new Ptest(); p.draw("yoroshiku"); c.add(p); p.setLayout(null); jlb = new JLabel("frame"); p.add(jlb); jlb.setBounds(70, 70, 50, 50); } } public class Test1 { public static void main(String[] args) { JFrame w = new Ftest(); w.show(); } }

    • ベストアンサー
    • Java
  •  superについて教えて下さい

     superについて教えて下さい  JAVAの初心者です、宜しくお願いします。  「super」についてよくわかりません。 ある本には、「親クラスのコンストラクタを呼び出す」、またある本には、「親クラスのオブジェクトを呼 び出す」、と書かれていました。  ・コンストラクタとオブジェクトとは同じ意味なのでしょうか。  ・また、ある本には、「コンストラクタの継承はされない」とかかれていますが、どのように違うのでしょうか。  ・JAVAのApIには、次のように書かれています。   「paint     public void paint(Graphics g)コンテナをペイントします。このコンテナの子コンポーネントで    あるすべての軽量コンポーネントへペイント要求を転送します。このメソッドが再実装される場合、軽量    コンポーネントが正しく描画されるように super.paint(g) を呼び出さなければなりません。    (以下略)」   super.paint(g)と各意味は、親クラスのメソッドを呼びだすことで、親クラスのメソッドを呼びだす時に  も、superが必要ということでしょうか。  コンストラクタ自体についてよく理解出来ていないのですが  ・そもそもクラス(オブジェクトの生成)にとってどのような役割、意味があるのでしょうか。   オブジェクトの生成すると、デフォルトで自動的に引数なしのコンストラクタが作成されると書かれています  が、  ・作成されること自体にどのような意味があるのでしょうか。  変数の初期化とかをコンストラクタ内で設定するのは意味があるとは思うのですが、、、、

    • ベストアンサー
    • Java
  • JButtonの画像をactionPerformedメソッド内で再描画

    JButtonの画像をactionPerformedメソッド内で再描画したい。 以下のソースのようにして、再描画したいのです。 setIconメソッドではなく、 JButtonに対して描画したものに対して再描画したいです。 Graphics2DクラスについてJAVA APIで調べましたが、 仕組の理解に至りませんでした。 仕組みと方法を教えて頂きたいです。 よろしくお願いいたします。 import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; public class test extends JFrame implements ActionListener{ JButton b= new JButton(); public static void main(String a[]) { new test(); } public test() { super(); this.setSize(100,100); b.addActionListener(this); b.add(new Zoom(new ImageIcon("img1.jpg"),0,0,50,50)); this.add(b); this.setVisible(true); } class Zoom extends JComponent { private static final long serialVersionUID = 1L; private ImageIcon icon = null; private int x = 0; private int y = 0; private int h = 0; private int w = 0; private double scale = 1.0d; public Zoom(ImageIcon icon, int x, int y, int w, int h) { super(); this.icon = icon; this.x = x; this.y = y; this.w = w; this.h = h; } public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.scale(scale, scale); ////////////////////////////////// //画僧を再描画したい。 //g2.clearRect(0, 0, 80, 80);//× g2.drawImage(icon.getImage(), x, y, w, h, this); } } public void actionPerformed(ActionEvent e) { if(e.getSource()==b){ System.out.print("ok"); //this.repaint();//× //b.repaint();//× b.add(new Zoom(new ImageIcon("img2.jpg"),0,0,50,50));//(再描画できない) //b.setIcon(new ImageIcon("img2.jpg"));//ok(再描画出来る) } } }

    • ベストアンサー
    • Java
  • SwingのアプリケーションでのpaintComponentによる処理について

    javaを学習している者です。 「マウスがクリックされたところを赤い四角を描画して、その前にクリックされて描画されていた赤い四角は同時に消える」という処理を実装したいのですが、うまくできず、赤い四角が残ってしまいます。 プログラムはpaintComponent(Graphics g)の中で、クリックされた場所で赤い四角を描画する処理だけ実装していて、マウスがクリックされるたび、mouseClicked(MouseEvent e)の中でrepaint()を呼ぶ、という風に書いているのですが、どう変えればうまくいくでしょうか? 前に勉強していたアプレットではこのような感じで出来たと思うのですが・・・。 よろしくお願いします。

    • ベストアンサー
    • Java
  • 描画した線や画像などを消す方法。

    アプレットを勉強している初心者です。 イベントであるボタンを押すと、ある数字が描画される、というものを作ったのですがそれを消す方法で悩んでいます。白い正方形で塗りつぶすのかな、と思ったのですが、手元の入門書のコードだとpaintメソッドの中で if(flag != 0){g.drawImage(myImg,0,0,this); と書くだけでそれを実装できているみたいなんです。「画像が出るボタン」を押すとフラグを1にしてrepaint()メソッドでpaintメソッドを呼び出して(?repaintメソッドの説明があまりなくてrepaintメソッドの効果がいまいちよく分かりません)画像を描画して、「消すボタン」を押すとフラグを0にしてrepaint()メソッドを実行してpaintメソッドを呼び出して(?)フラグが0なので結果何もしない。という流れです。 私の感覚だと消すボタンを押してもpaintメソッド内で何もしないなら画像が出たまんまなんじゃないか?と思っているのですが、ちゃんと画像は消えます。 (本当はコードを全部載せられれば一番いいのでしょうが、本に掲載されているコードなのでムリだと思うので載せません) どういうことが起こっているのでしょうか?また一度描画されたものを消す方法はどういう方法があるのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • リスナについて

    Java を勉強している者です GUIライブラリである awt,swing のリスナについての質問です awt,swing では リスナというイベント処理用のクラスと処理内容を用意して その部品に、イベント用のリスナを登録することによって、コールバックする仕組みになっていると思います。 リスナとイベントの対応ですが、マウスリスナやキーリスナ、ボタンを押したときに対応するアクションリスナ などがありますが、多用する再描画に関しての paintListener がありません 再描画に対応する場合、常に部品を継承して、paintcomponent をオーバーライドして記述しなければなりません 再描画も重要なイベントだと思うのですがなぜリスナが用意されてないのか。 JFrame j = new JFrame(); j.addPaintListener( new PaintAdapter { void onPaint() { ... } } のように描画処理を後付できないかという質問です。 できるようならサンプルのコードを教えてください。 またpaintリスナが用意されない理由があればこれも教えていただけると幸いです。

    • ベストアンサー
    • Java
  • repaintがpaintを実行してくれません。

    repaint()をおこなっても、paintが実行される場合とされない場合があります。 なぜですか? repaint()で、paintメソッドに指定した描画を必ず実行させたいのですが、 どうしたら良いのでしょうか?

    • ベストアンサー
    • Java

専門家に質問してみよう