Componentのサイズ指定
http://java.sun.com/docs/books/tutorial/uiswing/layout/problems.html
ContainerでLayoutManagerを使っている場合で、そのContainerにaddするComponentのサイズを明示的に指定したい場合、
ComponentのsetMinimumSize, setPreferredSize, setMaximumSize に同じサイズを指定する。setSizeはLayoutManagerによって呼び出される(と思われる)ので、使っても上書きされてしまう。
明示的にサイズを指定した後に、自動計算されるサイズを有効にしたい場合は、setXxxSizeにnullを指定する(経験則)。
すでに表示されているComponentのサイズを変更した場合、そのrevalidateを呼んで、再レイアウトさせる。さらに、Componentのrepaintも呼ぶ。
レイアウトマネージャなしでレイアウト(絶対位置指定)
http://java.sun.com/docs/books/tutorial/uiswing/layout/none.html
レイアウトマネージャを作る
http://java.sun.com/docs/books/tutorial/uiswing/layout/custom.html
addLayoutComponent(String, Component) は、Container#add(String, Component)が呼ばれる場合に呼ばれ、Container#add(Component)が呼ばれた場合には呼ばれない。
layoutContainer(Container) が呼ばれたときは、レイアウト対象のComponent(Containerが持っているComponent)を取得する必要があるが、取得にはContainer#getComponents()を使うのが基本のようだ。
addLayoutComponent(String, Component)で得られたComponentをLayoutManagerで覚えておいてlayoutContainerで使うような処理にすると、Container#add(Component)されたComponentについては漏れてしまう(開発するLayoutManagerの仕様がadd(String,Component)必須とするのであれば、それでも問題なさそうだが。)
revalidate, invalidate, validate
- Componentを追加したら(そのComponentの?)revalidateとrepaintを呼ぶと、Containerに表示されるようになる。
http://java.sun.com/docs/books/tutorial/uiswing/layout/problems.html
- Componentのサイズが変わった場合(サイズ変更、フォント変更など)、そのComponentのrevalidateとrepaintを呼び出す必要がある。
http://java.sun.com/docs/books/tutorial/uiswing/layout/howLayoutWorks.html
- 表示中のContainerのadd/removeを呼び出したら、そのあとでContainerのvalidateを呼び出す必要がある。
(APIリファレンスのContainer#add, Container#removeの説明より)
- 表示中のContainerのremoveを呼び出し、さらにvalidateを呼び出しても表示に反映されない場合は、そのContainerのrepaintを呼び出すと反映される場合がある(経験)
- Componentのrevalidateを呼び出すと、コンテナ内容物階層構造の上に向かってその要求が伝達される。その伝達は、scroll paneやトップレベルコンテナなど、Componentのサイズ変更の影響を受けないContainer (ContainerのisValidateRootメソッドを呼び出して決まる) に出会うまで続く。そして、そのContainerはレイアウトされる。その結果として、revalidateされたComponentと、それに影響を受けるComponentのサイズが調整される。
http://java.sun.com/docs/books/tutorial/uiswing/layout/howLayoutWorks.html
ここまでの話ではinvalidateが出てこない。Component/Containerの利用者がinvalidateを使う必要はない??
paint, repaint, update
http://java.sun.com/products/jfc/tsc/articles/painting/index.html
AWTの場合
- 再描画を要求するときはreapintを呼べ
- 描画処理はpaintに書け
- リンクリメンタル描画(とは?)をしたければupdateをオーバーライドせよ
- Conteiner継承クラスでpaintをオーバーライドしたら、そのpaintでsuper.paint() を必ず呼べ
動作
- プログラムからの描画要求(repaint)があると、updateが呼ばれ、updateからpaintが呼ばれる
- システム(OS)からの描画要求があると、(updateなしに)paintが呼ばれる
Swingの場合
- 再描画を要求するときはreapintを呼べ
- 描画処理はpaintで実施されるが、paintからpaintComponent, paintBorder, paintChildrenが呼ばれるため、paintComponentに描画処理を書け
- paintComponentからはsuper.paintComponentを呼べ (UI delegateを持ったSwing componentの場合(JPanel含む))
動作
- updateは呼ばれない