In the first method, a command string is associated with a button and delivered to the ActionListener via the ActionEvent object. The target object implements the ActionListener interface, and the AWT framework will call the actionPerformed method when the button is pressed. The target application object, in its actionPerformed method, may fetch this string from the event object and perform whatever function is requested. Disadvantages of this method include the need to insure the strings match in the GUI and target classes. Also, as the amount of functionality to be exposed in this manner evolves, the target class may require modification, again providing an opportunity for errors. An "adapter" subclass of the base target class can be made, however then the subclass must be instantiated when the objects are created, forcing changes in other code. Example Code.
A better method that avoids this problem is to create and adapter class that contains the basic target object as shown in this example. The adapter class then parses the command string and invokes the requested operation. The original target class is not changed at all.
It turns out that in the 1.1 AWT only action events have associated command strings. So this delegation model may not be used for other events such as mouse moves, window events etc. A generalization of the adapter method is to create adapter objects with an associated command ID (which could be an integer or string or anything else) and target object instance. These objects implement the ActionListener interface, and when the actionPerformed method is called the ID is used to select the appropriate target method to invoke. This method still requires correlating the command IDs across various classes, but still does not touch the original target class. Example Code
The third method uses "Inner classes" within the GUI class to define an adapter class with the desired functionality on the fly. This can even be done in an anonymous manner, without even giving the inner class a name. And in fact the class declaration may be completely contained as an argument to a method call, providing a close approximation to method arguments in C/C++. This has the advantage that no correlation of command IDs across classes is required. Arbitrary functions may be performed and added without touching the target class or an adapter class. Disadvantages are that more lines of code are required than in the first case. A potentially more serious disadvantage is there is code bloat not only in the number of lines, but each one of these inner classes will generate a separate .class file. And a large application may generate a number of exactly identical inner classes that are separately defined, rather than reused. It remains to be seen whether this will have a significant performance penalty. Example Code.
The personal preference of the author is the dedicated adapter class with inner classes used in special cases where necessary. Such a special case might be for complicated and unique or rarely used functions that need not clutter up the basic adapter class.
by patrick@fnal.gov