Because I don't seem to be able to find some predefined Morph
that can display the contents of a Dictionary
, I decided I'd better stop looking and wanted to create my own Morph
. I found a nice description how to start with some nice example code to get me started, but quite soon I got to the problem that I don't seem to manage to draw text or anything like that on a canvas.
I created a class
Morph subclass: #DictionaryView
instanceVariableNames: 'dictionary'
classVariableNames: ''
poolDictionaries: ''
category: 'StatisticsTool'
and I wanted to override drawOn
as follows:
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. ].
I know this is not exactly the best piece of code (I have no idea yet how I should take into account the longest string etc, but I got to this point where I don't even really want to think about that anymore), but I just wanted to get something displayed. Unfortunately, this does not seem to work when I try
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.
I get an Error: Instances of SmallInteger are not indexable
I don't know what to do anymore. I actually don't have time to write these long questions or to look a whole week for something like this. This all makes me very nervous and impatient and therefore I would like to excuse myself for the direct way of asking:
How can I display a dictionary in Smalltalk so that I can use it in a GUI?
PS: any tips on coping with stress are also welcome ;)
working with Canvas and its drawing API is mostly about implementing your own base Morphs. If you want to build a GUI, you can try to use existing Morphs as building blocks.
Just like Debugger/Inspector don't implement their own list morphs, you can use existing classes. LazyListMorphs are used by PluggableListMorphs. You can plugin a model that provides the list and some selectors for list selection behavior.
This is a simple example. In a real world application, you would implement a model class that provides the list (see Inspector or other tools).
If you want to list dictionary contents, you can built a multicolumn listMorph for both "sublists" (keys, values), another multicolumn example:
The source of your error is here
There's no guarantee that any of them will be string (and in your case the values are numbers), so you have to convert them manually
You should be able to debug this kind of problem quite easily.
Regarding the width of string, you can ask a font for the length of a string.
Update:
You can also simply convert all the values to
StringMorph
s and compose them together.(of course remove the
#drawOn:
method as it will be no longer needed)Obviously there's a lot of room for improvement, but that's out of the scope of this Q&A.
Alternatively you can use the
MulticolumnLazyListMorph
widget.