質問: swingのpaintcomponent()メソッドについて java初心者です、宜しくお願いします。 参考書で、swingについて以下のようなコメントを見つけました、ただ何故そうなのかの理由を書いていません。 以下の内容はどのような理由からそうなるのでしょうか。 「swing コンポーネントでは、メソッドpaintは推奨されていません。 paintcomponentをプログラムから呼び出してはいけません。描画をしたい場合は、 paintcomponent をオーバー ライドしたクラスの repaint() メソッドを呼び出します。 swing コンポーネント上に描画するには、 描画したいコンポーネントのクラスを継承したクラスで、 メソッド paintcomponent(graphics g) をオーバーライドし、 パラメータで渡された g に対して graphics クラスのメソッドで描画をします。 オーバーライドした paintcomponent の先頭で、このコンポーネントの土台を描画するために、 super.paintcomponent(g) を呼び出しておきます。」 宜しくお願いします。
回答: swingでは、コンポーネントの描画はかなり複雑になっている。awtでは、repaintが呼ばれると、updateが呼ばれた後、paintが呼ばれる。が、swingでは、paing内で更にpaintcomponentによってコンポーネントが描画され、それからpaintborderでボーダーが描画され、最後にpaintchildrenによって内包するコンポーネントの描画が呼び出される、という仕組みになっている。 したがって、paintをオーバーライドしてしまうとその中で呼ばれる各種描画メソッドが呼ばれなくなり、コンポーネントの描画が正しく行われなくなる可能性がある。このため、何かを描画したい場合には、paint内の、コンポーネント描画のために用意されているpaintcomponentをオーバーライドして描画を行う。ただし、これもsuperにメソッドを送るのを忘れると本来の描画が正しくなされないため、かならずsuper.paintcomponentしないといけない。 また、このように複雑に描画が行われるため、全体を再描画する場合にはかならずrepaintしないといけない。途中のメソッドを呼び出すと、全体の描画が正しく行われない可能性がある。 要するに、awtの場合は、paintは描画処理の末端のメソッドであり、「プログラマが勝手に使っていいメソッド」として用意されていて、そこではコンポーネントのクラスでは何も処理が実装されていなかった。ところがswingでは、paintは末端の何もしていないメソッドではなくなり、その内部でコンポーネントの描画に必要なメソッドの呼び出しなどが細かく実行されるようになった。このために、すべてのメソッドが正しく実行されるように注意してコードを書かないといけなくなった、ということ。やれ、「このメソッドはオーバーライドするな」とか「これは最初にsuperに送れ」とかというのは、すべて「あらかじめ設計されたとおり、描画のためのメソッドが正しい順にすべてきちんと実行される」ようにするためのマナー、ということ。