Hi,

how i can fix my code to support keyboard input?

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package calculater1;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.Container.*;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import java.awt.event.ActionListener;


/**
 *
 * @author al_khtaiob
 */
public class Calcu extends JFrame implements ActionListener{

        final int MAX_INPUT_LENGTH = 20;
    final int INPUT_MODE = 0;
    final int RESULT_MODE = 1;
    final int ERROR_MODE = 2;
    int displayMode;

    boolean clearOnNextDigit, percent;
    double lastNumber;
    String lastOperator ="0";

        private JLabel jlbOutput;
    private JButton jbnButtons[];
    private JPanel jplMaster, jplBackSpace, jplControl, jplButtons;


        Font f12 = new Font("Times New Roman", 0, 12);
    Font f121 = new Font("Times New Roman", 1, 12);

        public Calcu(){
            super("Simple Calculater");
            setBackground(Color.gray);

            //output label..
            jlbOutput = new JLabel("0");
            jlbOutput.setBackground(Color.WHITE);
            jlbOutput.setOpaque(true); //paints every pixel within the Jcomponent bounds

            //I've used border and grid layout to design this calculter
            getContentPane().add(jlbOutput, BorderLayout.NORTH);

            //input buttons..
            jbnButtons = new JButton[22];
            jplButtons = new JPanel();

            // Create numeric Jbuttons
        for (int i=0; i<=9; i++)
        {
            // set each Jbutton label to the value of index
            jbnButtons[i] = new JButton(String.valueOf(i));
        }

            //Operator Jbuttons
        jbnButtons[10] = new JButton(".");
        jbnButtons[11] = new JButton("=");
        jbnButtons[12] = new JButton("/");
        jbnButtons[13] = new JButton("*");
        jbnButtons[14] = new JButton("-");
        jbnButtons[15] = new JButton("+");
        jbnButtons[16] = new JButton("sqrt");
        jbnButtons[17] = new JButton("1/x");
        jbnButtons[18] = new JButton("%");


                //Controls Jbuttons

        jplBackSpace = new JPanel();// panel for the backSpace
        jplBackSpace.setLayout(new GridLayout(1, 1, 2, 2));

                Icon bug = new ImageIcon(getClass().getResource("pug1.GIF"));
        jbnButtons[19] = new JButton(bug);
        jplBackSpace.add(jbnButtons[19]);
                ////////////////////////////////////////////////////////////////
        jplControl = new JPanel();// panel for clear buttons
        jplControl.setLayout(new GridLayout(1, 2, 2 ,2));

        jbnButtons[20] = new JButton(" CE ");
        jbnButtons[21] = new JButton("C");

        jplControl.add(jbnButtons[20]);
        jplControl.add(jbnButtons[21]);
                ////////////////////////////////////////////////////////////////

                //panel for keypad buttons
                jplButtons.setLayout(new GridLayout(4, 5, 2, 2));

                //Add buttons to keypad panel starting at top left
        // First row
        for(int i=7; i<=9; i++)      {
            jplButtons.add(jbnButtons[i]);
        }

        // add button "/" and "sqrt"
        jplButtons.add(jbnButtons[12]);
        jplButtons.add(jbnButtons[16]);

        // Second row
        for(int i=4; i<=6; i++)
        {
            jplButtons.add(jbnButtons[i]);
        }

        // add button "*" and "x^2"
        jplButtons.add(jbnButtons[13]);
        jplButtons.add(jbnButtons[17]);

        // Third row
        for( int i=1; i<=3; i++)
        {
            jplButtons.add(jbnButtons[i]);
        }

        //adds button "-" and "%"
        jplButtons.add(jbnButtons[14]);
        jplButtons.add(jbnButtons[18]);

        //Fourth Row
        // add "0",".", "+", "="
        jplButtons.add(jbnButtons[0]);
        jplButtons.add(jbnButtons[10]);
        jplButtons.add(jbnButtons[15]);
        jplButtons.add(jbnButtons[11]);

                //Managing the Master panel contains all other panels with border layout
                jplMaster = new JPanel();
                jplMaster.setLayout(new BorderLayout());
        jplMaster.add(jplBackSpace, BorderLayout.WEST);// adding the BS at west
        jplMaster.add(jplControl, BorderLayout.EAST);// adding Controls at east
        jplMaster.add(jplButtons, BorderLayout.SOUTH);// adding Buttons at south

                //adding Master panel to south of the frame
                getContentPane().add(jplMaster, BorderLayout.SOUTH);
        requestFocus();// to make Master panel the focused Window, must be displayable, focusable, visible..

                  //Add ActionListener to the buttons
        for (int i=0; i<jbnButtons.length; i++){
            jbnButtons[i].addActionListener(this);
        }

               }//end of constructor

    public void actionPerformed(ActionEvent e) {

        double result = 0;
        // Search for the button pressed until end of array or key found
        for (int i=0; i<jbnButtons.length; i++)
        {
            if(e.getSource() == jbnButtons[i])
            {
                switch(i)
                {
                    case 0:
                        addDigitToDisplay(i);
                        break;

                    case 1:
                        addDigitToDisplay(i);
                        break;

                    case 2:
                        addDigitToDisplay(i);
                        break;

                    case 3:
                        addDigitToDisplay(i);
                        break;

                    case 4:
                        addDigitToDisplay(i);
                        break;

                    case 5:
                        addDigitToDisplay(i);
                        break;

                    case 6:
                        addDigitToDisplay(i);
                        break;

                    case 7:
                        addDigitToDisplay(i);
                        break;

                    case 8:
                        addDigitToDisplay(i);
                        break;

                    case 9:
                        addDigitToDisplay(i);
                        break;

//                  case 10:    //for decimal point
//                      processSignChange();
//                      break;
                                        case 10:    //for decimal point
                        addDecimalPoint();
                        break;

                    case 11:    //for =
                        processEquals();
                        break;

                    case 12:    //for divide
                        processOperator("/");
                        break;

                    case 13:    //for *
                        processOperator("*");
                        break;

                    case 14:    //for -
                        processOperator("-");
                        break;

                    case 15:    //for +
                        processOperator("+");
                        break;


                    case 16:    // sqrt
                        if (displayMode != ERROR_MODE)// شرط متحقق
                        {
                            try
                            {
                                                            //return error if sqrt for a negatine number..
                                if (getDisplayString().indexOf("-") == 0)
                                    displayError("Invalid input for function!");

                                result = Math.sqrt(getNumberInDisplay());
                                displayResult(result);
                            }

                            catch(Exception ex)
                            {
                                displayError("Invalid input for function!");
                                displayMode = ERROR_MODE;
                            }
                        }
                        break;

                    case 17:    // 1/x
                        if (displayMode != ERROR_MODE){
                            try
                            {
                                                            //retrun error msg if divided by 0
                                if (getNumberInDisplay() == 0)
                                    displayError("Cannot divide by zero!");

                                result = 1 / getNumberInDisplay();
                                displayResult(result);
                            }

                            catch(Exception ex) {
                                displayError("Cannot divide by zero!");
                                displayMode = ERROR_MODE;
                            }
                        }
                        break;

                    case 18:    // %
                        if (displayMode != ERROR_MODE){
                            try {
                                result = getNumberInDisplay() / 100;
                                displayResult(result);
                            }

                            catch(Exception ex) {
                                displayError("Invalid input for function!");
                                displayMode = ERROR_MODE;
                            }
                        }
                        break;

                    case 19:    //for  backspace
                        if (displayMode != ERROR_MODE){
                                                    //substring() Returns a new string that is a substring of Displayed String.
                            setDisplayString(getDisplayString().substring(0,
                                        getDisplayString().length() - 1));
                                                        //if the displayed string has only one number..
                            if (getDisplayString().length() < 1)
                                setDisplayString("0");
                        }
                        break;

                    case 20:    //for CE
                                            //to reset the displaying area..
                        clearExisting();
                        break;

                    case 21:    //for C
                                            //to clear the displayed area..
                        clearAll();
                        break;
                }
            }
        }

    }// end of action performed


    void setDisplayString(String s){
        jlbOutput.setText(s);
    }

    String getDisplayString (){
        return jlbOutput.getText();
    }

    void addDigitToDisplay(int digit){
            //empty in the begining
        if (clearOnNextDigit)// ture by defualt.. just for the first time will performed
            setDisplayString("");

        String inputString = getDisplayString();//تحتوي على الرقم المدخل من اليوزر

        if (inputString.indexOf("0") == 0){// هنا ان ادخل المستخدم الرقم الأول نجعل  ما يؤشره على  السترنق المدخل يبدأ من  الاندكس الي وراه يعني لو كان بدو يدخل 12 و دخل 1 و بدو يدخل 2 حتى ما تروح ال1
                    inputString = inputString.substring(1);
        }

        if ((!inputString.equals("0") || digit > 0)  && inputString.length() < MAX_INPUT_LENGTH){
            setDisplayString(inputString + digit);// فعليا gettext من المدخل حسب setDisplayString = "" فارغة و لما نضفلها الديجت فعليا بنكون ضفنا شو دخل اليوزر
        }


        displayMode = INPUT_MODE;
        clearOnNextDigit = false;// to make the first condition not true at the next time..
    }

    void addDecimalPoint(){
        displayMode = INPUT_MODE;

        if (clearOnNextDigit)
            setDisplayString("");

        String inputString = getDisplayString();


                //if index of "." < 0 means it's not exists at the number so add it otherwise "it's exist" do nothing
        if (inputString.indexOf(".") < 0)
            setDisplayString(new String(inputString + "."));
    }



    void clearAll() {
        setDisplayString("0");
        lastOperator = "0";
        lastNumber = 0;
        displayMode = INPUT_MODE;
        clearOnNextDigit = true;
    }

    void clearExisting(){
        setDisplayString("0");
        clearOnNextDigit = true;
        displayMode = INPUT_MODE;
    }

    double getNumberInDisplay() {
        String input = jlbOutput.getText();
        return Double.parseDouble(input);
    }

    void processOperator(String op) {
        if (displayMode != ERROR_MODE)
                {
                    double numberInDisplay = getNumberInDisplay();
                    //System.out.println("hhhhh");
                        //if it was any one of the operators, processLastOperator which return the result of the done operation..
            if (!lastOperator.equals("0"))
            {
                             //System.out.println("nirmeen");
            try
                {
                    double result = processLastOperator();
                    displayResult(result);// to show the result at the display area
                    lastNumber = result;
                }

                catch (DivideByZeroException e)
                {
                }
            }

            else
            {
                lastNumber = numberInDisplay;
            }

            clearOnNextDigit = true;
            lastOperator = op;
        }
    }

    void processEquals(){
        double result = 0;

        if (displayMode != ERROR_MODE){
            try
            {
                                //System.out.println("nirmeenTest!!!");
                                result = processLastOperator();// return result
                displayResult(result);
            }

            catch (DivideByZeroException e) {
                displayError("Cannot divide by zero!");
            }

            lastOperator = "0";
        }
    }

    double processLastOperator() throws DivideByZeroException {
        double result = 0;
        double numberInDisplay = getNumberInDisplay();

        if (lastOperator.equals("/"))
        {
            if (numberInDisplay == 0)
                throw (new DivideByZeroException());

            result = lastNumber / numberInDisplay;
        }

        if (lastOperator.equals("*"))
            result = lastNumber * numberInDisplay;

        if (lastOperator.equals("-"))
            result = lastNumber - numberInDisplay;

        if (lastOperator.equals("+"))
            result = lastNumber + numberInDisplay;

        return result;
    }

    void displayResult(double result){
        setDisplayString(Double.toString(result));
        lastNumber = result;
        displayMode = RESULT_MODE;
        clearOnNextDigit = true;
    }

    void displayError(String errorMessage){
        setDisplayString(errorMessage);
        lastNumber = 0;
        displayMode = ERROR_MODE;
        clearOnNextDigit = true;
    }
}//end of class



class DivideByZeroException extends Exception{
    public DivideByZeroException()
    {
        super();
    }

    public DivideByZeroException(String s)
    {
        super(s);
    }
}

Recommended Answers

All 6 Replies

what exactly do you mean? you want to be able to control the '+' '-' and digits buttons by the keyboard instead of clicking on them?

no i wnat to control the opertators by the keyboard and also by clicking on them. i did the clicking code but i need to know how to insert form key board.

also i need to insert numbers 0-9 from keyborad, Enter for = ..

thank you

Key listeners have their place as a low-level interface to keyboard input, but for responding to individual keys key bindings are more appropriate and tend to result in more easily maintained code. Key listeners are also difficult if the key binding is to be active when the component doesn't have focus.

(That's from the Oracle Java Tutorials - http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html )

Check out that tutorial. Key Listeners may look like an easy approach but they are full of pitfalls and problems, and are really only appropriate when you need to "get down and dirty". Key Bindings may look a bit more complicated at first, but work much better. They are based on Actions, so if you update your button handing to Actions as well you will have one set of code that deals with mouse clicks and keyboard interchangeably

commented: : ) okay thanks +0
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.