<HTML>
<HEAD>

<!-- Change the Title please -->
<TITLE>AWT SHORT COURSE: NestedEvent</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="NestedPanels.html"><img border=0 src="/developer/images/magelang/previous.gif" hspace=10 alt="Previous" width=64 height=20></a>
</td>
<td>
<a href="Events.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="Nested Containers and The Event Chain">
<font size=+1><b>Nested Containers and The Event Chain</b></font><P>
</a>

<p>
When creating compound components, how is event handling affected and how can the constituent components communicate with components in the applet or other containers?  Consider using the KeyPad to flip through a set of slides.  The main applet will have a KeyPad and a SlideViewer that are laid out next to each other with the default FlowLayout.  The SlideViewer will be a compound Component containing a series of slides laid out using CardLayout. Here is the running SlideShow applet:

<p>
<center>
<hr>
<applet code=SlideShow CODEBASE="/applets/magelang/AWT-Training/Examples/" width=200 height=100>
</applet>
<hr>
</center>

<p>
How can you get the KeyPad to flip through the slides in the CardLayout?  We define an interface called KeyPadObserver that allows an object to be notified when a key has been pressed:

<p>
<tt><pre>
interface KeyPadObserver {
    public void pressed(String key);
}
</pre></tt>

<p>
The interface allows the KeyPad to be more general.  An arbitrary object that implements this interface can then be attached to a new version of the KeyPad called KeyPadWithObserver:

<tt><pre>
class KeyPadWithObserver extends Panel {
    String[] keys = { "1","2","3",
                      "4","5","6",
                      "7","8","9",
                      "*","0","#" };
    Button[] b = new Button[keys.length];
    KeyPadObserver observer;
    public KeyPadWithObserver(KeyPadObserver o) {
        observer = o;
        setLayout(new GridLayout(4,3));
        for (int i=0; i&ltkeys.length; i++) {
            b[i] = new Button(String.valueOf(keys[i]));
            add(b[i]);
        }
    }
    public boolean action(Event e, Object arg) {
        observer.pressed((String)arg);
        return true;
    }
}
</pre></tt>

<p>
A KeyPadObserver is passed to KeyPadWithObserver during construction. Then, upon key press (the action method is called), a KeyPadWithObserver can notify the observer.  Events generated by a key are handled in KeyPadWithObserver rather than handling them in the SlideShow applet.  The following containment hierarchy demonstrates the event chain when Button 2 on the KeyPadWithObserver is pushed:

<p>
<center>
<img src=./images/keyobserv.gif>
</center>

<p>
The SlideViewer is nothing but a Panel managed by CardLayout that implements the KeyPadObserver interface.  The SlideViewer is designed so that the slides can be specified as an array of arbitrary Component objects:

<tt><pre>
class SlideViewer extends Panel implements KeyPadObserver {
    CardLayout layout;
    public SlideViewer(Component[] comps) {
        layout = new CardLayout();
        setLayout(layout);
        for (int i=0; i&ltcomps.length; i++) {
            // set the key of component to the index
            add(String.valueOf(i+1), comps[i]);
        }
    }
    public void pressed(String key) {
        layout.show(this, key);
    }
}
</pre></tt>

<p>
The pressed method is called by the KeyPadWithObserver object when a key is pressed via:

<tt><pre>
observer.pressed((String)arg);
</pre></tt>

<p>
When the KeyPadWithObserver object is created by the SlideShow applet, the SlideViewer is passed as the KeyPadObserver.  SlideShow does nothing but create a set of slides, a SlideViewer, and a KeyPadWithObserver that is attached to the SlideViewer.

<tt><pre>
import java.awt.*;
import java.applet.Applet;

public class SlideShow extends Applet {
    Component[] slides = {    new Label("Slide 1"),
                              new Button("Slide 2"),
                              new TextField("Slide 3"),
                              new TextField("Slide 4"),
                              new Label("Slide 5"),
                              new Label("Slide 6"),
                              new Label("Slide 7"),
                              new Label("Slide 8"),
                              new Label("Slide 9") };
    public void init() {
        SlideViewer sv = new SlideViewer(slides);
        KeyPadWithObserver keypad = new KeyPadWithObserver(sv);
        add(keypad);
        add(sv);
    }
}
</pre></tt>

<p>
Note that that there are only nine slides.  Buttons "*", "0", and "#" will not affect the SlideViewer.

<p>
Related exercise:
<ul>
<LI><A HREF="../Exercise/FormElement/index.html"> FormElement</A>
</ul>
</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>
