今回は関数描画アプリケーションの Controller の部分を作成します(一覧)。
コントローラの分析
コントローラに定義する処理は前々回の「アクションの分析」で列挙してました。
名前 | 説明 | 実装 |
---|---|---|
Paint | グラフを描画する | controller.paintGraph |
About | 説明を表示する | controller.showAbout |
FunctionPlotterController 概要
次は実装。 ソースファイルは
- FunctionPlotter/griffon-app/controllers/functionplotter/FunctionPlotterController.groovy
です。 生成されたソースコードは以下のようになっています:
package functionplotter class FunctionPlotterController { def model def view }
model, view フィールドにはそれぞれ FunctionPlotterModel, FunctionPlotterView のインスタンスが自動的に設定されます。
showAbout の処理
まずは簡単そうな About アクションから。 処理はメソッドとしても実装できますが、Closure 型のプロパティとして定義する方が普通なようです。
package functionplotter import javax.swing.JOptionPane class FunctionPlotterController { def model def view def showAbout = { evt = null -> JOptionPane.showMessageDialog(app.windowManager.windows[0], '''A Function Plotter that serves as a SwingBuilder example for Groovy in Action''') } }
- controller から view を構築するビルダーをどうやって参照するのか分からなかったので(たぶんそんなに難しくないかと思うけど)、JOptionPane を直接使ってメッセージダイアログを表示しています。
- view では javax.swing パッケージのクラスは自動インポートされますが、controller ではそうではないので、JOptionPane のインポートもしています。
- メッセージダイアログを表示させるためには親ウインドウが必要ですが、Griffon アプリケーションのルートウインドウは app プロパティから辿って取得できるようです:
app.windowManager.windows[0]
paintGraph の処理
次は paintGraph の処理。 まずは関数式を表す文字列を Script オブジェクトに変換して、式評価も行う Dynamo クラスを定義。 これは FunctionPlotterController.groovy に直接書いていいでしょう*1:
class Dynamo{ static final GroovyShell SHELL = new GroovyShell() Script functionScript Dynamo(String function){ this.functionScript = SHELL.parse('import static java.lang.Math.*;'+function) } Object f(x){ functionScript.x = x return functionScript.run() } }
- java.lang.Math クラスに定義されている static メソッド(で表される関数)を簡単に使えるように、ビューのテキストフィールドに入力された式(文字列)に 'import static java.lang.Math.*;' を付け加えて評価するようにしています(特に必要な処理ではありませんが)。
これを踏まえて paintGraph 処理の実装を。
package functionplotter import java.awt.Color class FunctionPlotterController { def model def view def paintGraph = { evt = null -> def calc = new Dynamo(model.function) def canvas = view.canvas def g = canvas.graphics int w = canvas.size.width int h = canvas.size.height g.color = new Color(255, 255, 150) g.fillRect(0, 0, w, h) g.color = Color.BLUE def dx = (model.to - model.from) / w def dy = h / (model.max - model.min) int ceiling = h + model.min * dy int lastY = calc.f(model.from) * dy for(x in (1..w)){ int y = calc.f(model.from + x * dx) * dy g.drawLine(x-1, ceiling - lastY, x, ceiling-y) lastY = y } } def showAbout = { evt = null -> // ... } }
- 処理内容は『Groovyイン・アクション』 Chapter 8 の関数描画アプリケーションに載ってるのと基本的に同じです。 ローカル変数はちょっと名前変えてますが(必ずしも適切な名前ではありませんが、短くして見やすくするため)。
- モデルに定義した変数(function, from など)を使用する際は、model のプロパティとして参照します(model.function, model.from など)。
- ビューに定義したコンポーネントは、ビューに id を指定して(panel(id:'canvas') など)、view のプロパティとして参照します(view.canvas など)。
- 時間のかかりそうな処理は doLater{} や doOutside{} などを使って別スレッドで実行した方がよいようですけど、まぁここでは気にしないことに。
これでとりあえず MVC は実装完了。
- 作者: Dierk Konig,Andrew Glover,Paul King,Guillaume Laforge,Jon Skeet,杉浦孝,櫻井正樹,須江信洋,関谷和愛,佐野徹郎,寺沢尚史
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2008/09/27
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 146回
- この商品を含むブログ (121件) を見る