<HTML>
<HEAD>

<!-- Change the Title please -->
<TITLE>AWT SHORT COURSE: EncapsulatingBehavior</TITLE>
</HEAD>

<!-- BODY-TEMPLATE -->

<!-- NAVBAR-PULLQUOTE-TEMPLATE -->
<TR VALIGN=TOP>
<td width=178>

<BR clear=LEFT>
<TABLE ALIGN=LEFT>
<TR VALIGN=TOP>
<td width=60>
<a href="../TOC.html"><img border=0 src="/developer/images/magelang/contents.gif" alt="contents" WIDTH=147 HEIGHT=23></a>
</td>
</tr>
<tr>
<td>
<a href="ActionEvents.html"><img border=0 src="/developer/images/magelang/previous.gif" hspace=10 alt="Previous" width=64 height=20></a>
</td>
<td>
<a href="Colors.html"><img border=0 src="/developer/images/magelang/next.gif" alt="Next" width=43 height=20></a>
</td>
</tr>
</table>

</TR>
</TABLE>

<!-- PAGETOP-TEMPLATE -->
<TR>
<TD WIDTH=452 ALIGN=RIGHT>
<img src=images/ShortCourse.gif>
</TD>
</TR>
<TR>
<TD WIDTH=452 COLSPAN=2 ALIGN=right>
<!--breadcrumb trail; change to reflect the current URL-->
<!-- Please change to reflect where _exactly_ you are in the site
<!-- Add more subcategories as needed  -->

<!-- Please Change these.  The Links are SubCat#, and titled SubCategory# -->
</TD>
</TR>

<!--- Please put everything you want here to the right of the navbar.
	<TR>
	<TD>
	This is the MAIN TABLE.  Put data HERE unless you need a table that
 	REQUIRES the full screen width, i.e. an event schedule table.
	Add a new table row for the data.

	If the text needs to be in two columns, use this <TR> structure:
	Make the width=452
	<TR>
	<TD WIDTH=226>
	</TD>
	<TD WIDTH=226>
	</TD>
	</TR>

	</TD>
	</TR>
--->

<TR>
<TD width=452>
<p>
<a name="Encapsulating Behavior in Components">
<font size=+1><b>Encapsulating Behavior in Components</b></font><P>
</a>

Applets that do not handle events in the individual components generally end up with an action method with a big switch statement that must handle events for all components contained in the applet.  A better solution is to have components handle their own events.  Then, when a Component is activated, it can notify any other object that needs to know about its state change.

<p>
The first way to handle events locally to a Component requires that we subclass the Component and override the mouseDown action, or whatever the event of interest is.  For example, creating a Button that handles an action is straightforward:

<tt><pre>
class OkButton extends Button {
    public boolean action(Event e, Object arg) {
        // desire behavior
    }
}
</pre></tt>

<p>
This approach encapsulates the required behavior within the Button object, but requires that we create a new class for each new behavior--a tedious proposition considering how many components a typical GUI has.  Further, the behavior of a Component cannot be changed at runtime.

<p>
A better solution involves Component observers that allow you to create a single subclass for each Component regardless of the number of different components needed for a GUI.  For example, an object that wants to be notified upon a button press could define a ButtonObserver:

<tt><pre>
interface ButtonObserver {
    public void pressed();
}
</pre></tt>

<p>
Then, a special Button could be defined to notify a ButtonObserver:

<tt><pre>
class ButtonWithObserver extends Button {
    ButtonObserver observer;
    ButtonWithObserver(String label, ButtonObserver o) {
        super(label);
        observer = o;
    }
    public boolean action(Event e, Object arg) {
        observer.pressed();
        return true;
    }
}
</pre></tt>

<p>
This approach has the additional benefit that the event-handling behavior can be changed at runtime by changing the observer field.

<p>
Here is an applet that employs ButtonObserver and ButtonWithObserver:

<p>
<center>
<hr>
<applet code=ButtonEventTest.class CODEBASE="/applets/magelang/AWT-Training/Examples/" width=50 height=50></applet>
<hr>
</center>

<p>
Corresponding source code:

<tt><pre>
import java.applet.*;
import java.awt.*;
public class ButtonEventTest extends Applet
             implements ButtonObserver {
    public void init() {
        ButtonWithObserver b = new ButtonWithObserver("OK", this);
        add(b);
    }
    public void pressed() {
        getGraphics().drawString("Pressed", 0, 40);
    }
}
</pre></tt>

<p>
The applet itself is considered the button observer and, hence, we pass <tt>this</tt> to the ButtonWithObserver constructor and implement method pressed in ButtonEventTest.  The applet itself is notified when Button b has been pressed.
</TD>
</TR>
</TABLE>

<!--
        This table is for everything that goes under the 
        navbar, it is a full screen table. Use this table 
        ONLY for full screen width tables like an event 
        hourly schedule.
-->

<br clear=left>
<TABLE ALIGN=left>

<tr>
<td WIDTH=600 align=right>

<!--Last Modified and copyright message

    Please modify the date whenever significant changes are made to 
    a page; leave the copyright alone
-->

</td>
</tr>
</TABLE>

</BODY>
</HTML>
