import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
import java.lang.reflect.*;

public class UmApplet extends Applet 
{
	Frame janela;
	Checkbox interruptor;
	TextArea texto;
	
	public void init() {
		setLayout(new BorderLayout());
		add("North",new Label("Ouvindo eventos de outra janela...",Label.CENTER));
		
		texto = new TextArea(10,60);
		add("Center",texto);	
		
		SuperOuvinte o = new SuperOuvinte(this);
		
		janela = new GUIWindow();
		janela.setTitle("Uma janela do tutorial");
		janela.pack(); janela.show();	
		
		o.bisbilhotarHV(janela); // visita toda a hierarquia visual...
		
		Panel baixo = new Panel();
		add("South",baixo);
		baixo.add(new Label("Ouvindo " + o.bisbilhotices + " tipos evento de "+o.componentes+ " fontes"));
		
		interruptor=new Checkbox("Activo",false);
		baixo.add(interruptor);
	}
}

class SuperOuvinte implements
	ActionListener,AdjustmentListener,ComponentListener,
	ContainerListener,FocusListener,ItemListener,KeyListener,MouseListener,
	TextListener,MouseMotionListener,WindowListener	{   // vamos querer TODOS os eventos!
 	
 	UmApplet mostrador;
 	int bisbilhotices=0; int componentes=0;
 	
 	SuperOuvinte(UmApplet x) {
 		mostrador=x;
 	}
 	
 	void mostra(AWTEvent e) {
 		if (mostrador.interruptor.getState()) 
 			mostrador.texto.append(e.toString()+"\n");
 	}
 	
 	// Seguem-se transcrições das 11 interfaces xxxxListener:
	public void actionPerformed(ActionEvent e) {mostra(e);}
	
	public void adjustmentValueChanged(AdjustmentEvent e){mostra(e);}
	
	public void componentResized(ComponentEvent e){mostra(e);}
	public void componentMoved(ComponentEvent e){mostra(e);}
	public void componentShown(ComponentEvent e){mostra(e);}
	public void componentHidden(ComponentEvent e){mostra(e);}
	
	public void componentAdded(ContainerEvent e){mostra(e);}
	public void componentRemoved(ContainerEvent e){mostra(e);}
	
	public void focusGained(FocusEvent e){mostra(e);}
	public void focusLost(FocusEvent e){mostra(e);}
	
	public void itemStateChanged(ItemEvent e){mostra(e);}
	
	public void keyTyped(KeyEvent e){mostra(e);}
	public void keyPressed(KeyEvent e){mostra(e);}
	public void keyReleased(KeyEvent e){mostra(e);}
	
	public void mouseClicked(MouseEvent e) {mostra(e);}
    public void mousePressed(MouseEvent e) {mostra(e);}
    public void mouseReleased(MouseEvent e) {mostra(e);}
    public void mouseEntered(MouseEvent e) {mostra(e);}
    public void mouseExited(MouseEvent e) {mostra(e);}
    
    public void mouseDragged(MouseEvent e){mostra(e);}
    public void mouseMoved(MouseEvent e){mostra(e);}
    
    public void textValueChanged(TextEvent e){mostra(e);}

    public void windowOpened(WindowEvent e) {mostra(e);}
    public void windowClosing(WindowEvent e) {mostra(e);}
    public void windowClosed(WindowEvent e) {mostra(e);}
    public void windowIconified(WindowEvent e) {mostra(e);}
    public void windowDeiconified(WindowEvent e) {mostra(e);}
    public void windowActivated(WindowEvent e) {mostra(e);}
    public void windowDeactivated(WindowEvent e) {mostra(e);}
    
    // visita a hierarquia, aplicando outro método para cada nó:
    void bisbilhotarHV(Component c) {
		bisbilhotarUm(c);
		if (c instanceof Container) {
			Container cc = (Container)c;
			for (int i=0; i<cc.getComponentCount(); i++)
				bisbilhotarHV(cc.getComponent(i));
		}
    }
    
    /* Aviso: segue-se material eventualmente chocante, extra-cadeira :) */
    
    void bisbilhotarUm(Component c) {
    	tenta(c,"addActionListener","java.awt.event.ActionListener");
    	tenta(c,"addAdjustmentListener","java.awt.event.AdjustmentListener");
    	tenta(c,"addComponentListener","java.awt.event.ComponentListener");
    	tenta(c,"ContainerListener","java.awt.event.ContainerListener");
    	tenta(c,"addFocusListener","java.awt.event.FocusListener");
    	tenta(c,"addItemListener","java.awt.event.ItemListener");
    	tenta(c,"addKeyListener","java.awt.event.KeyListener");
    	tenta(c,"addMouseListener","java.awt.event.MouseListener");
    	tenta(c,"addMouseMotionListener","java.awt.event.MouseMotionListener");
    	tenta(c,"addTextListener","java.awt.event.TextListener");
		tenta(c,"addWindowListener","java.awt.event.WindowListener");
		componentes++;
    }

    void tenta(Object fonte,String nomeMetodo,String classeArgumento){
    	Class argumentosFormais[] = new Class[1]; Method metodo = null;
    	Object argumentos[] = new Object[1];
    	try {
    		argumentosFormais[0]=Class.forName(classeArgumento);
    		metodo = fonte.getClass().getMethod(nomeMetodo,argumentosFormais);
    		argumentos[0]=this;
    		metodo.invoke(fonte,argumentos);
    		bisbilhotices++;
    	}
    	catch (Exception e) {}
    }
}