/* * ATM Example system - file SimKeyboard.java * * copyright (c) 2001 - Russell C. Bjork * */ package simulation;import java.awt.*;import java.awt.event.*;/** Simulate the keyboard portion of the customer console */class SimKeyboard extends Panel{    /** Constructor     *     *  @param display the display on which to echo typed input     *  @param envelopeAcceptor - to be notified if cancel is pressed     */    SimKeyboard(SimDisplay display,                SimEnvelopeAcceptor envelopeAcceptor)    {        this.display = display;        this.envelopeAcceptor = envelopeAcceptor;                setLayout(new GridLayout(5,3));                // Create the keys representing digits                Button [] digitKey = new Button[10];        for (int i = 1; i < 10; i ++)        {             digitKey[i] = new Button("" + i);            add(digitKey[i]);        }                add(new Label(""));                digitKey[0] = new Button("0");        add(digitKey[0]);                add(new Label(""));                // Create the function keys                Button enterKey = new Button("ENTER");        enterKey.setForeground(Color.black);        enterKey.setBackground(new Color(128, 128, 255)); // Light blue        add(enterKey);                Button clearKey = new Button("CLEAR");        clearKey.setForeground(Color.black);        clearKey.setBackground(new Color(255, 128, 128)); // Light red        add(clearKey);                Button cancelKey = new Button("CANCEL");        cancelKey.setBackground(Color.red);        cancelKey.setForeground(Color.black);        add(cancelKey);                // Add action listeners to each key                for (int i = 0; i < 10; i ++)            digitKey[i].addActionListener(new ActionListener() {                public void actionPerformed(ActionEvent e)                {                    digitKeyPressed(Integer.parseInt(e.getActionCommand()));                }            });                    enterKey.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e)            {                enterKeyPressed();            }        });        clearKey.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e)            {                clearKeyPressed();            }        });        cancelKey.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e)            {                cancelKeyPressed();            }        });                // Allow the user to use the regular keyboard instead of the awt keyboard        addKeyListener(new KeyAdapter() {            public void keyPressed(KeyEvent e)            {                char keyChar = e.getKeyChar();                int keyCode = e.getKeyCode();                if (keyChar >= '0' && keyChar <= '9')                {                    digitKeyPressed(keyChar - '0');                    e.consume();                }                else                {                    switch (keyCode)                    {                        case KeyEvent.VK_ENTER:                                                    enterKeyPressed();                            break;                                                    case KeyEvent.VK_CLEAR:                                                    clearKeyPressed();                            break;                                                    case KeyEvent.VK_CANCEL:                        case KeyEvent.VK_ESCAPE:                                                    cancelKeyPressed();                            break;                    }                    e.consume();                }            }        });        // Initialze mode and input buffer                currentInput = new StringBuffer();        mode = IDLE_MODE;    }        /** Read input from the keyboard     *     *  @param mode the input mode to use - one of the constants defined below.     *  @param maxValue the maximum acceptable value (used in MENU_MODE only)     *  @return the line that was entered - null if user pressed CANCEL.     */    synchronized String readInput(int mode, int maxValue)    {        this.mode = mode;        this.maxValue = maxValue;        currentInput.setLength(0);        cancelled = false;        if (mode == AMOUNT_MODE)            setEcho("0.00");        else            setEcho("");        requestFocus();                try        {            wait();        }        catch(InterruptedException e)        { }                this.mode = IDLE_MODE;                if (cancelled)            return null;        else            return currentInput.toString();    }        /** Handle a digit key     *     *  @param digit the value on the key     */    private synchronized void digitKeyPressed(int digit)    {        switch (mode)        {            case IDLE_MODE:                            break;                            case PIN_MODE:            {                currentInput.append(digit);                StringBuffer echoString = new StringBuffer();                for (int i = 0; i < currentInput.length(); i ++)                    echoString.append('*');                setEcho(echoString.toString());                break;            }                            case AMOUNT_MODE:            {                           currentInput.append(digit);                String input = currentInput.toString();                if (input.length() == 1)                    setEcho("0.0" + input);                else if (input.length() == 2)                    setEcho("0." + input);                else                    setEcho(input.substring(0, input.length() - 2) + "." +                        input.substring(input.length() - 2));                break;            }                        case MENU_MODE:            {                if (digit > 0 && digit <= maxValue)                {                    currentInput.append(digit);                    notify();                }                else                    getToolkit().beep();                break;            }                       }    }        /** Handle the ENTER key     */    private synchronized void enterKeyPressed()    {        switch(mode)        {            case IDLE_MODE:                            break;                            case PIN_MODE:            case AMOUNT_MODE:                            if (currentInput.length() > 0)                    notify();                else                    getToolkit().beep();                break;                                case MENU_MODE:                            getToolkit().beep();                break;        }    }                               /** Handle the CLEAR key     */    private synchronized void clearKeyPressed()    {        switch(mode)        {            case IDLE_MODE:                            break;                            case PIN_MODE:                            currentInput.setLength(0);                setEcho("");                break;                            case AMOUNT_MODE:                            currentInput.setLength(0);                setEcho("0.00");                break;                            case MENU_MODE:                            getToolkit().beep();                break;        }    }                               /** Handle the CANCEL KEY     */    private synchronized void cancelKeyPressed()    {        switch(mode)        {            case IDLE_MODE:                            // It is possible to press the cancel key when requested                // to insert an envelope - so notify the envelope acceptor                // of this fact (notification is ignored if acceptor is                // not waiting for an envelope)                                synchronized(envelopeAcceptor)                {                    envelopeAcceptor.notify();                }                            case PIN_MODE:            case AMOUNT_MODE:            case MENU_MODE:                            cancelled = true;                notify();        }    }                   /** Set the echo string displayed on the display     *     *  @param echo the text to set the echo to (the whole line)     */    private void setEcho(String echo)    {        display.setEcho(echo);    }        /** The display onto which to echo input     */    private SimDisplay display;        /** The envelope acceptor to notify if CANCEL is pressed while not awaiting     *  customer input     */    private SimEnvelopeAcceptor envelopeAcceptor;        /** Current input mode - one of the values defined below     */    private int mode;        /** Not currently reading input - ignore keys (except CANCEL)     */    private static final int IDLE_MODE = 0;        /** Read input in PIN mode - allow user to enter several characters,     *  and to clear the line if the user wishes; echo as asterisks     */    private static final int PIN_MODE = Simulation.PIN_MODE;        /** Read input in amount mode - allow user to enter several characters,     *  and to clear the line if the user wishes; echo what use types     */    private static final int AMOUNT_MODE = Simulation.AMOUNT_MODE;        /** Read input in menu choice mode - wait for one digit key to be pressed,     *  and return value immediately.     */    private static final int MENU_MODE = Simulation.MENU_MODE;        /** Current partial line of input     */    private StringBuffer currentInput;        /** Cancellation flag - set to true if user cancels     */    private boolean cancelled;        /** Maximum valid value - used in MENU_MODE only     */    private int maxValue;}                                       