如何在smalltalk的变形中显示字典的内容?

时间:2015-12-26 21:09:22

标签: user-interface smalltalk squeak

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

我创建了一个类

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:欢迎任何有关应对压力的提示;)

2 个答案:

答案 0 :(得分:4)

您的错误来源是

    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:方法)

显然还有很大的改进空间,但这超出了本Q&amp; A的范围。

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

答案 1 :(得分:1)

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

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

|list listMorph|
list := Smalltalk allClasses.
listMorph := PluggableListMorph on:list list:#yourself selected:nil changeSelected:nil.
listMorph openInHand

这是一个简单的例子。在实际应用程序中,您将实现一个提供列表的模型类(请参阅Inspector或其他工具)。

如果要列出字典内容,可以为两个&#34;子列表构建多列listMorph&#34; (键,值), 另一个多列示例:

|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