S-JIS[2011-01-15] 変更履歴
ScalaのSwingで単純なウィンドウアプリを作成するのに便利なのがSimpleSwingApplicationクラス。
main()メソッドを持っているので、このクラスを継承したオブジェクトを作ればウィンドウアプリとして実行できる。
なお、GUIApplication(SimpleGUIApplication)というクラスもあったようだが、非推奨になっている。
単純にウィンドウを表示するサンプル。
import scala.swing.{Label, MainFrame, SimpleSwingApplication} object Sample0 extends SimpleSwingApplication { def top = new MainFrame { title = "サンプル" contents = new Label("Swingの実験です!") } }
Windowsで実行すると、外観(Look&Feel)が自動的にWindowsになるようだ。
ちなみにこれをREPL上で実行する(「Sample0.main(Array())
」で実行できる)と、ウィンドウを閉じた時にREPL自体も終了してしまう^^;
MainFrameは閉じられたときにSystem.exit(0)で終了するから。
topは、SimpleSwingApplicationの中で宣言されている抽象メソッド。
それを自分のクラスで実装している。
「new MainFrame」はMainFrameクラスのインスタンス生成で、
後ろにとげ括弧「{}
」が付いていることにより、MainFrameを拡張したクラス(無名クラス)となっている。
(とげ括弧内はコンストラクター)
title・contentsへの代入は、MainFrameのメソッド呼び出し。
titleで言えば、MainFrameの中(具体的には親トレイトであるRichWindowの中)で「title_=(s: String)
」というメソッドが定義されている。
Scalaでは「_=」で終わる名前のメソッドは、フィールドの代入のような書き方が出来る。したがって「title
= 〜
」という書き方が出来るが、これは「title_=(〜)
」というメソッド呼び出しとなる。
contentsも同様。
ScalaのSwingはこの文法によって初期化する思想のようだ。
SimpleSwingApplicationの親クラスはSwingApplicationであり、以下のようなコードになっている。
abstract class SwingApplication extends Reactor { def main(args: Array[String]) = Swing.onEDT { startup(args) } def startup(args: Array[String]) def quit() { shutdown(); System.exit(0) } def shutdown() {} }
見ての通り、main()メソッドがある。ので、このクラスを継承したオブジェクトはここから実行される。
中身はSwingオブジェクトのonEDTメソッド(event
dispatching threadを使用する)を介したstartup()メソッドの呼び出し。
startup()メソッドはSwingApplicationでは抽象メソッドとして定義されており、
実体はSimpleSwingApplicationにある。
SimpleSwingApplicationは以下のようなコード。
abstract class SimpleSwingApplication extends SwingApplication { def top: Frame override def startup(args: Array[String]) { val t = top if (t.size == new Dimension(0,0)) t.pack() t.visible = true } 〜 }
topが抽象メソッドで、これをプログラマーがオーバーライドしてフレームを定義する。
ちなみにstartup()の中身は、
そのフレームにサイズ指定が無ければpack()(Javaのpack())して、
visibleをtrue(JavaのsetVisible(true))にすることによってウィンドウを表示する
という実装になっている。