JavaのSwingによる描画について調べてみたところ、こんなに良い記事がありました。
Painting in AWT and Swing
ここにSwingを使うときのガイドラインがありましたので、意訳して紹介しておきます。
- Swingの描画ではAWTとは異なり常にpaintメソッドが使われる(updateメソッドは呼び出されない)
- paintメソッドを直接呼ばないで、repaintメソッドを呼ぶこと
- 複雑な描画処理をする場合は影響範囲を限定するために、パラメータつきのrepaintメソッド(たとえば public void repaint(int x, int y, int width, int height)など)を呼ぶこと
- Swingの描画はpaintComponent()、paintBorder()、paintChildren()を順番に呼び出すので、Swingコンポーネントを拡張(extends)する場合には、独自の描画コードはpaintComponentメソッドにコーディングすること(paintメソッドにはコーディングしない)
- Swingには描画の効率に影響する2つのプロパティ、opaque(コンポーネントのすべての点を描画するかしないか)とoptimizedDrawingEnabled(子コンポーネントの重なりがあるか否か)があるので適切に使用すること(getter, setter が用意されている)
- Swingコンポーネントのopaqueがtrueに設定されたときはこのコンポーネントの境界内で描画されていた背景はすべて上書きされる
- opaque かoptimizedDrawingEnabled のどちらかにfalseが設定されたときは、描画操作に対してより多くの処理が必要になるので、適切な設定をするように気をつけること
- UI delegatesをもつSwingコンポーネント(JPanelを含む)を拡張(extends)する場合には、paintComponent()の実装の最初にsuper.paintComponent()を呼び出すこと
- SwingはJComponentのdoubleBufferedプロパティでダブルバッファリングを簡単に利用できるようになっており、すべてのSwingコンポーネントでこのプロパティは有効になっていますが、Swingコンテナでこの値をtrueにすると個々の設定を無視してすべてtrueになる
- すべてのSwingコンポーネントについてダブルバッファリングは有効にすることを強く推奨する
- 複雑な描画をするComponentでは描画対象領域を狭めるためにクリップ領域の指定を上手に利用すること