以前の記事で新たに MVC グループを生成する方法を見ましたが、今回はその逆に、既に存在する MVC グループを破棄する方法を見ていきます(一覧)。
関数描画アプリケーション
関数描画アプリケーションに組み込む機能としては、各 functionPanel パネル(関数式を入力する部分)にボタンをつけて、クリックするとそのパネルが削除されるようにします:
メッセージ・ダイアログは mvcGroupDestroy() メソッドの使い方のために(無理矢理)入れているだけです。 機能としては不必要*1。
コードを追加する(リ)ソースは以下のものです:
- FunctionPlotter/griffon-app/views/functionplotter/MonolineFunctionView.groovy
- FunctionPlotter/griffon-app/resources/function/remove.png
- FunctionPlotter/griffon-app/controllers/functionplotter/MonolineFunctionController.groovy
- FunctionPlotter/griffon-app/controllers/functionplotter/FunctionPlotterContoller.groovy
MonolineFunctionView.groovy
まずは MonolineFunctionView。 これに施す変更は
- 関数を削除する「Remove」アクションの追加
- 「Remove」アクションのトリガーとなる「Remove」ボタンの配置
です。 これらはまぁ、普通の View の実装です:
package functionplotter actions{ action(id:'remove', name: 'Remove', closure: controller.remove) } panel(id:'content', border:titledBorder(title:'Groovy')){ migLayout() toolBar(constraints:'north'){ this.button action:remove, hideActionText:true, icon:imageIcon('/function/remove.png') } label text: bind{ model.name } label '=' textField 'sin(x)', columns:15, action:paint, text: bind(target:model, 'function') }
- 「Remove」ボタンはツールバーに作成してみました。 アイコンの設定はアクションにした方がいい気もしますが、イマイチ動かなかったので「Remove」ボタンの位置にて設定。
- アイコンの画像は「FunctionPlotter/griffon-app/resources/function/remove.png」に配置。 アイコンはこんな感じに作成 →
MonolineFunctionController.groovy
さて次は、先ほど定義した「Remove」アクションの処理を Controller に実装しましょう(もちろん MonolineFunctionController)。
ここでの処理で、対象となっている「MonolineFunction」 MVC グループのインスタンスを破棄したいのですが
- FunctionPlotterController の functionModelList フィールドから、破棄したい MVC グループの Model を削除する
- FunctionPlotterView の functionPanel パネルから 、破棄したい MVC グループの View を削除する
という処理が必要なので、「Remove」処理は FunctionPlotterController に投げることにしましょう。 処理を投げるメソッドは removeFunction() とします(後ほど実装)。
package functionplotter import javax.swing.JOptionPane class MonolineFunctionController { def model def view String mvcName def remove = { evt = null -> app.controllers.FunctionPlotter.removeFunction(mvcName) } void mvcGroupDestroy(){ JOptionPane.showMessageDialog(app.windowManager.windows[0], "Function $mvcName(x) is removed.") } }
- mvcName プロパティは、この MVC グループを生成したときに指定した groupId です(createMVCGroup() メソッドに渡した第2引数 )。 これは、破棄する MVC グループを特定するために、FunctionPlotterController#removeFunction() メソッドに引数として渡します。 ちなみに、この mvcName プロパティは値が自動で注入されます*2。
- FunctionPlotterController オブジェクトは、「app.controllers.FunctionPlotter」によって取得しています。 「FunctionPlotter」MVC グループは1つしかインスタンスがないので、これでも取得できます。
- mvcGroupDestroy() は、この MVC グループが破棄される際に呼ばれます(mvcGroupInit() と対照的)。 ここでは、削除された関数の名前を表示しています。
FunctionPlotterController.groovy
最後は MVC グループの破棄を行う FunctionPlotterController#removeFunction() メソッドの実装。 最後に destroyMVCGroup() メソッドを呼び出して MVC グループを破棄します。 一度破棄するとそのグループのメンバを参照できないので、その前に不必要な参照を削除しておきます:
package functionplotter class FunctionPlotterController { def model def view private List functionModelList = [] as LinkedList def removeFunction(String mvcName){ def group = app.groups[mvcName] if(!group)return // Model を削除 this.functionModelList.remove(group.model) // View を削除 this.view.with{ functionPanel.remove(group.view.content) controlPanel.updateUI() } // MVC グループを破棄 destroyMVCGroup(mvcName) } }
- mvcName (MVC グループの groupId)から、MVC グループを取得するためには「app.groups[mvcName]」とします。 この返り値は MVC グループのメンバを含んだ Map オブジェクトになっていて、'model', 'view', 'controller', 'builder' をキーに、グループのメンバにアクセスできます。
- destroyMVCGroup() メソッドの引数には MVC グループの groupId を指定します(「関数描画アプリケーション」の例では 'f' や 'g' など)。 'MonolineFunction' などの名前ではありません。
これにて破棄処理の実装は完了。 removeFunction() メソッドの最後に destroyMVCGroup() メソッドを呼ばなくても実際には動きますが、2度と使用されない MVC グループのインスタンスがメモリ上に残ったままになるので好ましくありません。 いらない MVC グループはきちんと破棄しましょう。
- 作者: Andres Almiray,Danno Ferrin,James Shingler
- 出版社/メーカー: Manning Pubns Co
- 発売日: 2012/06/28
- メディア: ペーパーバック
- クリック: 8回
- この商品を含むブログ (19件) を見る
*1:というより、アプリケーション自体を終了すると、残っている functionPanel パネルの個数だけダイアログが表示されて鬱陶しくなります ^ ^;)
*2:「はじめての幻獣 Griffon 研 (26) : マルチ MVC への道 (3) : アプリケーション開始時に MVC グループを作成し、ビューを埋め込む createMVCGroup / mvcGroupInit」参照。