User interface 如何在smalltalk的变形中显示词典的内容?

User interface 如何在smalltalk的变形中显示词典的内容?,user-interface,smalltalk,squeak,User Interface,Smalltalk,Squeak,因为我似乎找不到一些预定义的Morph,可以显示词典的内容,所以我决定最好停止查找,并想创建自己的Morph。我找到了一个如何从一些好的示例代码开始的方法,但很快我就遇到了一个问题,我似乎无法在画布上绘制文本或类似的内容 我创建了一个类 Morph subclass: #DictionaryView instanceVariableNames: 'dictionary' classVariableNames: '' poolDictionaries: '' cat

因为我似乎找不到一些预定义的
Morph
,可以显示
词典的内容,所以我决定最好停止查找,并想创建自己的
Morph
。我找到了一个如何从一些好的示例代码开始的方法,但很快我就遇到了一个问题,我似乎无法在画布上绘制文本或类似的内容

我创建了一个类

Morph subclass: #DictionaryView
    instanceVariableNames: 'dictionary'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'StatisticsTool'
我想覆盖
drawin
,如下所示:

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.
我得到一个错误:
SmallInteger的实例不可索引

我不知道该怎么办了。实际上,我没有时间写这些长问题,也没有时间花整整一周的时间来寻找这样的问题。这一切都让我感到非常紧张和不耐烦,因此我想原谅自己直接问:

如何在Smalltalk中显示字典,以便在GUI中使用它


附言:任何关于应对压力的建议都是受欢迎的;)

您的错误源在这里

    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'
更新:

您还可以简单地将所有值转换为
stringmorp
s并将它们组合在一起

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
(当然,删除
#drawin:
方法,因为不再需要它)

显然还有很大的改进空间,但这超出了本问答的范围


或者,您可以使用
MultiColumnLazylistMorp
小部件。

您的错误源在这里

    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'
更新:

您还可以简单地将所有值转换为
stringmorp
s并将它们组合在一起

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
(当然,删除
#drawin:
方法,因为不再需要它)

显然还有很大的改进空间,但这超出了本问答的范围


或者,您可以使用
MultiColumnLazylistMorp
小部件。

使用画布及其绘图API主要是为了实现 你自己的基础变形。如果您想构建GUI,可以尝试使用 现有变形作为构建块

就像调试器/检查器不实现自己的列表变形一样,您可以 可以使用现有的类。 LazyListMorphs由PluggableListMorphs使用。你可以插入一个模型 为列表选择行为提供列表和一些选择器

|list listMorph|
list := Smalltalk allClasses.
listMorph := PluggableListMorph on:list list:#yourself selected:nil changeSelected:nil.
listMorph openInHand
这是一个简单的例子。在实际应用程序中,您将实现一个提供列表的模型类(请参见Inspector或其他工具)

如果要列出字典内容,可以为两个“子列表”(键、值)构建多列ListMorp, 另一个多列示例:

|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

使用Canvas及其绘图API主要是实现 你自己的基础变形。如果您想构建GUI,可以尝试使用 现有变形作为构建块

就像调试器/检查器不实现自己的列表变形一样,您可以 可以使用现有的类。 LazyListMorphs由PluggableListMorphs使用。你可以插入一个模型 为列表选择行为提供列表和一些选择器

|list listMorph|
list := Smalltalk allClasses.
listMorph := PluggableListMorph on:list list:#yourself selected:nil changeSelected:nil.
listMorph openInHand
这是一个简单的例子。在实际应用程序中,您将实现一个提供列表的模型类(请参见Inspector或其他工具)

如果要列出字典内容,可以为两个“子列表”(键、值)构建多列ListMorp, 另一个多列示例:

|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

我必须承认,我的问题提得很糟糕。我需要它显示在一个变形使用它在一个界面。。。对不起。@tsjolder先生,我已经更新了答案;如果你想要其他东西,那么你需要更好地指定你的问题,哪种方式可以改进?对我来说,这似乎是一个很好的解决方案(可能是因为我在整整一周内都没有显示任何内容)。还有,如何使用那些
lazylistmorp
s?我一直在研究代码,但没有找到如何将字典中的数据附加到代码上。无论如何,非常感谢!通过改进,我已经记住了它的外观和感觉(我觉得它很难看)。至于
(多列)LazyListMorph
,我不知道——我使用Pharo和Spec,很少使用Morphic小部件,这个小部件没有示例。我必须承认,我把我的问题提得很糟糕。我需要它显示在一个变形使用它在一个界面。。。对不起。@tsjolder先生,我已经更新了答案;如果你想要其他东西,那么你需要更好地指定你的问题,哪种方式可以改进?对我来说,这似乎是一个很好的解决方案(可能是因为我在整整一周内都没有显示任何内容)。还有,如何使用那些
lazylistmorp
s?我一直在研究代码,但没有找到如何将字典中的数据附加到代码上。无论如何,非常感谢!通过改进,我已经记住了它的外观和感觉(我觉得它很难看)。至于
(多列)LazyListMorph
,我不知道——我使用Pharo和Spec,很少使用Morphic小部件,这个小部件没有示例。会的