Java.use(better); Episode#21 ファインダーを作成する
┃開け胡麻:ツリーを作成する
まず、ファイルシステムが扱う情報を提示できるコンポーネントが必要です。ところが、パッケージ scala.swing には、javax.swing.JTree に相当するものが用意されていません。多くの Swing コンポーネントが、Scala でも利用できるようになっていますが、これは例外のひとつです。
□ 既存のリソースを再利用する
そこで「ツリーを作成する」ことから始めます。と言っても、それほど難しい作業ではありません。というのも、既存の Swing コンポーネントを再利用するための枠組が、すでに用意されているからです。
18: import swing._ 19: class TreeView extends Component { 20: import javax.swing.JTree 21: override lazy val peer: JTree = new JTree with SuperMixin 22: 23: import javax.swing.event._ 24: peer.getSelectionModel.addTreeSelectionListener( 25: new TreeSelectionListener { 26: def valueChanged(e: TreeSelectionEvent) { 27: publish(new TreeSelectionChanged(TreeView.this)) 28: } 29: }) 30: } 33: object TreeSelectionChanged { 34: def unapply(e: TreeSelectionChanged): Option[(TreeView)] = 35: Some((e.source)) 36: } 37: import swing.event._ 38: class TreeSelectionChanged(override val source: TreeView) 39: extends SelectionChanged(source)
[19]javax.swing.JTree に相当するものを TreeView と命名します。そして、この新たなコンポーネントを Component の傘下に用意します。というのも、既存のパッケージ scala.swing は、それを前提に作成されているからです。この Component を再利用すると、新たに記述すべきコードの量を削減できます。
[21]変数 peer もその枠組のひとつです。両者 scala.swing/javax.swing は、DNA の二重螺旋のように独立した階層構造を保ちながらも、相互に情報を交換したいときには、peer を介して、Scala から Java のリソースにアクセスできます。また、with SuperMixin を指定するだけで、各コンポーネントを再描画するための機能が付加されます。さらに、lazy 宣言をしておくと、TreeView へのアクセスが必要になるまで、JTree を生成するのを遅延できます。
□ イベントを処理する
新たなコンポーネントを作成するときには、イベント処理が欠かせません。このとき、「情報隠蔽の原則」に沿って、利用者(プログラマー)には必要な情報だけを開示して、それ以外の情報を隠蔽するのが、作成者(プログラマー)に課せられた責務です。それを体現したのが、後述する TreeSelectionChanged です。
[24-29]リスナーを登録しておくと、ツリー項目を選択したときに発生するイベントに呼応できます。イベントが発生すると、メソッド valueChanged の本体にあるコードの断片を実行します。このとき、メソッド publish の引数を介して、イベントが発生したコンポーネント TreeView.this にアクセスできます。
[33-36]オブジェクト TreeSelectionChanged では、コンストラクターパターンの動作を規定するメソッド unapply を用意して、イベントが発生したコンポーネント e.source を特定するための情報を提供します。
☞ 余録:match 式とポリモフィズム
[38-39]クラス TreeSelectionChanged では、既存のケースクラス SelectionChanged を拡張するだけで、パターンマッチングに必要な仕掛を再利用できます。
》作業中です《
↑ TOP