如何在 smalltalk 中以变形显示字典的内容?
How to display the contents of a dictionary in a morph in smalltalk?
因为我似乎无法找到一些可以显示 Dictionary
内容的预定义 Morph
,所以我决定最好停止寻找并想创建自己的内容Morph
。我找到了 nice description 如何从一些不错的示例代码开始让我开始,但很快我就遇到了一个问题,我似乎无法在 [=36= 上绘制文本或类似的东西].
我创建了一个class
Morph subclass: #DictionaryView
instanceVariableNames: 'dictionary'
classVariableNames: ''
poolDictionaries: ''
category: 'StatisticsTool'
我想覆盖 drawOn
如下:
drawOn: aCanvas
| x y |
x := 0.
y := 0.
dictionary associationsDo: [ :assoc |
aCanvas drawString: assoc key at: x@y.
aCanvas drawString: assoc value at: x+10@y.
y := y + 10. ].
我知道这不是最好的代码(我还不知道我应该如何考虑最长的字符串等,但我已经到了我什至不想考虑的地步那个了),但我只是想展示一些东西。不幸的是,当我尝试时这似乎不起作用
d := Dictionary new.
d at: 'test1' put: 5.
d at: 'test2' put: 23.
d at: 'test3' put: 514.
view := DictionaryView new.
view dictionary: d.
view openInWorld.
我得到一个错误:Instances of SmallInteger are not indexable
我不知道该怎么办了。我实际上没有时间写这些长问题,也没有时间花整整一周的时间来寻找这样的东西。这一切让我非常紧张和不耐烦,因此我想原谅自己直接提问:
如何在 Smalltalk 中显示字典以便在 GUI 中使用它?
PS:也欢迎任何应对压力的技巧;)
你的错误来源在这里
aCanvas drawString: **assoc key** at: x@y.
aCanvas drawString: **assoc value** at: x+10@y.
不能保证它们中的任何一个都是字符串(在你的情况下,值是数字),所以你必须手动转换它们
aCanvas drawString: assoc key printString at: x@y. "or asString"
aCanvas drawString: assoc value printString at: x+10@y.
你应该能够很容易地调试这类问题。
关于字符串的宽度,字符串的长度可以问字体
Preferences standardDefaultTextFont heightOfString: 'hello'
更新:
您也可以简单地将所有值转换为 StringMorph
并将它们组合在一起。
DictionaryView>>dictionary: aDictionary
| container keys values |
(container := Morph new)
layoutPolicy: TableLayout new;
listDirection: #leftToRight.
(keys := Morph new) layoutPolicy: TableLayout new.
(values := Morph new) layoutPolicy: TableLayout new.
aDictionary
associationsDo:
[ :assoc |
keys addMorph: assoc key printString asMorph.
values addMorph: assoc value printString asMorph ].
container
addMorph: keys;
addMorph: values.
self addMorph: container
(当然删除 #drawOn:
方法,因为它将不再需要)
显然还有很大的改进空间,但这超出了本次问答的范围。
或者您可以使用 MulticolumnLazyListMorph
小部件。
使用 Canvas 及其绘图 API 主要是关于实施
你自己的基地变形。如果你想构建一个 GUI,你可以尝试使用
现有变形作为积木。
就像Debugger/Inspector不实现他们自己的列表变形一样,你
可以使用现有的 classes。
LazyListMorphs 由 PluggableListMorphs 使用。你可以插入一个模型
提供列表和一些用于列表选择行为的选择器。
|list listMorph|
list := Smalltalk allClasses.
listMorph := PluggableListMorph on:list list:#yourself selected:nil changeSelected:nil.
listMorph openInHand
这是一个简单的例子。在真实世界的应用程序中,您将实现一个提供列表的模型 class(请参阅 Inspector 或其他工具)。
如果你想列出字典内容,你可以为"sublists"(键,值)构建一个多列listMorph,
另一个多列示例:
|listOfLists listMorph|
listOfLists := { (1 to:100) asArray . (1 to:100) collect:[:x | x * x]}.
listMorph := PluggableMultiColumnListMorph on:listOfLists list:#yourself selected:nil changeSelected:nil.
listMorph openInHand
因为我似乎无法找到一些可以显示 Dictionary
内容的预定义 Morph
,所以我决定最好停止寻找并想创建自己的内容Morph
。我找到了 nice description 如何从一些不错的示例代码开始让我开始,但很快我就遇到了一个问题,我似乎无法在 [=36= 上绘制文本或类似的东西].
我创建了一个class
Morph subclass: #DictionaryView
instanceVariableNames: 'dictionary'
classVariableNames: ''
poolDictionaries: ''
category: 'StatisticsTool'
我想覆盖 drawOn
如下:
drawOn: aCanvas
| x y |
x := 0.
y := 0.
dictionary associationsDo: [ :assoc |
aCanvas drawString: assoc key at: x@y.
aCanvas drawString: assoc value at: x+10@y.
y := y + 10. ].
我知道这不是最好的代码(我还不知道我应该如何考虑最长的字符串等,但我已经到了我什至不想考虑的地步那个了),但我只是想展示一些东西。不幸的是,当我尝试时这似乎不起作用
d := Dictionary new.
d at: 'test1' put: 5.
d at: 'test2' put: 23.
d at: 'test3' put: 514.
view := DictionaryView new.
view dictionary: d.
view openInWorld.
我得到一个错误:Instances of SmallInteger are not indexable
我不知道该怎么办了。我实际上没有时间写这些长问题,也没有时间花整整一周的时间来寻找这样的东西。这一切让我非常紧张和不耐烦,因此我想原谅自己直接提问:
如何在 Smalltalk 中显示字典以便在 GUI 中使用它?
PS:也欢迎任何应对压力的技巧;)
你的错误来源在这里
aCanvas drawString: **assoc key** at: x@y.
aCanvas drawString: **assoc value** at: x+10@y.
不能保证它们中的任何一个都是字符串(在你的情况下,值是数字),所以你必须手动转换它们
aCanvas drawString: assoc key printString at: x@y. "or asString"
aCanvas drawString: assoc value printString at: x+10@y.
你应该能够很容易地调试这类问题。
关于字符串的宽度,字符串的长度可以问字体
Preferences standardDefaultTextFont heightOfString: 'hello'
更新:
您也可以简单地将所有值转换为 StringMorph
并将它们组合在一起。
DictionaryView>>dictionary: aDictionary
| container keys values |
(container := Morph new)
layoutPolicy: TableLayout new;
listDirection: #leftToRight.
(keys := Morph new) layoutPolicy: TableLayout new.
(values := Morph new) layoutPolicy: TableLayout new.
aDictionary
associationsDo:
[ :assoc |
keys addMorph: assoc key printString asMorph.
values addMorph: assoc value printString asMorph ].
container
addMorph: keys;
addMorph: values.
self addMorph: container
(当然删除 #drawOn:
方法,因为它将不再需要)
显然还有很大的改进空间,但这超出了本次问答的范围。
或者您可以使用 MulticolumnLazyListMorph
小部件。
使用 Canvas 及其绘图 API 主要是关于实施 你自己的基地变形。如果你想构建一个 GUI,你可以尝试使用 现有变形作为积木。
就像Debugger/Inspector不实现他们自己的列表变形一样,你 可以使用现有的 classes。 LazyListMorphs 由 PluggableListMorphs 使用。你可以插入一个模型 提供列表和一些用于列表选择行为的选择器。
|list listMorph|
list := Smalltalk allClasses.
listMorph := PluggableListMorph on:list list:#yourself selected:nil changeSelected:nil.
listMorph openInHand
这是一个简单的例子。在真实世界的应用程序中,您将实现一个提供列表的模型 class(请参阅 Inspector 或其他工具)。
如果你想列出字典内容,你可以为"sublists"(键,值)构建一个多列listMorph, 另一个多列示例:
|listOfLists listMorph|
listOfLists := { (1 to:100) asArray . (1 to:100) collect:[:x | x * x]}.
listMorph := PluggableMultiColumnListMorph on:listOfLists list:#yourself selected:nil changeSelected:nil.
listMorph openInHand