CS11 Advanced Java Lab 5 - Boggle Client UI

This week you should be able to get the vast majority of the Boggle client UI finished up. There will be a few more tweaks necessary when we add the client-server interaction, but after this week almost everything should be done from a UI perspective.

Here is a picture of what your user interface might look like by the end of this week:

The major components are as follows:

Of course, all of this will be wrapped in an application class. You might call that JBoggleApp, or BoggleClient, or something like that. This class will contain the main() method for your application, and the main() method will of course start up your application's user interface.

The Model-View-Controller Design Pattern

This week you will have an opportunity to explore the Model-View-Controller (MVC) design pattern. The scrollable word-list should use a JList, and JLists are views into a model that implements the ListModel interface.

Unfortunately, your WordList class is almost certainly unsuitable for using directly as a JList model, since your word-list is a set of words, not a list of words, and thus the position of a specific word in the set is not well defined.

So, you have two choices for creating your word-list:

  1. Take the easy way out. Your client application can have two fields, one being the WordList object, and the other being a javax.swing.DefaultListModel object. Then, you can use the WordList to make sure you don't add duplicate words, and if a word isn't already in the WordList, you can just append it to the DefaultListModel object.
  2. Provide a cleaner implementation. Create a subclass of the AbstractListModel (which implements the ListModel interface) that contains a WordList field. Provide an accessor that returns the internal WordList. Provide "add word" and "clear words" methods that also fire the appropriate "list-data changed" events.

You can follow either of these choices for your implementation. (I took the easy way out in my implementation...)

The Boggle Timer

This week's lab is a little involved, so to save you some time, you will get to use a simple "Boggle timer" class (here is the file: JBoggleTimer.java). The Boggle timer derives from JLabel and includes an internal javax.swing.Timer object for performing its periodic updates.

There is one little problem with the Boggle timer, though: It is supposed to fire an ActionEvent when the Boggle timer hits 0, but it doesn't currently do this. The code for adding and removing ActionListener implementations is present, and there is even support for setting the Boggle timer's action-command. But, you need to provide the missing piece.

Implement the fireActionPerformed() method to actually fire the ActionEvent. This is easier than you might expect, since all Swing components use the same event-passing infrastructure, and you can use this same infrastructure to fire the action-event. Specifically, all Swing components have a protected listenerList member, which stores all event-listeners that have been registered on a particular Swing component.

Go to the Java API Documentation for the javax.swing.event.EventListenerList class, and follow the pattern outlined for the fireFooXXX() method. (Of course, in this case, "Foo" is "Action", and "XXX" is "Performed", but that's simple enough.) There is one caveat though: The example code shows the FooEvent as being a class field; this is wrong. Instead, make it a local variable in the fireActionPerformed() method. (Otherwise, bad stuff will happen. You can probably figure out what, if you eyeball the example code...)

Make sure to set the ActionEvent's ID to ActionEvent.ACTION_PERFORMED, and make sure to set the action-command as well. This way you can leverage these capabilities in your controller.

The Boggle-Client Controller

The last remaining part of this week's assignment is to create the controller for the Boggle client application. This will be pretty easy, since all of the view components you need to handle will fire ActionEvents. Thus, you can create a single action-listener implementation that receives events from these components and directs the flow of the application. (It would almost certainly be best to implement this as an inner class.) Here are the view-components that your controller should listen to, and what the controller should do when each component fires an ActionEvent:

That should be it for the controller. Once you have this coded up, you should be able to play rounds of Boggle. Make sure that your client application operates correctly, then add all of your new files to your Subversion repository. You can figure out which files are new by typing this command in your working copy:

    svn status

This command will recursively scan your directories, and report all files that are either modified or unrecognized. If a file is unrecognized (a "?" next to the filename) then you can svn add it to your repository.

Once this is all done, make sure you have committed your work, and leave your efforts in your ~/cs11/advjava/lab5 directory.


Copyright (C) 2008, California Institute of Technology. All rights reserved.
Last updated May 6, 2008.