import java.applet.*; import java.awt.*; import java.awt.event.*; public class AppletNumericTextFieldProcessKeyEvent extends Applet implements ActionListener { private NumericTextField numberField; private Button clear; public void init() { // Set the size and background color of the applet setSize(300, 100); setBackground(Color.CYAN); // Set the layout manager for the applet setLayout(new FlowLayout()); // Create an instance of the 'NumericTextField' class and add it to the applet numberField = new NumericTextField(10); add(numberField); // Create an instance of a 'Button', add it to the // applet, and then "listen" for it to be pressed clear = new Button("Clear"); add(clear); clear.addActionListener(this); } public void actionPerformed(ActionEvent ae) { Button source = (Button) ae.getSource(); // If the button was pressed, clear the textfield // and then return the focus to the textfield if (source.getLabel() == "Clear") { numberField.setText(""); numberField.requestFocus(); } } // Extend the 'TextField' class to create a new type of 'TextField' that // accepts only numbers; provide the capability to use "key" events to // filter characters entered into the 'NumericTextField' object public class NumericTextField extends TextField { public NumericTextField(int cols) { // Superclass constructor calls must be the FIRST statement in a constructor super(cols); // Enable "key" events on all objects of the class; this allows the // 'processKeyEvent' method to be invoked when a key is pressed enableEvents(AWTEvent.KEY_EVENT_MASK); } // Note that this method is actually called THREE TIMES for each time that // a key is pressed (probably for KEY_PRESSED, KEY_RELEASED, KEY_TYPED); // it is overridden to provide the code needed to filter out non-numeric // characters without the need to instantiate a separate 'Listener' object public void processKeyEvent(KeyEvent e) { // Get and store the key that was pressed char keyChar = e.getKeyChar(); // To avoid having the pressed key processed three times (see above), // 'KEY_TYPED' is used here because it represents key-down and key-up; // since key-down occurs before all other key events, the key will // either be processed (and then cleared) or changed into an illegal // character (below) so that it will be rejected when processed again if (e.getID() == KeyEvent.KEY_TYPED) { // Accept digits (0 - 9), decimal points (.), // negative signs (-), BACKSPACE, and DELETE if (((keyChar >= '0') && (keyChar <= '9')) || (keyChar == '.') || (keyChar == '-') ||(keyChar == 8) || (keyChar == 127)) { // Since the 'processKeyEvent' method has been overridden, the same // method should be invoked in the superclass by passing the event // object (the character) as a parameter; this ensures that all // necessary default processing occurs super.processKeyEvent(e); } else { // If the key is not one of the accepted characters, change it to an // illegal character (for the textfield) so that it will be rejected // and the user will hear a system beep e.setKeyChar('\000'); } } } } }