vieweditattachhistorytopchangessearchhelp

第73回


■SqueakではじめるSmalltalk入門   第73回  鷲見 正人


本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、製作途上の簡易GUIビルダで、テキストフィールドだけでなく、プッシュボタンも追加できるように拡張します。

▼メニュー項目の追加
まずは変化が見えやすいところから始めましょう。GUIビルダウインドウのウインドウメニューに手を入れます。ブラウザの右上のペインから「addModelItemsToWindowMenu:」をクリックして選択し、下のペインに表示されたその内容を次のように変更してください。

addModelItemsToWindowMenu: aMenu
  | window |
  window := aMenu defaultTarget.
  aMenu addLine.
  aMenu add: 'add field' target: self selector: #addFieldTo: argument: window.
  aMenu add: 'add button' target: self selector: #addButtonTo: argument: window.
  aMenu addLine.
  aMenu add: 'delete' target: self selector: #removeWidgetFrom: argument: window


ボタンを追加するためのメソッド名を#addButtonTo:とあらかじめ決めてしまい、それを起動するメニュー項目「add button」を追加する行を「addfield」の行の直下に挿入しています。accept(cmd + S)してコンパイルが済むと、GUIビルダウインドウのメニューには、記述通り「add button」という項目が現われます。

[fig.A]追加された「add button」コマンド
Uploaded Image: 73a.png

ただ、もちろん現時点では、このメニュー項目を選択しても起動するメソッド
が見つけられずエラーになります。

[fig.B]起動するメソッドが存在しないため起こるエラー
Uploaded Image: 73b.png


▼ボタン追加のためのメソッドの定義
テキストフィールド(a PluggableTextMorph)をGUIビルダウインドウに追加するためのメソッドは次のようなものでした(GUIビルダをブラウズ中のブラウザで、右上のペインの「addFieldTo:」をクリックすると呼び出せます)。

addFieldTo: window
 | field relFrame |
 field := PluggableTextMorph
   on: self text: nil accept: nil readSelection: nil menu: nil.
 relFrame := (Rectangle fromUser
   scaleFrom: window layoutBounds
   to: (0 asPoint extent: 1e3 asPoint)) scaleBy: 1.0e-3.
 window addMorph: field frame: relFrame


これにちょっと手を加えるだけで、新たに#addButtonTo:を簡単に作ることができます。

Smalltalkのメソッド定義の最初の行は「メッセージパターン」と呼ばれ、このメソッドを起動するためのメッセージの概要を示すと同時に、メソッド名(セレクタともいう。この場合、#addFieldTo:)とメッセージに添えられたパラメータ(引数)を関連づける変数(パラメータ変数。window)を宣言する場でもあります。したがって、この行のメソッド名の部分を書き換えるだけで、新しいメソッド(たとえば、#addButtonTo:)を定義することが可能です。

手始めに「addFieldTo:」の「Field」部分を「Button」に書き換えてから、accept(cmd + S)してみてください。ただちにコンパイルが終了し、右上のペインに「addButtonTo:」が追加されるはずです。「add button」メニュー項目はこれでエラーを出さなくなりますが、相変わらずテキストフィールドしか作れません。

メソッド本体も#addButtonTo:という名前にふさわしく、テキストフィールドではなくプッシュボタン(a PluggalbeButtonMorph)を追加する内容に置き換えましょう。二行目の「field」を選択した状態で「button」とタイプしてからcmd + shift + Jとタイプすると、テンポラリ変数fieldからbuttonへの全置換を行なえます。さらに、三行目から四行目をボタン用に変更、accept(cmd+ S)すれば作業は完了です。

addButtonTo: window
 | button relFrame |
 button := (PluggableButtonMorph
   on: self getState: nil action: nil) label: 'button'; yourself.
 relFrame := (Rectangle fromUser
   scaleFrom: window layoutBounds
   to: (0 asPoint extent: 1e3 asPoint)) scaleBy: 1.0e-3.
 window addMorph: button frame: relFrame


これで、GUIビルダウインドウに新たに設けられたメニュー項目「add button」は、以後、正常に機能するはずです。

[fig.C]「add button」により追加が可能になったプッシュボタン
Uploaded Image: 73c.png

ただ、既存メソッドをちょっと書き換えるだけで簡単に追加できたということは、裏を返せば書き換えた部分以外まったく同じ内容のメソッドの“複製”ができてしまったということを意味します。このまま安易な拡張を続けることで、同内容の処理を分散させ、メインテナンス性が損なわれるようではいけません。次回は今回のようなコード複製をせずとも、ウィジェットの種類を増やすことができるしくみを考えます。

このページを編集 (4038 bytes)


Congratulations! 以下の 1 ページから参照されています。

This page has been visited 264 times.