Slay - Sam
Slay - Sam

Reputation: 21

Java Calculator with Keystroke response

So I have this script written up; it's kind-of a hodgepodge of a calculator I found and pieced together.

The KeyListener is from the Java - oracle - .com website. On a side note, I'm extremely new to this and have no clue what I'm doing.

I'm attempting to use the KeyListener to allow the keystrokes to make the calculator work, so that the input doesn't have to be clicked; currently the script compiles but the input cannot be typed in... Am I even doing this right?

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;

public class Calculator extends JFrame implements KeyListener, ActionListener {

JPanel[] row = new JPanel[5];
JButton[] button = new JButton[19];
String[] buttonstring = {"7", "8", "9", "+",
                         "4", "5", "6", "-",
                         "1", "2", "3", "*",
                         ".", "/", "C", "SR",
                         "+/-", "=", "0"};
int[] dimW = {300,45,100,90};
int[] dimH = {35, 40};
Dimension displayDimension = new Dimension(dimW[0], dimH[0]);
Dimension regularDimension = new Dimension(dimW[1], dimH[1]);
Dimension rColumnDimension = new Dimension(dimW[2], dimH[1]);
Dimension zeroButDimension = new Dimension(dimW[3], dimH[1]);
boolean[] function = new boolean[4];
double[] temporary = {0, 0};
JTextArea display = new JTextArea(1,20);

Font font = new Font("Times new Roman", Font.BOLD, 14);
JTextArea displayArea;
JTextField typingArea;
static final String newline = System.getProperty("line.separator");

    //Uncomment this if you wish to turn off focus
    //traversal.  The focus subsystem consumes
    //focus traversal keys, such as Tab and Shift Tab.
    //If you uncomment the following line of code, this
    //disables focus traversal and the Tab events will
    //become available to the key event listener.
    //typingArea.setFocusTraversalKeysEnabled(false);


Calculator() {
    super("Calculator");
    setDesign();
    setSize(380, 250);
    setResizable(false);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    GridLayout grid = new GridLayout(5,5);
    setLayout(grid);

    for(int i = 0; i < 4; i++)
        function[i] = false;

    FlowLayout f1 = new FlowLayout(FlowLayout.CENTER);
    FlowLayout f2 = new FlowLayout(FlowLayout.CENTER,1,1);
    for(int i = 0; i < 5; i++)
        row[i] = new JPanel();
    row[0].setLayout(f1);
    for(int i = 1; i < 5; i++)
        row[i].setLayout(f2);

    for(int i = 0; i < 19; i++) {
        button[i] = new JButton();
        button[i].setText(buttonstring[i]);
        button[i].setFont(font);
        button[i].addActionListener(this);
    }

    display.setFont(font);
    display.setEditable(false);
    display.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
    display.setPreferredSize(displayDimension);
    for(int i = 0; i < 14; i++)
        button[i].setPreferredSize(regularDimension);
    for(int i = 14; i < 18; i++)
        button[i].setPreferredSize(rColumnDimension);
    button[18].setPreferredSize(zeroButDimension);

    row[0].add(display);
    add(row[0]);

    for(int i = 0; i < 4; i++)
        row[1].add(button[i]);
    row[1].add(button[14]);
    add(row[1]);

    for(int i = 4; i < 8; i++)
        row[2].add(button[i]);
    row[2].add(button[15]);
    add(row[2]);

    for(int i = 8; i < 12; i++)
        row[3].add(button[i]);
    row[3].add(button[16]);
    add(row[3]);

    row[4].add(button[18]);
    for(int i = 12; i < 14; i++)
        row[4].add(button[i]);
    row[4].add(button[17]);
    add(row[4]);

    setVisible(true);
}



public void clear() {
    try {
        display.setText("");
        for(int i = 0; i < 4; i++)
            function[i] = false;
        for(int i = 0; i < 2; i++)
            temporary[i] = 0;
    } catch(NullPointerException e) {  
    }
}

public void getSqrt() {
    try {
        double value = Math.sqrt(Double.parseDouble(display.getText()));
        display.setText(Double.toString(value));
    } catch(NumberFormatException e) {
    }
}

public void getPosNeg() {
    try {
        double value = Double.parseDouble(display.getText());
        if(value != 0) {
            value = value * (-1);
            display.setText(Double.toString(value));
        }
        else {
        }
    } catch(NumberFormatException e) {
    }
}

public void getResult() {
    double result = 0;
    temporary[1] = Double.parseDouble(display.getText());
    String temp0 = Double.toString(temporary[0]);
    String temp1 = Double.toString(temporary[1]);
    try {
        if(temp0.contains("-")) {
            String[] temp00 = temp0.split("-", 2);
            temporary[0] = (Double.parseDouble(temp00[1]) * -1);
        }
        if(temp1.contains("-")) {
            String[] temp11 = temp1.split("-", 2);
            temporary[1] = (Double.parseDouble(temp11[1]) * -1);
        }
    } catch(ArrayIndexOutOfBoundsException e) {
    }
    try {
        if(function[2] == true)
            result = temporary[0] * temporary[1];
        else if(function[3] == true)
            result = temporary[0] / temporary[1];
        else if(function[0] == true)
            result = temporary[0] + temporary[1];
        else if(function[1] == true)
            result = temporary[0] - temporary[1];
        display.setText(Double.toString(result));
        for(int i = 0; i < 4; i++)
            function[i] = false;
    } catch(NumberFormatException e) {
    }
}

public final void setDesign() {
    try {
        UIManager.setLookAndFeel(
                "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
    } catch(Exception e) {   
    }
}

@Override
public void actionPerformed(ActionEvent ae) {
    if(ae.getSource() == button[0])
        display.append("7");
    if(ae.getSource() == button[1])
        display.append("8");
    if(ae.getSource() == button[2])
        display.append("9");
    if(ae.getSource() == button[3]) {
        //add function[0]
        temporary[0] = Double.parseDouble(display.getText());
        function[0] = true;
        display.setText("");
    }
    if(ae.getSource() == button[4])
        display.append("4");
    if(ae.getSource() == button[5])
        display.append("5");
    if(ae.getSource() == button[6])
        display.append("6");
    if(ae.getSource() == button[7]) {
        //subtract function[1]
        temporary[0] = Double.parseDouble(display.getText());
        function[1] = true;
        display.setText("");
    }
    if(ae.getSource() == button[8])
        display.append("1");
    if(ae.getSource() == button[9])
        display.append("2");
    if(ae.getSource() == button[10])
        display.append("3");
    if(ae.getSource() == button[11]) {
        //multiply function[2]
        temporary[0] = Double.parseDouble(display.getText());
        function[2] = true;
        display.setText("");
    }
    if(ae.getSource() == button[12])
        display.append(".");
    if(ae.getSource() == button[13]) {
        //divide function[3]
        temporary[0] = Double.parseDouble(display.getText());
        function[3] = true;
        display.setText("");
    }
    if(ae.getSource() == button[14])
        clear();
    if(ae.getSource() == button[15])
        getSqrt();
    if(ae.getSource() == button[16])
        getPosNeg();
    if(ae.getSource() == button[17])
        getResult();
    if(ae.getSource() == button[18])
        display.append("0");
}

public void contentPane() {
 typingArea = new JTextField(20);
    typingArea.addKeyListener(this);
   displayArea = new JTextArea();
       displayArea.setEditable(false);
       JScrollPane scrollPane = new JScrollPane(displayArea);
       scrollPane.setPreferredSize(new Dimension(375, 125));

       getContentPane().add(typingArea, BorderLayout.PAGE_START);  
       getContentPane().add(scrollPane, BorderLayout.CENTER); 


}

public void keyTyped(KeyEvent e) {
    displayInfo(e, "KEY TYPED: ");
}

/** Handle the key pressed event from the text field. */
public void keyPressed(KeyEvent e) {
    displayInfo(e, "KEY PRESSED: ");
}

/** Handle the key released event from the text field. */
public void keyReleased(KeyEvent e) {
    displayInfo(e, "KEY RELEASED: ");
}

/** Handle the button click. */
public void ActionPerformed(ActionEvent e) {
    //Clear the text components.
    displayArea.setText("");
    typingArea.setText("");

    //Return the focus to the typing area.
    typingArea.requestFocusInWindow();
}

private void displayInfo(KeyEvent e, String keyStatus){

    //You should only rely on the key char if the event
    //is a key typed event.
    int id = e.getID();
    String keyString;
    if (id == KeyEvent.KEY_TYPED) {
        char c = e.getKeyChar();
        keyString = "key character = '" + c + "'";
    }  else {
        int keyCode = e.getKeyCode();
        keyString = "key code = " + keyCode
                + " ("
                + KeyEvent.getKeyText(keyCode)
                + ")";
    }

    int modifiersEx = e.getModifiersEx();
    String modString = "extended modifiers = " + modifiersEx;
    String tmpString = KeyEvent.getModifiersExText(modifiersEx);
    if (tmpString.length() > 0) {
        modString += " (" + tmpString + ")";
    } else {
        modString += " (no extended modifiers)";
    }

    String actionString = "action key? ";
    if (e.isActionKey()) {
        actionString += "YES";
    } else {
        actionString += "NO";
    }

    String locationString = "key location: ";
    int location = e.getKeyLocation();
    if (location == KeyEvent.KEY_LOCATION_STANDARD) {
        locationString += "standard";
    } else if (location == KeyEvent.KEY_LOCATION_LEFT) {
        locationString += "left";
    } else if (location == KeyEvent.KEY_LOCATION_RIGHT) {
        locationString += "right";
    } else if (location == KeyEvent.KEY_LOCATION_NUMPAD) {
        locationString += "numpad";
    } else { // (location == KeyEvent.KEY_LOCATION_UNKNOWN)
        locationString += "unknown";
    }

    displayArea.append(keyStatus + newline
            + "    " + keyString + newline
            + "    " + modString + newline
            + "    " + actionString + newline
            + "    " + locationString + newline);
    displayArea.setCaretPosition(displayArea.getDocument().getLength()); 

}
public static void main(String[] arguments) {
Calculator c = new Calculator();
}
}

Upvotes: 0

Views: 1418

Answers (2)

camickr
camickr

Reputation: 324098

Here is something to get you started. It shows how to use Key Bindings (instead of a KeyListener).

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class CalculatorPanel extends JPanel
{
    private JTextField display;

    public CalculatorPanel()
    {
        Action numberAction = new AbstractAction()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                display.setCaretPosition( display.getDocument().getLength() );
                display.replaceSelection(e.getActionCommand());
            }
        };

        setLayout( new BorderLayout() );

        display = new JTextField();
        display.setEditable( false );
        display.setHorizontalAlignment(JTextField.RIGHT);
        add(display, BorderLayout.NORTH);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout( new GridLayout(0, 5) );
        add(buttonPanel, BorderLayout.CENTER);

        for (int i = 0; i < 10; i++)
        {
            String text = String.valueOf(i);
            JButton button = new JButton( text );
            button.addActionListener( numberAction );
            button.setBorder( new LineBorder(Color.BLACK) );
            button.setPreferredSize( new Dimension(50, 50) );
            buttonPanel.add( button );

            InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
            inputMap.put(KeyStroke.getKeyStroke(text), text);
            inputMap.put(KeyStroke.getKeyStroke("NUMPAD" + text), text);
            button.getActionMap().put(text, numberAction);
        }
    }

    private static void createAndShowUI()
    {
//      UIManager.put("Button.margin", new Insets(10, 10, 10, 10) );

        JFrame frame = new JFrame("Calculator Panel");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add( new CalculatorPanel() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

Read the section from the Swing tutorial on How to Use Key Bindings for more information about Key Bindings and why they should be used instead of a KeyListener

Upvotes: 1

MadProgrammer
MadProgrammer

Reputation: 347184

The main visible component on your screen is the display JTextArea. You set this field to be non-editable, display.setEditable(false);, therefore the user will not be able to type text into it...

Also, the contentPane method is never called, so typingArea and displayArea are never displayed, but I'm not sure you want to do this anyway, as you've changed the layout manager from BorderLayout to GridLayout, which is just going to screw things up...

Also typingArea, which has the KeyListener attached, is never added to any displayable components, so it will never trigger any key events, as no one type into it...

It's difficult to know what to suggest, but I might suggest, getting rid of display and displayArea and using typingArea instead, unsless you really need multiple lines of numbers...

You should avoid using KeyListener on text components anyway, a better solution for listening for changes to the state of text component is the DocumentListener, see Listening for Changes on a Document for more details...

Upvotes: 1

Related Questions