import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;

/**
 * Demo program to show many of the awt/swing events that
 * are generated/consumed. Illustrates XXXListeners for several
 * types of events including semantic events (e.g., ActionEvent)
 * and low-level events (e.g., FocusEvent)
 *
 * This code is meant to be fuctional rather than elegant, though
 * hopefully elegance is present to some degree.
 *
 * @author Owen Astrachan
 */

public class EventDemo extends JFrame
{
    private JButton    myButton;
    private JMenu      myMenu;
    private JTextField myTextField;
    private JTextArea  myTextArea;

    private ActionListener myActionListener;
    private KeyListener    myKeyListener;
    private MouseListener  myMouseListener;
    private MouseMotionListener myMouseMotionListener;
    private FocusListener myFocusListener;
    
    public EventDemo()
    {
        makeListeners();
        JPanel top = new JPanel();
        myButton = makeButton();
        top.add(myButton);
        myTextField = makeTextField();
        top.add(myTextField);
        JButton clear = new JButton("clear");
        clear.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent e)
                {
                    myTextArea.setText("");
                }
            });
        top.add(clear);

        myTextArea = new JTextArea(30,40); // rows and columns
        myTextArea.addMouseMotionListener(myMouseMotionListener);
        myTextArea.addMouseListener(myMouseListener);
        JScrollPane scroller = new JScrollPane(myTextArea);
        
        getContentPane().add(top, BorderLayout.NORTH);
        getContentPane().add(scroller, BorderLayout.CENTER);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        show();
    }

    private void makeListeners()
    {
        // create listeners using anonymous inner classes
        
        myActionListener = new ActionListener(){
                public void actionPerformed(ActionEvent e)
                {
                    echoAction(e);
                }
            };
        myKeyListener = new KeyListener(){
                public void keyPressed(KeyEvent e)
                {
                    echoKey("press",e);
                }
                public void keyReleased(KeyEvent e)
                {
                    echoKey("release",e);
                }
                public void keyTyped(KeyEvent e)
                {
                    echoKey("typed",e);
                }                                
            };

        myMouseListener = new MouseListener(){
                public void mouseClicked(MouseEvent e)
                {
                    echoMouse("mouse click",e);
                }
                public void mouseEntered(MouseEvent e)
                {
                    echoMouse("mouse enter",e);                    
                }
                public void mouseExited(MouseEvent e)
                {
                    echoMouse("mouse exit",e);                    
                }
                public void mousePressed(MouseEvent e)
                {
                    echoMouse("mouse press",e);                    
                }
                public void mouseReleased(MouseEvent e)
                {
                    echoMouse("mouse release",e);                    
                }
            };

        myMouseMotionListener = new MouseMotionListener(){
                public void mouseDragged(MouseEvent e)
                {
                    echoMotion("drag",e);
                }
                public void mouseMoved(MouseEvent e)
                {
                    echoMotion("move",e);
                }
            };

        myFocusListener = new FocusListener(){
                public void focusGained(FocusEvent e)
                {
                    echoOther("gain focus",e);
                }
                public void focusLost(FocusEvent e)
                {
                    echoOther("lose focus",e);
                }
            };
    }

    private void showText(String s)
    {
        myTextArea.append(s+"\n");
        myTextArea.setCaretPosition(myTextArea.getText().length());
    }

    private JTextField makeTextField()
    {
        myTextField = new JTextField(30);
        myTextField.addActionListener(myActionListener);
        myTextField.addKeyListener(myKeyListener);
        // myTextField.addMouseListener(myMouseListener);
        myTextField.addFocusListener(myFocusListener);
        return myTextField;
    }

    private JButton makeButton()
    {
        myButton = new JButton("clickme");
        myButton.addActionListener(myActionListener);
        myButton.addKeyListener(myKeyListener);
        myButton.addMouseListener(myMouseListener);
        return myButton;
    }

    /**
     * Echo key presses by showing important attributes
     */
    void echoKey(String s, KeyEvent e)
    {
        showText(s + " char:"+e.getKeyChar()+ " mod: " +
                 KeyEvent.getKeyModifiersText(e.getModifiers()) +
                 " mod: " + KeyEvent.getKeyText(e.getKeyCode()));
    }


    /**
     * Echo action events including time event occurs and string
     */
    void echoAction(ActionEvent e)
    {
        showText("action = "+e.getActionCommand()+" "+e.getWhen());
    }

    /**
     * Echo mouse events (enter, leave, etc., including position and buttons
     */
    void echoMouse(String s, MouseEvent e)
    {
        showText(s + " x = " + e.getX() + " y = " + e.getY() + " mod: "+
                 MouseEvent.getMouseModifiersText(e.getModifiers()) +
                 " button: "+e.getButton() + " clicks " + e.getClickCount());
    }

    /**
     * Echo mouse motion events
     */
    void echoMotion(String s, MouseEvent e)
    {
        echoMouse(s,e);
    }

    /**
     * Echo other events (e.g., Focus)
     */

    void echoOther(String s, AWTEvent e)
    {
        showText(s+" "+e);
    }

    public static void main(String[] args)
    {
        EventDemo demo = new EventDemo();
    }
}
