Swingそれは「バットを振ること」。ではありません。
SwingはJava、JavaといえばSwing的なイメージがある方は多いかと思います。Swingを使うとそれっぽいアプリケーションが簡単に作れます。
しかし、SwingはJava上で動くひとつのソフトウェアライブラリに過ぎません。しかもUIが充実する一昔前に作られたものです。なのでちょっと、時代遅れ感が否めませんし、実際、あって当然のような機能がなかったりして残念な場合が結構あります。次世代Swingである「SwingX」なるものがあるようですが、正式版としてのリリースはまだ先の話になりそうです。
さて本題ですが、Swingはメインの普段私たちがコーディングして、動作させているスレッドとは別のスレッドで動いていることをご存知でしょうか。スレッド起動のタイミングこそ知りませんが、別スレッド動いているということを意識するのと、しないのとでは大分、コーディングの仕方に差がでるのではないかと思います。また、Swingはスレッドセーフではないとのことなので、無茶な割り込みをされると、動作が保障できないようです。なので、Swingを扱う処理と、それ以外の処理は別のスレッドが行うのが適切ということになります。Swingを扱うスレッドはEDT(EventDispatchThread)と呼ばれています。
適切なSwingの扱い方
SwingUtilities.invokeLater()を使ってください。ただそれだけなんです。
SwingUtilities.invokeLater()を使ってください。ただそれだけなんです。
使い方はRunnableをimplementsするかThreadを継承して、runメソッドを実装し、そのインスタンスをSwingUtilities.invokeLater()に渡してあげます。
こうすることで、Swing処理を渡した順番どおりにやってくれます。要は先入れ先だしでスタックが詰まれているわけです。
注意すべきことは、Swingの処理にまぜて、Swingに関係ない処理をさせないことです。Swingはシングルスレッドで動いていますので、関係ない処理がものすごい時間を喰う処理だった場合、その処理をしている間、Swingは応答しないことになります。例えば、でっかい画像を読み込む処理をEDTで開始後、やっぱキャンセルしよう!と判断して、キャンセルボタンを押そうにもSwingは画像を読み込む処理に必死なので、反応できません。ちょっとしたハングアップが起こることになります。こういうことはユーザにとっては悪です。