Previous Lesson: Text Field with Any Model
Next Lesson: List Selections
Status quo | ||
Nothing causes me as much grief in AWT as managing a List component. There are a whole mess of limitations that an MVC programmer has to work around, such as:
|
The Smalltalk list widgets (called SequenceView and MultiSelectionSequenceView) natively implement a lot of what we're talking about here. | |
The Model for List: SelectionInList | ||
So if we want to somehow convert Lists to the MVC framework, what would the model look like? Well, a List has two pieces of information that we are concerned about: the elements in the list and the selection(s). So both of these things should be captured as the model behind a List.
We call the model a SelectionInList. All it really does is hold onto two ValueModels: one for the list and one for the selectionIndex(es). This is all the information we need. The class gives a whole bunch of utility methods that help out but fundamentally that's all the information we need. We'll take a look in this lesson at the list part, then next lesson we'll see how the selection mechanism works. | In Smalltalk, this model represented by classes called SelectionInList and MultiSelectionInList. The Java version of SelectionInList plays both these roles. | |
The list behind MVCList | ||
Just like an MVCTextField always reflects the underlying model, the contents of an MVCList always relfect the contents of the ValueModel which represents the list. Huh? Let me try that again. Actually, let's look at an example first. | ||
Example 6: An MVCList of Strings | ||
Our theme for the examples on this page is that we want to display a list of basketball players. Since I'm from Chicago, we'll look at two teams: the Orlando Magic (arch-nemesis du jour) and your Chicago Bulls. In this initial example, we just want to display the names of the players. We'll have two button which will populate the list: one for the Magic and one for the Bulls. Look at the source code to see how this works. | The Smalltalk version of this example can be found in Example6.st and can be started by evaluating "Example6 open". | |
Example 6 | ||
Lists of Objects | ||
That's fine, but most of the time I want to be dealing with
lists of Objects, not plain old Strings. We need something that converts
the Objects we deal with in the model into Strings that the component can
display. Hmmm, sounds like the PrintConverter
we used for text fields. Almost, but not exactly. Here's the story.
The PrintConverter interface is actually just a composite of two other interfaces: ObjectPrinter and ObjectReader. This is so we can convert objects to strings (ObjectPrinter) and strings to objects (ObjectReader). We need to do both for something like a text field. For the list widget, however, we are only concerned about converting objects to strings, so the widget actually needs an ObjectPrinter. The cool thing is that we can use a PrintConverter as well, since it implements the ObjectPrinter interface. Anyway, if you don't give MVCList an ObjectPrinter explicitly, it will
create one for you behind the scenes called DefaultObjectPrinter.
All this does is send the method
|
By default, Smalltalk will send the message #displayString to the Objects to get a string representation. You can override this behavior by sending #displayStringSelector: to the SequenceView, or even setting a visual block that can represent the Object in a graphical manner. We don't have quite that much flexibility in AWT - yet!
| |
Example 7: An MVCList of Players | ||
This time, instead of having a list of Strings which represent basketball players, I am going to have a list of Player objects. For this example, a Player object is very simple: a Player has a first name (firstName ) and a last name (lastName ). The class has only one behavior right now, which is the toString() method, which will display the first name, a space, then the last name (which seems to be a reasonable default representation). There is a description of the object model if you are interested in more details.
We have the same two teams we had before with the same two population
buttons. This time we have two list components instead of one. The interesting
thing, though, is that they share the same underlying model, so the lists
and selections will always be in sync. The left list shows the default
behavior of MVCList:
it sends | The Smalltalk version of this example can be found in Example7.st and can be started by evaluating "Example7 open". Note that we have to go through quite a few hoops to get the desired behavior for the right-side list. This is one case where Java is easier than Smalltalk! | |
Example 7 | ||
MVCList limitations | ||
A lot of things become a lot easier when you deal with the model instead of the view. Not only is this encouraged, but there are some implementation limitations you should be aware of when dealing directly with an MVCList.
| Smalltalk has many of the same limitations, except that it also provides a collection class like Vector called List which does announce when it has changed. This often proves useful and allows you to forget about the view just a little bit more. | |
Coming up next... | ||
We have looked at one half of the List equation: the list of Objects. Next we'll look at how to handle selections using the Model-View-Controller approach. |