Hatena::ブログ(Diary)

Smalltalkのtは小文字です

id:sumim:about

Smalltalk を本格的に勉強する気はないけれど、うんちく程度に知っておきたいなら→Smalltalkをちょっとかじってみたい人のための、チュートリアルまとめ - Qiita

オブジェクト指向の“モヤッと”の正体を知りたくなったらこちらの記事が役に立つかも→id:sumim:20080415:p1 とか id:sumim:20040525:p1


 | 

2008-09-23

[] VisualWorks Smalltalk の“アプリケーションモデル”で BMI checker 2


id:sumim:20080919:p1 の続き。umejavaさんにコメントやメールで教えていただいたので、フィールドの色が変わる版も。複数のウインドウが共通のモデルを共有したときにも動作するように細工してみました。


| app1 app2 window1 window2 |
app1 := BMIChecker4 new.
window1 := app1 open window.
app2 := BMIChecker4 new.
app2 height: app1 height.
app2 weight: app1 weight.
app2 bmi: app1 bmi.
window2 := app2 open window.
window1 moveTo: 100@100.
window2 moveTo: window1 displayBox topRight + (20@0)

http://squab.no-ip.com/collab/uploads/61/bmicheker4.png


前の BMIChecker との違い(=教えていただいて学んだこと)は、

  • フィールドの色を変えるために、GUI Painter Tool → BMI値入力欄 → Basics → ID:欄 に #bmi を入力して、あとで #componentAt: でたぐれるようにしたこと
  • #height、#weight、#bmi は、同じく GUI Painter Tool で対応する入力欄を選択した状態で Edit → Define で自動生成させたこと。それに伴い、
    • インスタンス変数アクセスを間接アクセスパターンに切り替えたこと
    • BMI値更新用の #bmiChanged を新たに設けたこと
  • ウィジェットビルド後にコールされる #postBuildWith: をフックして BMI値欄の色づけを伴う初期化を行なっていること

…といったところでしょうか。あと、モデル共有時に期待通りの動作をしなかったため今回は使いませんでしたが、#onChangeSend:to: のコールをハンドコードする代わりに、GUI Painter Tool → 各入力欄 → Notificationタブ → Change:欄で #bmiChanged などと入力して指定することでも似たようなことが可能であることも教えていただきました。


Smalltalk defineClass: #BMIChecker4
    superclass: #{UI.ApplicationModel}
    indexedType: #none
    private: false
    instanceVariableNames: 'height weight bmi '
    classInstanceVariableNames: ''
    imports: ''
    category: '(none)'

BMIChecker4 >> initialize
    super initialize.
    self height value: 1.704.
    self height onChangeSend: #bmiChanged to: self.
    self weight value: 60.4.
    self weight onChangeSend: #bmiChanged to: self

BMIChecker4 >> postBuildWith: aBuilder
    self bmiChanged

BMIChecker4 >> bmi: aValueHolder
    bmi := aValueHolder

BMIChecker4 >> height: aValueHolder
    height := aValueHolder.
    aValueHolder onChangeSend: #bmiChanged to: self

BMIChecker4 >> weight: aValueHolder
    weight := aValueHolder.
    aValueHolder onChangeSend: #bmiChanged to: self

BMIChecker4 >> bmi
    ^bmi isNil ifTrue: [bmi := 0 asValue] ifFalse: [bmi]

BMIChecker4 >> height
    ^height isNil ifTrue: [height := 0 asValue] ifFalse: [height]

BMIChecker4 >> weight
    ^weight isNil ifTrue: [weight := 0 asValue] ifFalse: [weight]

BMIChecker4 >> bmiChanged
    | bmiValue component fieldColor |
    bmiValue := self weight value / (self height value ** 2).
    self bmi value: bmiValue.
    fieldColor :=
        bmiValue < 18.5 ifTrue: [ColorValue white] ifFalse: [
        bmiValue < 20 ifTrue: [ColorValue yellow] ifFalse: [
        bmiValue < 30
            ifTrue: [ColorValue orange]
            ifFalse: [ColorValue red]]].
    component := self builder componentAt: #bmi.
    component lookPreferences: (component lookPreferences setBackgroundColor: fieldColor)

BMIChecker4 class >> windowSpec
    "Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

    <resource: #canvas>
    ^#(#{UI.FullSpec}
        #window:
        #(#{UI.WindowSpec}
            #label: 'BMI checker'
            #bounds: #(#{Graphics.Rectangle} 640 400 840 520 ) )
        #component:
        #(#{UI.SpecCollection}
            #collection: #(
                #(#{UI.LabelSpec}
                    #layout: #(#{Graphics.LayoutSizedOrigin} 15 0 15 0 46 18 )
                    #label: 'Height:' )
                #(#{UI.LabelSpec}
                    #layout: #(#{Graphics.LayoutSizedOrigin} 15 0 50 0 46 18 )
                    #label: 'Weight:' )
                #(#{UI.LabelSpec}
                    #layout: #(#{Graphics.LayoutSizedOrigin} 15 0 85 0 29 18 )
                    #label: 'BMI:' )
                #(#{UI.InputFieldSpec}
                    #layout: #(#{Graphics.LayoutSizedOrigin} 70 0 13 0 100 23 )
                    #model: #height
                    #type: #number )
                #(#{UI.InputFieldSpec}
                    #layout: #(#{Graphics.LayoutSizedOrigin} 70 0 48 0 100 23 )
                    #model: #weight
                    #type: #number )
                #(#{UI.InputFieldSpec}
                    #layout: #(#{Graphics.LayoutSizedOrigin} 70 0 83 0 100 23 )
                    #name: #bmi
                    #model: #bmi
                    #type: #number )
                #(#{UI.LabelSpec}
                    #layout: #(#{Graphics.LayoutSizedOrigin} 175 0 15 0 10 18 )
                    #label: 'm' )
                #(#{UI.LabelSpec}
                    #layout: #(#{Graphics.LayoutSizedOrigin} 175 0 50 0 16 18 )
                    #label: 'kg' ) ) ) )

ファイルイン用のファイルはこちらに。

umejavaumejava 2008/09/23 22:28 素晴らしい。これでsumimさんもVisualWorkerですね。ちなみにValueHolderの共有をやめ、単にwindow2 := app1 open window.としてみると、一見動くようですが、背景の変更がうまくいきません。self builder componentAt: の悪しき部分が見えますね。

sumimsumim 2008/09/23 23:24 ありがとうございます。これの使い方が分かれば、もう VisualWorks でアプリが組めるような気がしてきて恐ろしいですね。w

> 一見動くようですが
ずばりその点に今回ハマりました^^;。アプリケーションモデルは builder をひとつしか持てないので、複数のウィジェットを同時にはいじれないのですよね。バリューホルダの共有にしたのは苦肉の策です。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト

コメントを書くには、なぞなぞ認証に回答する必要があります。

 | 
2004 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 08 | 10 | 12 |
2013 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 11 | 12 |
2014 | 01 | 02 | 05 | 07 | 08 | 09 | 10 | 11 |
2015 | 04 | 07 | 08 | 11 | 12 |
2016 | 02 | 03 | 06 | 07 | 08 |
2017 | 04 | 05 |

最近のコメント

1. 06/25 sumim
2. 06/25 山田
3. 08/29 squeaker
4. 08/29 ardbeg1958
5. 10/16 umejava

最近のトラックバック

1. 05/25 プラグインレスでSVGを表示する「SIE」開発ブログ - メッセージをや...
2. 01/30 no_orz_no_life - Erlangとジャンケン
3. 12/31 檜山正幸のキマイラ飼育記 - J言語、だってぇー?
4. 09/04 Twitter / @atsushifx
5. 07/06 みねこあ - オブジェクト指向 と FizzBuzz

この日記のはてなブックマーク数
1672725