Assignment 7b
Home ] Up ] Assignment 7a ] [ Assignment 7b ] Assignment 7c ]

 

 

A "Shuttle" Component

Now, convert the Shuttle program you wrote in the last assignment into a Shuttle Component that may be added to a container (as other components like JButton, JList, etc. may be added to a container).

Here's what to do:

  1. Create a Shuttle Component Class

    Create a class called Shuttle, as follows:

    • It should extend JPanel. Why?
    • Create a default constructor for the class. 
      • It should contain roughly the code you placed in the equivalent class in the first section of this assignment. (Things like setting the background color, adding/placing the left and right lists and the two buttons, etc.)
      • However, it should not contain code that moves anything into the two lists. That's because we want to make those operations driven by other classes that will be making use of Shuttle components.
    • Have the class implement the following methods:
      • public void addToLeft(String item)
      • public void addToLeft(String[] items)
      • public void removeFromLeft(String item)
      • public void removeFromLeft(String[] items)
      • public void addToRight(String item)
      • public void addToRight(String[] items)
      • public void removeFromRight(String item)
      • public void removeFromRight(String[] items)

      (It should be obvious what each of these methods will do.)

    • You'll have to have the Shuttle class implement the appropriate Listeners for the events that it will have to handle, and create the necessary methods for these Listeners. (Or use equivalent, perhaps inner, classes to handle them.)

  2. Add Support for a ShuttleListener

    We're going to turn our Shuttle into a real component that generates its own events, so that other classes can express interest in listening for and handling those events. To do this, we'll follow the JDK 1.1+ event model and create:

    • A ShuttleEvent class,
    • A ShuttleListener class, and
    • A ShuttleAdapter class.

    What kind of events are we interested in for a Shuttle?  Regardless of the internal details, the only things of external interest are:

    • An item was added to the left list
    • An item was removed from the left list
    • An item was added to the right list
    • An item was removed from the right list

    (Note that, if several items are added to a list in one operation (using the addToLeft(String[] items) or addToRight(String[] items) methods, or equivalent remove methods), an appropriate event should be generated for each separate item added.)

    What kinds of information are we interested in for each of these events? In each case, the information we wish to convey is the string being added or removed.

    So, create a public ShuttleEvent class, in package shuttle, as follows:

    • It should extend from class ComponentEvent. Why?
    • It should contain a set of public static final ints with unique values: LEFT_ITEM_ADDED, LEFT_ITEM_REMOVED, RIGHT_ITEM_ADDED, RIGHT_ITEM_REMOVED
    • A public constructor that accepts the same datatypes as the ComponentEvent constructor, plus the string item that was added to or removed from the list. It should save the item string in the ShuttleEvent instance.
    • A public getItem() method that returns the item string.

    Now, create a public ShuttleListener interface in package shuttle, as follows:

    • It should specify four methods:
      • public void leftItemAdded(ShuttleEvent event);
      • public void leftItemRemoved(ShuttleEvent event);
      • public void rightItemAdded(ShuttleEvent event);
      • public void rightItemRemoved(ShuttleEvent event);

    That was easy! Now, create a public ShuttleAdapter class in package shuttle, as follows:

    • What should it extend? Implement?
    • What methods should it contain?

    Hint: Take a look at other similar classes in the JDK 1.x class library.

  3. Use the ShuttleListener functionality

    Now, we can start to make use of these classes.

    • To the Shuttle class, add the following methods:
      • public void addShuttleListener(ShuttleListener listener)
      • public void removeShuttleListener(ShuttleListener listener)

    You will need to implement the code to add and remove a ShuttleListener, and also add and implement the necessary methods within the Shuttle class to cause all the registered ShuttleListeners to be notified when an event of interest happens.

    Hints: You will have to be very careful to write code that can deliver the event notifications to the registered Listeners, while at the same time handling requests to add and remove ShuttleListeners. I recommend that you use the javax.swing.event.EventListenerList class to implement this;  see its API javadocs for details of how to do this.
  4. Generating Events from the Add/Remove Methods

    Each of the methods:

    • public void addToLeft(String item)
    • public void removeFromLeft(String item)
    • public void addToRight(String item)
    • public void removeFromRight(String item)

    should not only perform the obvious addition or removal of an item to/from the corresponding list, but should also generate an appropriate event corresponding to the event types listed above, in the ShuttleEvent class.  By generate an event I mean the following:

    1. Create an instance of ShuttleEvent, with the appropriate constructor arguments. This is the generated event.
    2. Use the EventQueue's postEvent() method to cause the event to be "fired" (see here for documentation of postEvent
    3. The result of calling postEvent will be to cause the event to be delivered in the Event Dispatch thread, which will cause the component's processEvent method to be invoked with this event as a parameter. (See here for documentation on processEvent)  You will need to override the processEvent method in the shuttle component to cause it to process ShuttleEvents -- don't forget to call the processEvent method in the shuttle component's superclass to process events that are not ShuttleEvents
    4. By analogy with the existing methods such as processComponentEvent, etc., I recommend that you write a processShuttleEvent(ShuttleEvent ev) method to do the processing of ShuttleEvents, called from your overriding processEvent method.  The processShuttleEvent method should be responsible for determining what kind of ShuttleEvent is being delivered, and as a result, which entry point in each of the ShuttleListeners will be called.  This is how your ShuttleEvents are delivered to your  ShuttleListeners.

    Note that the methods:

    • public void addToLeft(String[] items)
    • public void removeFromLeft(String[] items)
    • public void addToRight(String[] items)
    • public void removeFromRight(String[] items)

    should simply delegate the real processing of each individual item to the appropriate method to add or remove a single item.  Otherwise, you're making work for yourself!

  5. Test It!!!

    By now, you should already have created some kind of test for the functionality you've created above. I created a ShuttleTest class that exercised the functionality as thoroughly as I could, and this allowed me to debug where things didn't work.

    In particular, I set up a class that acted as a ShuttleListener, which printed out a suitable message whenever a ShuttleEvent was received.

    I expect you to do something very similar.  In fact, I expect you to test all your assignments thoroughly!

 

This page was last modified on 02 October, 2007