Smalltalk(VisualWorks with Jun)の基本事項
- 導入
- ウィンドウを操作
- ウィンドウに描画
- 問題
Smalltalk(VisualWorks with Jun)の基本事項を習得しましょう。以下に示すプログラムを音読しながら、当該のプログラムをワークスペースへとコピー&ペーストして実行します。この過程を繰り返すことにより、Smalltalkの対話的なプログラミングを垣間見てゆきましょう。
さっそくウィンドウを1つ開いてみます。UI.ApplicationWindow
へnew
のメッセージを送り、そのインスタンスを作ります。そして、それを一時変数aWindow
に束縛します。その後、それに向かってopen
と伝言するだけです。
| aWindow |
aWindow := UI.ApplicationWindow new.
aWindow open
以下のような小さなウィンドウが開いてくるはずです。確認できたら、開いたウィンドウを閉じてください。一仕事、一片付けです。
次に、ウィンドウにラベルを付け、ウィンドウの大きさ(最小のサイズ)を指定して開いてみましょう。一時変数aWindow
に束縛したUI.ApplicationWindow
のインスタンスへlabel:
でラベル文字列を伝言し、minimumSize:
で幅と高さを伝言します。
| aWindow |
aWindow := UI.ApplicationWindow new.
aWindow label: '私のウィンドウ'.
aWindow minimumSize: 400 @ 300.
aWindow open
今度は、ウィンドウの背景色を変えてみます。background:
のメッセージセレクタを用いて赤色(Graphics.ColorValue red
)を指定します。
| aWindow |
aWindow := UI.ApplicationWindow new.
aWindow label: '私のウィンドウ'.
aWindow minimumSize: 400 @ 300.
aWindow background: Graphics.ColorValue red.
aWindow open
では、グレースケールで5つのウィンドウを開いてみましょう。(0 to: 1 by: 0.25)
の間隔オブジェクトへdo:
のメッセージセレクタを用いて繰り返したいブロッククロージャを伝言します。そのブロッククロージャの中では、次々とやってくる0, 0.25, 0.5, 0.75, 1
の値を束縛したaValue
を使ってグレースケールをこしらえて背景色に設定しています。Graphics.ColorValue
へ明度を指定するbrightness:
でグレースケールの値aValue
を伝言しているところを注視してください。
| aRectangle |
aRectangle := nil.
(0 to: 1 by: 0.25)
do:
[:aValue |
| aWindow |
aWindow := UI.ApplicationWindow new.
aWindow label: '私のウィンドウ'.
aWindow minimumSize: 400 @ 300.
aWindow background: (Graphics.ColorValue brightness: aValue).
aRectangle
ifNil:
[aWindow open.
aRectangle := aWindow displayBox]
ifNotNil:
[aRectangle := aRectangle translatedBy: 50 @ 25.
aWindow openIn: aRectangle]]
ご覧のように5つのウィンドウが右下へとずれながら開いてきます。どのようにしてウィンドウの開く場所をずらしているのかを解説しておきましょう。aRectangle
という一時変数に最初nil
を束縛しておきます。そして、1つ目のウィンドウが開いた場所(矩形領域)を記憶します。2つ目以降は50 @ 25
だけ移動させているのです。
次のプログラムはロイヤルブルーの背景色を持つウィンドウを1つ開き、それを斜め下方向へ徐々に移動させます。translatedBy: 2 @ 1というメッセージに注目してください。
| aWindow aRectangle |
aWindow := UI.ApplicationWindow new.
aWindow label: '私のウィンドウ'.
aWindow minimumSize: 400 @ 300.
aWindow background: Graphics.ColorValue royalBlue.
aWindow open.
aRectangle := aWindow displayBox.
100
timesRepeat:
[aRectangle := aRectangle translatedBy: 2 @ 1.
aWindow displayBox: aRectangle.
aWindow displayPendingInvalidation.
0.125 seconds wait]
次のプログラムはスプリンググリーンの背景色を持つウィンドウを1つ開き、それを徐々に大きくしてゆきます。 expandedBy: 4 @ 3に着目してください。
| aWindow aRectangle |
aWindow := UI.ApplicationWindow new.
aWindow label: '私のウィンドウ'.
aWindow minimumSize: 400 @ 300.
aWindow background: Graphics.ColorValue springGreen.
aWindow open.
aRectangle := aWindow displayBox.
50
timesRepeat:
[aRectangle := aRectangle expandedBy: 4 @ 3.
aWindow displayBox: aRectangle.
aWindow displayPendingInvalidation.
0.125 seconds wait]
では、文字を表示してみましょう。次のプログラムを実行してください。一時変数aString
へ束縛した文字列をウィンドウ内に表示します。文字列から構成テキスト(ComposedText
)を作成しています。構成テキストは、文字の大きさなどを指定することのできるオブジェクトです。
| aString aComposedText aWindow |
aString := '私の名前'.
aComposedText := Graphics.ComposedText withText: aString asText
style: (Graphics.TextAttributes styleNamed: #large).
aWindow := UI.ApplicationWindow new.
aWindow label: '私のウィンドウ'.
aWindow minimumSize: 400 @ 300.
aWindow background: (Graphics.ColorValue brightness: 0.9).
aWindow component: aComposedText.
aWindow open
表示する位置を変えてみます。文字列から作成した構成テキストを表示する際に、displayOn:
ではなく、displayOn:at:
で場所を指定するようにしました。
| aString aComposedText aVisualBlock aWindow |
aString := '私の名前'.
aComposedText := Graphics.ComposedText withText: aString asText
style: (Graphics.TextAttributes styleNamed: #large).
aVisualBlock := UI.VisualBlock block:
[:graphicsContext :viewBounds |
| aPoint |
aPoint := 50 @ 50.
aComposedText displayOn: graphicsContext at: aPoint].
aWindow := UI.ApplicationWindow new.
aWindow label: '私のウィンドウ'.
aWindow minimumSize: 400 @ 300.
aWindow background: (Graphics.ColorValue brightness: 0.9).
aWindow component: aVisualBlock.
aWindow open
ウィンドウの真ん中に表示するのはどうすればいいでしょうか。displayOn:at:
で指定する場所を計算するように変更しています。ビューの大きさと、表示する文字の大きさを考えなくてはいけませんよね・・・。プログラムを読んで確認してください。
| aString aComposedText aVisualBlock aWindow |
aString := '私の名前'.
aComposedText := Graphics.ComposedText withText: aString asText
style: (Graphics.TextAttributes styleNamed: #large).
aVisualBlock := UI.VisualBlock block:
[:graphicsContext :viewBounds |
| aPoint |
aPoint := viewBounds center - aComposedText bounds center.
aComposedText displayOn: graphicsContext at: aPoint].
aWindow := UI.ApplicationWindow new.
aWindow label: '私のウィンドウ'.
aWindow minimumSize: 400 @ 300.
aWindow background: (Graphics.ColorValue brightness: 0.9).
aWindow component: aVisualBlock.
aWindow open
center
以外にも、矩形の位置を訊ねるメッセージがあります。配置を覚えておきましょう。
| aCollection aVisualBlock aWindow |
aCollection := Core.OrderedCollection new.
aCollection add: #topLeft -> nil.
aCollection add: #topCenter -> nil.
aCollection add: #topRight -> nil.
aCollection add: #leftCenter -> nil.
aCollection add: #center -> nil.
aCollection add: #rightCenter -> nil.
aCollection add: #bottomLeft -> nil.
aCollection add: #bottomCenter -> nil.
aCollection add: #bottomRight -> nil.
aCollection do:
[:anAssociation |
| aComposedText |
aComposedText := Graphics.ComposedText
withText: anAssociation key asString
style: (Graphics.TextAttributes styleNamed: #small).
anAssociation value: aComposedText].
aVisualBlock := UI.VisualBlock block:
[:graphicsContext :viewBounds |
aCollection do:
[:anAssociation |
| aSymbol aComposedText aRectangle aPoint |
aSymbol := anAssociation key.
aComposedText := anAssociation value.
aRectangle := aComposedText bounds.
aRectangle := aRectangle align: (aRectangle perform: aSymbol)
with: (viewBounds perform: aSymbol).
aPoint := aRectangle origin.
aComposedText displayOn: graphicsContext at: aPoint]].
aWindow := UI.ApplicationWindow new.
aWindow label: '私のウィンドウ'.
aWindow minimumSize: 400 @ 300.
aWindow background: (Graphics.ColorValue brightness: 0.9).
aWindow component: aVisualBlock.
aWindow open
私のウィンドウというラベルを持ち、背景色が白色、幅600で高さ200のウィンドウを開き、そのウィンドウの中央に京都産業大学のロゴ画像を描画するプログラムを作成しなさい。
京都産業大学のロゴ画像は以下のプログラムで取得することができます。
| aLambda anImage |
aLambda :=
[:urlString |
| separatorString workDirectory commandLine imageFile imageReader |
separatorString := Core.String with: OS.Filename separator.
workDirectory := (OS.SystemUtils getEnvironmentVariable: 'HOME') , separatorString , 'Desktop'.
commandLine := '(cd ' , workDirectory , ' ; curl -O ' , urlString , ')'.
OS.ExternalProcess cshOne: commandLine.
imageFile := workDirectory , separatorString , (OS.URL fromString: urlString) path last.
imageReader := Graphics.ImageReader fromFile: imageFile.
imageReader image].
anImage := aLambda value: 'http://www.cc.kyoto-su.ac.jp/~atsushi/images/KyoSanDaiLogo.png'.
^anImage
構成テキスト(ComposedText
のインスタンス)と同様に、画像(Image
のサブクラスのインスタンス)もbounds
やdisplayOn:at:
のメッセージセレクタを用いた伝言に応答することができます。さぁ!がんばって。
Updated: 2019/08/26 (Created: 2008/04/01)
