Technical Support
Discussion Forum
Online Training
Read About Java
Java In-Depth
Product Discounts
Membership Information

Java Cup Logo

JDC Home Page


Top
Back
Next
Online Training
shadowSearchFAQFeedback

Nested Containers and The Event Chain

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:



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:

interface KeyPadObserver {
    public void pressed(String key);
}

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:

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<keys.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;
    }
}

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:

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:

class SlideViewer extends Panel implements KeyPadObserver {
    CardLayout layout;
    public SlideViewer(Component[] comps) {
        layout = new CardLayout();
        setLayout(layout);
        for (int i=0; i<comps.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);
    }
}

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

observer.pressed((String)arg);

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.

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);
    }
}

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

Related exercise: