SignalListener
interface which recieves signals.
SignalFetcher
class which implements SignalListener
and prints a message whenever a signal is received.
SignalSender
class which lets you attach any number of SignalListener
objects and send a signal to all of them; furthermore, when the signal is sent to each of the listeners, it is done in order based on a key value.
ArrayList
), and whenever a signal is generated, the signal generator simply goes through and calls a method to send the signal to each of the listener objects. Since many different types of classes might be interested in receiving a signal, the signal listener is typically just represented as an interface which is implemented by any interested classes.
When we send a signal, what does the signal look like? That depends. We may be sending something as simple as a numerical reading, or we have some kind of event object (like a mouse click which has coordinates of the click and information about which button was used). If we don't know in advance, it may make sense to use generics. This allows us to leave the type unspecified until we need it.
Another question is whether it makes a difference which order the listeners are called. Maybe it doesn't make a difference, in which case first-come-first-served would be good enough. But if it does make a difference, then it may make sense to include some key which shows the precedence between different listeners.
In this lab, we will build a signal generator and a signal listener, and we will do it with generics so that it can be applied to any signal type we want to send. Furthermore, we will make sure to sort the list of listeners as we add them by priority, so that we can ensure the order in which they are called.
Task:
First, let's create a listener interface. We will call this interface SignalListener
. The SignalListener
will have two generic type parameters associated with it: the first is the type for the key, which is used to prioritize listeners when they're added to the signal generator. The second is the type of the object which is sent over whenever a signal is sent. So if we were to declare the variable SignalListener<Integer, String> listener
, then listener
is prioritized by an Integer
key and the signals which are sent to it are String
s. The interface should have two methods: a getKey()
call which returns the key value; and a signal(signalvalue)
call which does not return anything, and takes a single parameter of the signal object's type.
Second, we will implement the SignalListener
interface in the SignalFetcher
class, which also has two generic type parameters. This class's primary purpose is to print messages whenever a signal is recieved. It must have: a one-parameter constructor which allows us to initialize the key value; the getKey()
method required by the interface; a toString()
method which gives the word "listener"
followed by a space followed by the toString()
value of the key; and the signal message, which prints a message in the following format whenever it receives a signal:
listener key's_toString() received signal signalvalue's_toString()
SignalSender
. Like the other classes and interfaces in this project, the SignalSender
is generic and has two generic type parameters, the key type and the signal type. This class will allow you to add new listeners, which will put them in a list. Also, it will have a method to send a signal to all registered listeners (all listeners which are in the list). We want the signal to be sent to each listener in order by the signal's key value, which means that the listeners should be sorted at some point. Any sorting algorithm (or built-in sorting method) may be used for this. The methods which you are responsible for are: a default constructor (no parameters); an addSignalListener(listener)
method which takes an appropriate SignalListener
object as a parameter (and does not return anything), and adds the listener to the list; and a sendSignal(signalvalue)
method which sends the given signal to all registered listeners, in order by key.
Tip: since the signal listeners must be in order by key, it would make sense to require the key to be some kind of Comparable
type; this can be enforced within the declaration of the generic type parameters.
Example:
> SignalSender<Integer,String> generator = new SignalSender<Integer,String>();
> SignalListener<Integer,String> listener1 = new SignalFetcher<Integer,String>(1);
> SignalListener<Integer,String> listener2 = new SignalFetcher<Integer,String>(2);
> SignalListener<Integer,String> listener3 = new SignalFetcher<Integer,String>(3);
> generator.addSignalListener(listener3);
> generator.addSignalListener(listener1);
> generator.addSignalListener(listener2);
> generator.sendSignal("hello");
listener 1 received signal hello
listener 2 received signal hello
listener 3 received signal hello
Submission instructions are as follows.
xxx_yyyyyyyy_E12/
.java
files into the directory that you've created.ID.txt
in the format shown below, containing your name, userid, G#, lecture section
and lab section, and add it to the directory.
Full Name: Donald Knuth