JaVa
   

Reading Keyboard Input

In this example we learn how to recognize keyboard events and relative information associated with them. The following example, SimpleKeyboard.java, is an applet program that displays information about keyboard events.

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class SimpleKeyboard extends JApplet implements KeyListener
{
 public void init()
 {
 getContentPane().setLayout(null);
 setSize(250,200);
 addKeyListener(this);
 }
 public void start()
 {
 lastKeyEvent = null;
 requestFocus();
 }
 public void paint(Graphics g)
 {
 g.setColor(Color.black);
 g.fillRect(0,0,250,200);
 g.setColor(Color.white); g.drawString("Example: Simple Keyboard",50,20);
 g.drawString("Press a key",90,165);
 if(lastKeyEvent!=null)
 { g.drawString("Key description:",30,65);
 g.drawString(lastKeyEvent.getKeyText(lastKeyEvent
 .getKeyCode()),120,65);
 g.drawString("Key character:",30,80);
 g.drawString(String.valueOf(lastKeyEvent
 .getKeyChar()),120,80);
 g.drawString("Key code:",30,95);
 g.drawString(String.valueOf(lastKeyEvent
 .getKeyCode()),120,95);
 g.drawString("Is an Action key:",30,110);
 g.drawString(String.valueOf(lastKeyEvent
 .isActionKey()),120,110);
 g.drawString("Modifier keys:",30,125);
 g.drawString(lastKeyEvent.getKeyModifiersText
 (lastKeyEvent.getModifiers()),120,125);
 } }
 public void keyPressed(KeyEvent e)
 {
 lastKeyEvent = e;
 repaint();
 }
 // The methods keyReleased(..) and KeyTyped(..) inherited // from KeyListener interface // must be defined, but we can ignore them if we choose
 public void keyReleased(KeyEvent e) { // ignore
 }
 public void keyTyped(KeyEvent e)
 {
 // ignore
 }
 private KeyEvent lastKeyEvent;
}


Now run the example and hold down the Shift key at the same time as the r key on the keyboard. When this is done, the output should look the same as the following screen shot. (Note that you may need to click on the applet with the mouse to gain the keyboard focus when running in a web browser if the focus is lost to another aspect of the browser—e.g., the address bar.) Notice that the key character is an uppercase R. This is because the Caps Lock is turned off on the keyboard, and holding down Shift turns lowercase to uppercase, and vice versa.

Java ScreenShot
Screenshot-1:

The SimpleKeyboard class implements the interface KeyListener, which means that it must provide functionality for the three methods declared in the KeyListener interface: keyPressed, keyReleased, and keyTyped. The KeyListener interface can be implemented by any classes that you want; we did not need to choose the main applet class but could have made a separate class for handling the key events just as easily. But it is common sense to handle the key events in the object concerned. Use the identifier lastKeyEvent to reference the newly received keyboard events, which are then accessed in the paint method. When we retrieve new key events, we also call the repaint method for the applet so that it can refresh itself. This is a quick-fix way to update the display. We'll look into handling events in a proper graphics processing main loop a little later. We add the key listener to listen to our main class instance in the init method, which is called when the applet is loaded with the following line of code:

addKeyListener(this);


This adds a key listener object to our main applet object (a key listener object being an object that implements the KeyListener interface and therefore provides functionality for the event handling methods). In this line of code, we declare that our main applet component itself will be used as the key listener and will therefore handle the events itself. Once this line of code is added, the event thread, invoking the appropriate listener method, such as keyPressed, will report any key events that occur while the main applet has focus. However, the Event Dispatch Thread is another thread separate from the main loop thread. This means trouble, as when an event occurs, it will interrupt your main loop and invoke one of the event handling methods. We will discuss why this is a problem in more detail and will make an all-effective callback routine to handle this problem a little later, integrating received events with the main loop thread. For now, however, we will concentrate on retrieving relevant information from these events. In the paint method in the previous example, we get hold of the KeyEvent lastKeyEvent, and display five attributes associated with that event. The first attribute is a text description of the key that has been pressed, returned from the method getKeyText (e.g., HOME, DELETE, C, etc.). This method requires one parameter, which is the key code of the key that has been pressed. The next attribute is the character associated with the key pressed, returned from the method getKeyChar. The third attribute is the key code of the key pressed, returned from the method getKeyCode. The KeyEvent class contains a large list of static key codes using plain text identifiers beginning with VK_ (virtual key) and then the string description of the key pressed. For example, we could add the following switch statement to identify key presses for the keys E, t, Escape, and Home in the keyPressed method.

public void keyPressed(KeyEvent e)
{
 lastKeyEvent = e;
 repaint();
 switch(e.getKeyCode())
 {
 case KeyEvent.VK_E:
 // handle event of (uppercase) key 'E' being pressed
 break;
 case KeyEvent.VK_T:
 // handle event of (lowercase) key 't' being pressed
 break;
 case KeyEvent.VK_ESCAPE:
 // handle event of ESCAPE key being pressed
 break;
 case KeyEvent.VK_HOME:
 // handle event of HOME key being pressed
 break;
 default:
 // Do nothing or inform user about invalid key
 break;
 }
}


In this code snippet we are also looking for an uppercase E and a lowercase t. The key codes are not case sensitive. Therefore, in order to determine if the key pressed was uppercase or lowercase, we need to use the method discussed earlier, getKeyChar, which will return the character value of type char with case sensitivity.

case KeyEvent.VK_T:
 if(e.getKeyChar() == 't')
 System.out.println("Lowercase t was pressed);
break;


Note that in this example (as you know, the key pressed was the t key anyway), you could just as easily use the static method Character.isLowerCase(e.getKeyChar()) to check the case, which returns a Boolean result. The fourth attribute in the paint method in the previous example is a Boolean value, true or false, retrieved from the method isActionKey. Examples of action keys are F1-F12, Insert, Left, Right, etc. The fifth and final attribute associated with the key event is the modifier key or keys, such as Alt or Ctrl+Shift. This string value is returned from the method getKeyModifiersText, which takes one integer parameter: the modifier's flag for the event. The modifier's flag is retrieved as a return value of getModifiers, a method inherited by KeyEvent from its super class InputEvent. The modifier value simply holds bitwise information about the event. We will need these modifiers in order to obtain information about which mouse button was pressed a little later in the chapter.

There is no distinct difference in using the key and mouse listeners in an applet or in an app. In an app, we would have added the key listener to the main JFrame, and our main JFrame would also have implemented the KeyListener interface if we chose for it to. To keep our mutual app and applet approach, we will use an app for the upcoming mouse example.

JaVa
   
Comments