Updating ZooKeeperList automatically
The ZooKeeperList object needs some way of being notified whenever a change to the collection of zookeeper objects held by the administrator changes, in order that it can update its model and thus be reflected in the list of items displayed. This can be accomplished by defining suitable event and listener objects, as follows:
Create a sub-package under virtualzoo.core called event, within which you will define the class ZooKeeperEvent and the interface ZooKeeperListener.
Define a ZooKeeperEvent class in package virtualzoo.core.event:
- The class extends
EventObject, which is a Java supplied class intended for sub-classing by different event types; - The constructor requires a
ZooKeeperobject to be passed in and which is in turn passed to the superclass constructor (which accepts anyObject); - The
EventObjectclass defines agetSource()method so client objects can determine the source of the event. BecausegetSource()returns it as anObjecta cast is required to get it back into itsZooKeepertype which you know it has to be. To save client objects the inconvenience of having to do this cast you have defined agetZooKeeper()method that performs the cast here.
Define a ZooKeeperListener interface in package virtualzoo.core.event.
- The interface extends
EventListener, which is a Java supplied interface intended for sub-classing by different event listeners - Separate methods are specified for when a
ZooKeeperis created, changed or removed. Note the argument for each isZooKeeperEvent
Because ZooAdministrator stores the collection of ZooKeeper objects it is a natural place to maintain references to objects that want to know about new, changed or removed zoo keepers (i.e., ZooKeeperListeners) and to notify them whenever these events occur.
In ZooAdministrator define an import for virtualzoo.core.event and add the following instance variable to store a collection of listeners:
Instantiate the collection inside the constructor:
Now define two new public methods so that client objects can register themselves as listeners:
- The above methods simply delegate to the
add()andremove()methods of the collection
Define a private helper method that notifies all registered listeners whenever a new zookeeper is added:
- The above method creates a
ZooKeeperEventand then iterates over each registered listener notifying them of the fact that a new zookeeper has been created
Modify the createZooKeeper() method to invoke fireZooKeeperCreated() once the ZooKeeper object has been added to the collection:
You can now define methods fireZooKeeperChanged() and fireZooKeeperRemoved(), each very similar to fireZooKeeperAdded():
Modify changeZooKeeper() and removeZooKeeper() to invoke the respective "fire" methods:
The purpose of ZooAdministrator maintaining a collection of listener objects is so that it need have no direct knowledge of any of the classes which are likely to want to be notified of when a zookeeper is created, changed or removed. In this way, your classes accomplish loose-coupling, meaning that they are not directly dependent upon any more classes than is strictly necessary.
The ZooKeeperList class can now be modified to implement the ZooKeeperListener interface (note you need to import virtualzoo.core.event):
If you click the glyph that appears to the left of the class declaration statement above, you can click the option to implement all abstract methods. The following code will appear:
NetBeans generated the statements to throw an UnsupportedOperationException merely so that the code will compile. It is up to you to replace these lines with the actual code that should occur in response to the events. In all three cases you simply want the data in the list model (held in the ZooKeeperListModel inner class) to be reloaded. To do this you can invoke the loadModel() method from within the event listener methods, so make the following modifications:
You now need to wire up the ZooKeeperList object which is referenced in ZooKeeperPanel so that it listens to events. In ZooKeeperPanel define a new instance variable to reference the ZooAdministrator object (you need to import import virtualzoo.core):
Now change the constructor to obtain the ZooAdministrator object add call its addZooKeeperListener() method:
You can now run the application, enter and save one (or several) zookeepers, and you should find the list automatically updates itself:
It would be better to clear the editor form after adding a new zookeeper ready for adding a new one, so add a call to clearZooKeeper() in the saveButtonActionPerformed() method of ZooKeeperEditor:
Verify that the form gets cleared after successfully adding a new zookeeper.