Small World: A Little (More) Smalltalk

Lesson 2: Your First Application

In this lesson you will create your first Small World application. The application will be very simple, only 8 lines long, but it will illustrate many of the basic features found in almost all Smalltalk applications. To begin, start the Small World system and create a class browser. In the expression portion of the class browser, enter the text Class addNewClass: Object subclass, as shown below:

This command is telling the Small World system to create a new class, which is a subclass of Object, and place it into the class dictionary. To execute this command, press the evaluate expression button. The subclass command will bring up a class creation window. In this window, enter the name Hello, and leave the other two lines blank. This window show look as follows:

After you hit the create class button the class will be created and entered into the class dictionary. Returning to the class browser window, find the new class Hello in the list of classes to the right. (If you don't see it, try pressing the clear button. This will reset the class list). Select this class, then press the button marked examine class. In response you should get a class editor for the class Hello, which should look something like the following:

Using the panel in the middle of the window, enter the following method. You can resize the window to make it wider and taller if necessary.

Once you have entered the class, press the button marked compile. If all works well you will get a notification window indicating that compilation was successful. If not, you will get an error window (see the section on common errors at the end of this lesson). In the latter case, fix the method and try recompiling until you get the notification window that compilation was successful.

Close this window. The method named run should now appear in the right column of the class browser.

Windows, Panes and Images

Before actually running your newly created application, let us explain the various parts that it is made of. If you have been browsing classes and methods as suggested in the previous lesson, you should already be somewhat familiar with the general form of a Smalltalk method. The name of this method is run. The three names between the vertical braces are temporary variables, variables that will be used only during the execution of this method. In this case, the three variable names are win, pane, and img. These three variables will hold the three values that are part of almost any graphical application. These are a window, a pane, and an image.

A Window is the rectangular portion of a screen that you are undoubtedly  familiar with from other computer applications. A window has attributes such as a title and a size. In latter lessons we will also see that a window can have features such as menus.

A Pane is a graphical item that can be displayed in a window.  There are a wide variety of panes. This example uses a very simple form, which is an image pane. Other types of panes include buttons, sliders, lists, and many more. In addition panes can be subdivided into subpanes in a variety of ways. We will see examples of this in later lessons. One important feature of a pane is that it can respond to mouse activity. There are three basic methods for detecting mouse events: onMouseDown: onMouseUp: and onMouseMove:. Each takes a one-argument block that, when executed, will be given the location of the mouse event.

An Image is a graphical  canvas on which you can draw. The class Image supports a number of primitive drawing operations. In this example, when the mouse is pressed, we will draw the text "Hello World!" at the location of the mouse.

The image is connected to the pane when the pane is created. Later, the pane is connected to the window. Finally the command show tells the window to make itself visible.

Running your application

We are now ready to run the application. Return to the Smalltalk Browser and enter the command Hello new run, like the following:

Press the button marked evaluate expression. If you have done everything correctly, your window should now appear. Try clicking the mouse a few times in the window. Each time you click the text "Hello world" should appear right under the mouse:

Congratuations, you have just created your first Small World application. If you get an error message window you have probably made a typing error somewhere along the line. See the common errors section  at the end of this lesson for suggestions on where you might have gone wrong. You can go back and fix the run method and try again until you get it right. To close your application window you can select the close option in the menu bar. (The exact way this is done is different on each platform, but all allow it in some fashion or another). Try resizing the window by selecting the lower right corner. Notice if the window becomes smaller than the image that scroll bars are automatically inserted.

Further variations

There are a number of simple variations you can make to explore other features of the Small World. For example, suppose you want to erase the previous text message before printing the new text in response to a mouse down. To do this you need to remember the location of the previous mouse press. That requires another new temporary variable. Let us call this variable prev, and initialize it to the location 0@0. Now when the mouse goes down we want to execute the following five commands. First, change the color of the "ink" used by the image in the drawing commands to white. Then draw the text in white, which is in effect erasing the previous text. Reset the color to black, save the current location, and finally draw the new text. The revised method looks something like the following:

Try this out and see if the effect is what you expect.

But why restrict our colors to boring black?  Colors are defined in Small World using the RGB system, which is common in computer applications. RGB stands for red, green and blue. Each of these three colors is represented by a number between 0 and 255. You can explore these values in more detail using the color select window. Just type Color select in the Smalltalk browser and see what you get. To create a new color all you need are three values between 0 and 255. Fortunately, we have a source numbers, which is the coordinate points for the mouse press. But this yields only two numbers, not three. But we can use an arbitrary value, such as 100, for the third. Try changing the color command to the following:
  img setColor: (Color red: p x green: 100 blue: p y).
This uses the x and y locations of the mouse point for the red and blue hues, and the value 100 for the green hue. Notice now that when you click the mouse in the window the color will change depending upon which part of the screen you are in.

Another possibility is to print an image, rather than text.  Declare a different new variable to hold the image. Initialize this image to be slightly smaller, say 30 by 30 pixels. Then invoke the message edit on the newly created image. 

When executed, the method edit will produce a small special purpose drawing window. You can use this to, for example, produce a happy face:

After you close the drawing window the new image is returned to your program. Now when the mouse is pressed you will produce multiple copies of the happy face. Because drawing images does not automatically generate a window repaint event, it is necessary to explicitly ask for the window to be redrawn after each image (see the body of the method presented earlier).

Cleaning Up

That's about all we want to do with the Hello World application, but before leaving we can illustrate a few other useful commands.  From the Smalltalk browser try entering the command Hello fileOut:

Remember to press the evaluate expression button. This command will create a text file named Hello. You might want to try looking at this file using your favorite text editor after you have left the Small World. In your next session of Small World you can read this file back in using the command File fileIn: 'Hello'. You can file out any class, including those provided as part of the standard image. This can be useful if you want a textual form of the class methods in order to study the Small World library in more detail.

If you want to keep the current image, including your new class, you can press the button marked save Image in the original Small World window.

It is a good idea to save your images regularly. The image is by default saved in a file named image. You can use your regular operating system commands to make copies of this file, or to rename old images. It is also a good idea to have a back up image just in case something goes wrong.

If you want to remove your application before saving the image you can select the class name in the Smalltalk Browser, then press the button marked delete class. A question window will appear asking if you really want to do this, and if you answer yes the class will be removed. Finally, when you are all done, and the image has been saved, and you are finished for the day, you can press the button marked quit in the Small World window, and the application will halt.


Common Errors

Q: I created my application yesterday, but today I can't find the application class anywhere.
A: Did you remember to save your image after you were finished?

Q: I get a funny error message about an undefined selector. What is this?
A: It means that you tried passing a message to an object that didn't understand it. There are several possible causes. These include (a) not initializing a variable, (b) assuming that a variable has a value different from what you expect, (c) getting confused about the precedence of message (forgetting that unary message bind tigher than binary, which bind tighter than keyword), or (d) forgetting to use a period as a statement separator. In the latter case the first token of the next statement will be interpreted as a message selector. Sometimes the types associated with the backtrace in the error window can help you track down the source of the error.

Q: I created my class, but it doesn't appear in the Smalltalk Browser.
A: Sometimes the list of classes in the browser can get out of date. Try hitting the clear button. This has the effect of refreshing the class list.

Q: When I try to compile, I get a funny error message about illegal element inserted into a byte array.
A: In this application? You must be doing something a bit more complex. This message usually means that the bytecode representation for a method has exceeded 256 bytes, which causes problems since addresses are stored as bytes. Try reducing the size of your method by moving some functionality into another method.  We will show how in the next lesson.

Q: I want to see more examples of windows and panes.
A: Have patience. You must learn to walk before you can fly. But if you insist, there are lots of examples hidden in the standard image. You can see all of these using the browser. For example, the class creation form is found in the method subclass in class Class. Error messages are handled by the method error: in class Object. Many other examples are hidden in class level protocol, which you can view by using the examine metaclass button in a class editor. Some good examples are the methods question: and notify: in the metaclass for class Window. The color selector is created by method select in the metaclass for class Color. The Smalltalk browser is created by the method browser in the metaclass for class Class. The class editor itself is created by the method edit in the same place. The latter is near the limit of the maximum size a method is allowed to be.