import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

/** DemoKeyEvents - demo of event-driven programming using
* keyboard events.<p>
*
* This is a follow-on program to <code>DemoTranslateEnglish</code>.
* it is an example of <i>event-driven programming</i>.<p>
*
* <b>Event-driven programming.</b>
* All GUI applications use a programming strategy known as
* <i>event-driven programming</i>.
* Instead of the user synchronizing with the program
* (as with <i>sequential programming</i>), the program
* synchronizes with, or reacts to, the user.  Events
* are triggered by user actions such as
* manipulating the mouse, pressing mouse buttons, or
* pressing keys on the keyboard.<p>
*
* With JFC/Swing, events are handled through <i>event listeners</i>.
* Setting up a program to respond to events is a three-step
* process:<p>
*
* <ol>
* <li>The signature of the extended <code>JFrame</code> must include
* the clause "<code>implements</code> <i>listener</i>", where <i>listener</i>
* is the name of the appropriate listener.
* <li>An "add listener" method must be invoked on
* any component that is to listen for events.
* <li>The methods defined in the listener must be implemented
* in the extended <code>JFrame</code>.
* </ol>
*
* This program demonstrates the above three steps using
* a text field that "listens for" keyboard events.  For step 1,
* we use the clause <code>implements KeyListener</code>.  For step 2,
* we use the method <code>addKeyListener</code>.  For step 3,
* we provide an implementation of each of the three methods
* defined in <code>KeyListener</code>.  These are
* <code>keyPressed</code>, <code>keyReleased</code>, and
* <code>keyTyped</code>.<p>
* 
* Note that the <code>addKeyListener</code> method requires one
* argument, a <code>KeyListener</code> object.  Since our
* extended <code>JFrame</code> "<code>implements KeyListener</code>", we
* simply include <code>this</code> -- a reference to our
* extended <code>JFrame</code> -- as the argument.<p>
*
* When the user enters text in the text field, a key event is
* triggered on each keystroke.  One or more of the <code>KeyListener</code>
* methods will execute.  The response
* varies depending on the key.  For example,
* symbol keys, such as "A", are treated differently
* than modifier keys, such as SHIFT.  One of the best ways to
* appreciate the difference is by executing this program and
* observing the behaviour for various keystrokes.<p>
*
* Each of the <code>KeyListener</code> methods receives
* a single arugment, a <code>KeyEvent</code> object.  In the
* method implementations, the <code>KeyEvent</code> object
* is used to determine several things, such as the source
* of the event (if, for example, more than one text field
* is registered to listen for key events), or the code or
* character corresponding to the keystroke that triggered
* the event.<p>
*
* The implementation of the three <code>KeyListener</code> methods
* is very simple: A message is sent to the console
* containing the string returned by the <code>paramString</code> method
* of the <code>KeyEvent</code> class.  The parameter string contains
* the key code, key character, and modifier keys (e.g., CTRL).<p>
*
* In addition, this program demonstrates how to trap <i>high-level events</i>
* (aka <i>semantic events</i>) using the <code>Keystroke</code> class.
* In the <code>keyPressed</code> method, we define a constant as follows:
* <p>
*
* <pre>
*     final KeyStroke ALT1 = Keystroke.getKeyStroke(KeyEvent.VK_1, KeyEvent.ALT_MASK);
* </pre>
*
* The constant <code>ALT1</code> represents the key sequence
* ALT-1, entered on the keyboard by pressing and holding the ALT
* modifier key
* while pressing "1".  When the <code>keyPressed</code> method executes,
* we build a similar <code>KeyStroke</code> object (except using the
* values returned by <code>getKeyCode</code> and <code>getModifiers</code>)
* and test if the two are
* equal.  If so, an appropriate message is sent to the console and a beep
* is sounded on the system speaker.  The beep is generated as follows:<p>
*
* <pre>
*     Toolkit.getDefaultToolkit().beep();
* </pre>
*
* or as
*
* <pre>
*     System.out.print("\07"); 
*     System.out.flush();
* </pre>
*
* Semantic events are discussed in more detail in
* <code>DemoActionEvents</code>.<p>
*
* Screen snap...<br>
* <center><img src="DemoKeyEvents-1.gif"></center><p>
*
* @see <a href="DemoKeyEvents.java">source code</a>
* @author Scott MacKenzie, 2003
*/
public class DemoKeyEvents
{
   public static void main(String[] args)
   {
      DemoKeyEventsFrame frame = new DemoKeyEventsFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setTitle("DemoKeyEvents");
      frame.pack();
      frame.show();
   }
}

class DemoKeyEventsFrame extends JFrame implements KeyListener
{
   private JTextField enterField;

   // constructor

   public DemoKeyEventsFrame()
   {
      // ----------------------------------
      // construct and configure components
      // ----------------------------------

      enterField = new JTextField(10);

      // -------------
      // add listeners
      // -------------

      enterField.addKeyListener(this);

      // ------------------
      // arrange components
      // ------------------

      // add components to panel
      
      JPanel panel = new JPanel();
      panel.add(new JLabel("Enter some text:"));
      panel.add(enterField);
      panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

      // make panel this JFrame's content pane

      this.setContentPane(panel);
   }

   // ---------------------------------
   // implement KeyListener methods (3)
   // ---------------------------------

   public void keyPressed(KeyEvent ke)
   {
      System.out.println(ke.paramString());

      final KeyStroke ALT1 = KeyStroke.getKeyStroke(KeyEvent.VK_1, KeyEvent.ALT_MASK);
      KeyStroke k = KeyStroke.getKeyStroke(ke.getKeyCode(), ke.getModifiers());
      if (k == ALT1)
      {
         System.out.println("ALT-1 pressed!");
			// the following should beep, but doesn't.  Related to XP?
         //Toolkit.getDefaultToolkit().beep(); 

			// next two lines are a work-around 
			System.out.print("\07"); 
			System.out.flush();
      }
   }

   public void keyReleased(KeyEvent ke)
   {
      System.out.println(ke.paramString());
   }

   public void keyTyped(KeyEvent ke)
   {
      System.out.println(ke.paramString());
   }
}

