CIT 594 About the Assignment 1 Sample Code
CIT 594, Spring 2005

You should be able to figure out how to use and adapt my sample code without knowing exactly how it works. If you are interested, however, there are some things in it that we haven't discussed. This page is a brief guide to the code.

FloodFillApplet
    extends JApplet implements Observer

FloodFillApplet is an ordinary JApplet. The init() method is perfectly typical--it creates the GUI, and installs an event handler, handleButtonClick(). There are only two interesting aspects of this applet: It uses a custom component (ColorArrayComponent canvas) and it implements Observer.

The ColorArrayComponent is a component much like any other--a button, say, or a text field. It displays a two-dimensional array of colors, Color[][] colors, and it responds to mouse clicks on any cell of the displayed array. It differs from other components in two respects. First, I wrote it myself. Second, it uses Observer/Observable rather than Event/Listener (more on this below).

ColorArrayComponent
    extends JComponent

The Sun-supplied Swing components extend JComponent, and ColorArrayComponent is no exception. One nice thing about extending JComponent is that when the component needs to be redrawn (for example, when the window is resized, or covered and uncovered), Swing automatically calls my paintComponent(Graphics g) method. (User code should never call paintComponent(Graphics g) directly; instead, it calls repaint(), so that Java can do the painting at an appropriate time.)

The constructor for ColorArrayComponent takes two arguments: the Color[][] array to be displayed, and an Observer (The FloodFillApplet supplies itself as the observer). It creates a MouseHandler object (described below) and tells it about the observer.

For painting itself when needed, ColorArrayComponent overrides JComponent's default paintComponent(Graphics g) method. This method gets the current width and height of the component when called, so that the method works well when the applet is resized.

MouseHandler
     extends Observable implements MouseListener

This is just a simple mouse listener. It is an inner class of ColorArrayComponent so that it can easily find out the size of the array and the size of the component; it needs this information to figure out the row number and column number on which the mouse was clicked.

I would have preferred to extend MouseAdapter and override only the mouseClicked(MouseEvent e) method. However, a Java class can only extend one other class, and I needed to extend Observable. It was only a little extra work to implement the MouseListener interface and supply stubs for the methods I didn't care about.

Observer/Observable

I'm using the Observer design pattern, which is nicely supported in Java by the Observer interface and Observable class. The problem that this design pattern solves is that I wanted to decouple the component from the code that uses it. That is, the component should be independent of whatever GUI uses it.

One way to achieve this independence is to make the component an Observable. An Observable takes a list of Observers (analogous to listeners) and, whenever it wants to indicate that something happened, calls setChanged() and notifyObservers(Object). These methods tell Java to call the update(Observable, Object) method of every registered Observer--the Observable doesn't have to know anything about the Observers, or even if there are any. The Object parameter is whatever information the Observable wants to post about itself--in this case, a Point object containing row and column indices.

To register itself as an observer, FloodFillApplet passes itself (this) as an argument to the ColorArrayComponent, which then calls MouseHandler's addObserver(observer) method.

What I should have done

While the above more-or-less successfully decouples my new component from the GUI, it does have some problems. For one thing, by setting up the link in the constructor, I've limited the component to having only a single observer (that's just bad programming on my part). For another, Sun-supplied components use events and listeners, not observables and observers, so my code isn't as consistent with "the rest of the world" as it should be.

AWTEvent is just a normal class, and EventListener is just a normal interface. What I should have done is this:

The advantage of this approach would be that users of a ColorArrayComponent could just define a listener or listeners for it in the usual (and hopefully familiar) way.

OK, why didn't I do things this way? Well, as usual, I was in a hurry, and I'm not exactly sure how to establish the connection between an event and the listener for that event. I believe I can figure it out fairly easily (some time when I'm not in a hurry), but by using Observer/Observable (which I know pretty well), I was able to get the code done before class.