Java GUI 科学计算器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31408162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:04:12  来源:igfitidea点击:

Java GUI Scientific Calculator

javacalculator

提问by mp252

I am trying to code a Scientific calculator in Java. However, I am having difficulties trying to actually get the program to calculate. You can see in the code below, I have a managed to get the GUI working with the numbers printing on the GUI. I have also added functionality to the "+" button in order to test it first to see if the program works.

我正在尝试用 Java 编写一个科学计算器。但是,我在尝试实际让程序进行计算时遇到了困难。您可以在下面的代码中看到,我设法让 GUI 与 GUI 上打印的数字一起工作。我还向“+”按钮添加了功能,以便首先测试它以查看程序是否有效。

public class Gui extends JFrame {
    private static JButton [] button = new JButton[36];
    private static TextField tf;
    private JPanel panel;
    private JPanel panel1;



public Gui(){
    super("Scientific Calculator");
    panel = new JPanel();
    panel1 = new JPanel(new GridLayout(0,4));

    tf = new TextField(20);
    tf.setEditable(false);
    panel.add(tf);

    button[0]=new JButton("Rad/Deg");
    button[1]=new JButton("x!");
    button[2]=new JButton("sqrt");
    button[3]=new JButton("sin");
    button[4]=new JButton("cos");
    button[5]=new JButton("tan");
    button[6]=new JButton("ln");
    button[7]=new JButton("log");
    button[8]=new JButton("1/x");
    button[9]=new JButton("e^x");
    button[10]=new JButton("x^2");
    button[11]=new JButton("y^x");
    button[12]=new JButton("|x|");
    button[13]=new JButton("pi");
    button[14]=new JButton("e");

    button[15]=new JButton("C");
    button[16]=new JButton("(");
    button[17]=new JButton(")");
    button[18]=new JButton("%");
    button[19]=new JButton("/");
    button[20]=new JButton("7");
    button[21]=new JButton("8");
    button[22]=new JButton("9");
    button[23]=new JButton("*");
    button[24]=new JButton("4");
    button[25]=new JButton("5");
    button[26]=new JButton("6");
    button[27]=new JButton("-");
    button[28]=new JButton("1");
    button[29]=new JButton("2");
    button[30]=new JButton("3");
    button[31]=new JButton("+");
    button[32]=new JButton(".");
    button[33]=new JButton("0");
    button[34] =new JButton("+/-");
    button[35] =new JButton("=");



    for(int i = 0; i<button.length;i++){
        panel1.add(button[i]);
    }


    panel.add(panel1);
    add(panel);

    HandlerClass handler = new HandlerClass();
    for(int i = 0; i<button.length;i++){
        button[i].addActionListener(handler);
    }

}
private class HandlerClass implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e) {
        double num1 = 0,num2;

        String alreadyDisplayed = tf.getText();
        String toDisplay = "";

        if(e.getSource()==button[33]){
            alreadyDisplayed = tf.getText();
            toDisplay = alreadyDisplayed + (button[33].getText());
            tf.setText(toDisplay);
        }
        if(e.getSource()==button[28]){
             alreadyDisplayed = tf.getText();
             toDisplay = alreadyDisplayed + (button[28].getText());
            tf.setText(toDisplay);
        }
        if(e.getSource()==button[29]){
            alreadyDisplayed = tf.getText();
            toDisplay = alreadyDisplayed + (button[29].getText());
            tf.setText(toDisplay);
        }
        if(e.getSource()==button[30]){
            alreadyDisplayed = tf.getText();
            toDisplay = alreadyDisplayed + (button[30].getText());
            tf.setText(toDisplay);
        }
        if(e.getSource()==button[24]){
            alreadyDisplayed = tf.getText();
            toDisplay = alreadyDisplayed + (button[24].getText());
            tf.setText(toDisplay);
        }
        if(e.getSource()==button[25]){
            alreadyDisplayed = tf.getText();
            toDisplay = (button[25].getText());
            tf.setText(toDisplay);
        }
        if(e.getSource()==button[26]){
            alreadyDisplayed = tf.getText();
            toDisplay = alreadyDisplayed + (button[26].getText());
            tf.setText(toDisplay);
        }
        if(e.getSource()==button[20]){
            alreadyDisplayed = tf.getText();
            toDisplay = alreadyDisplayed + (button[20].getText());
            tf.setText(toDisplay);
        }
        if(e.getSource()==button[21]){
            alreadyDisplayed = tf.getText();
            toDisplay = alreadyDisplayed + (button[21].getText());
            tf.setText(toDisplay);
        }
        if(e.getSource()==button[22]){
            alreadyDisplayed = tf.getText();
            toDisplay = alreadyDisplayed + (button[22].getText());
            tf.setText(toDisplay);
        }
        if(e.getSource()==button[31]){
            alreadyDisplayed = tf.getText();
            toDisplay = alreadyDisplayed + (button[31].getText());
            tf.setText(toDisplay);
        }

However my problem is what to do afterwards. What I am trying to do is have a try and catch block to see if the first input is a number and then convert it into a double, then store it in an array so that I can use the operator function afterwards and then keep adding numbers until the user wants to stop and perform the calculation. My attempt at this code is below, but it is wrong. Can someone please suggest what I am doing wrong? Thanks

但是我的问题是之后该怎么做。我想要做的是有一个 try 和 catch 块,看看第一个输入是否是一个数字,然后将它转换为一个双精度值,然后将它存储在一个数组中,以便我之后可以使用运算符函数,然后继续添加数字直到用户想要停止并执行计算。我对这段代码的尝试如下,但它是错误的。有人可以建议我做错了什么吗?谢谢

try{
    num1 = Double.parseDouble(toDisplay);
}
catch(NumberFormatException e1){
    System.out.println("You have not entered a number");
}
double[] arr = new double[10];
for(int i=0; i<arr.length;i++){
    arr[i]=num1;
    String test = String.valueOf(arr[i]);
    tf.setText(test);
}

EDITI have wrote new code for a simple calculator as recommended by another user and it works for two inputs. However I am still getting errors when I try to implement multiple inputs. Below is the working code for the two input calculator.

编辑我已经按照另一个用户的推荐为一个简单的计算器编写了新代码,它适用于两个输入。但是,当我尝试实现多个输入时,我仍然遇到错误。下面是两个输入计算器的工作代码。

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;

public class CalcGui extends JFrame {

    private JButton buttonZero;
    private JButton buttonOne;
    private JButton buttonTwo;
    private JButton buttonThree;
    private JButton buttonFour;
    private JButton buttonFive;
    private JButton buttonSix;
    private JButton buttonSeven;
    private JButton buttonEight;
    private JButton buttonNine;

    private JButton opButtonPlus;
    private JButton opButtonMinus;
    private JButton opButtonDivide;
    private JButton opButtonMultiply;
    private JButton opButtonEquals;
    private JButton opButtonClear;

    private TextField tf;

    private JPanel numButtonPanel;
    private JPanel opButtonPanel;
    private JPanel basePanel;

    public CalcGui(){
        super("Scientific Calculator");
        basePanel = new JPanel();
        numButtonPanel = new JPanel(new GridLayout(0,4));
        opButtonPanel = new JPanel(new GridLayout(0,1));

        tf = new TextField(20);
        tf.setEditable(false);
        basePanel.add(tf);

         buttonZero = new JButton("0");
         numButtonPanel.add(buttonZero);
         buttonOne = new JButton("1");
         numButtonPanel.add(buttonOne);
         buttonTwo = new JButton("2");
         numButtonPanel.add(buttonTwo);
         buttonThree = new JButton("3");
         numButtonPanel.add(buttonThree);
         buttonFour = new JButton("4");
         numButtonPanel.add(buttonFour);
         buttonFive = new JButton("5");
         numButtonPanel.add(buttonFive);
         buttonSix = new JButton("6");
         numButtonPanel.add(buttonSix);
         buttonSeven = new JButton("7");
         numButtonPanel.add(buttonSeven);
         buttonEight = new JButton("8");
         numButtonPanel.add(buttonEight);
         buttonNine = new JButton("9");
         numButtonPanel.add(buttonNine);

         basePanel.add(numButtonPanel);

        opButtonPlus = new JButton("+");
        opButtonMinus = new JButton("-");
        opButtonDivide = new JButton("/");
        opButtonMultiply = new JButton("*");
        opButtonEquals = new JButton("=");
        opButtonClear = new JButton("C");

        opButtonPanel.add(opButtonPlus);
        opButtonPanel.add(opButtonMinus);
        opButtonPanel.add(opButtonDivide);
        opButtonPanel.add(opButtonMultiply);
        opButtonPanel.add(opButtonEquals);
        opButtonPanel.add(opButtonClear);

        basePanel.add(opButtonPanel);

        add(basePanel);

        HandlerClass handler = new HandlerClass();

        buttonZero.addActionListener(handler);
        buttonOne.addActionListener(handler);
        buttonTwo.addActionListener(handler);
        buttonThree.addActionListener(handler);
        buttonFour.addActionListener(handler);
        buttonFive.addActionListener(handler);
        buttonSix.addActionListener(handler);
        buttonSeven.addActionListener(handler);
        buttonEight.addActionListener(handler);
        buttonNine.addActionListener(handler);

        opButtonPlus.addActionListener(handler);
        opButtonMinus.addActionListener(handler);
        opButtonDivide.addActionListener(handler);
        opButtonMultiply.addActionListener(handler);
        opButtonEquals.addActionListener(handler);
        opButtonClear.addActionListener(handler);

    }


    private class HandlerClass implements ActionListener{
        public void actionPerformed(ActionEvent e){
            String alreadyDisplayed = tf.getText();
            if(e.getSource()==buttonZero){
                String buttonZeroText = alreadyDisplayed + buttonZero.getText();
                tf.setText(buttonZeroText);
            }else if(e.getSource()==buttonOne){
                String buttonOneText = alreadyDisplayed + buttonOne.getText();
                tf.setText(buttonOneText);
            }else if(e.getSource()==buttonTwo){
                String buttonTwoText = alreadyDisplayed + buttonTwo.getText();
                tf.setText(buttonTwoText);
            }else if(e.getSource()==buttonThree){
                String buttonThreeText = alreadyDisplayed + buttonThree.getText();
                tf.setText(buttonThreeText);
            }else if(e.getSource()==buttonFour){
                String buttonFourText = alreadyDisplayed + buttonFour.getText();
                tf.setText(buttonFourText);
            }else if(e.getSource()==buttonFive){
                String buttonFiveText = alreadyDisplayed + buttonFive.getText();
                tf.setText(buttonFiveText);
            }else if(e.getSource()==buttonSix){
                String buttonSixText = alreadyDisplayed + buttonSix.getText();
                tf.setText(buttonSixText);
            }else if(e.getSource()==buttonSeven){
                String buttonSevenText = alreadyDisplayed + buttonSeven.getText();
                tf.setText(buttonSevenText);
            }else if(e.getSource()==buttonEight){
                String buttonEightText = alreadyDisplayed + buttonEight.getText();
                tf.setText(buttonEightText);
            }else if(e.getSource()==buttonNine){
                String buttonNineText = alreadyDisplayed + buttonNine.getText();
                tf.setText(buttonNineText);
            }else if(e.getSource()==opButtonPlus){
                String opButtonPlusText = alreadyDisplayed + opButtonPlus.getText();
                tf.setText(opButtonPlusText);
            }else if(e.getSource()==opButtonEquals){
                String opButtonEqualsText = alreadyDisplayed + opButtonEquals.getText();
                tf.setText(opButtonEqualsText);
            }else if(e.getSource()==opButtonMinus){
                String opButtonMinusText = alreadyDisplayed + opButtonMinus.getText();
                tf.setText(opButtonMinusText);
            }else if(e.getSource()==opButtonMultiply){
                String opButtonMultiplyText = alreadyDisplayed + opButtonMultiply.getText();
                tf.setText(opButtonMultiplyText);
            }else if(e.getSource()==opButtonDivide){
                String opButtonDivideText = alreadyDisplayed + opButtonDivide.getText();
                tf.setText(opButtonDivideText);
            }else if(e.getSource()==opButtonClear){
                String opButtonClearText = "";
                tf.setText(opButtonClearText);
            }


            double result;
            for(int i=0; i<alreadyDisplayed.length();i++){

                if(e.getSource()==opButtonEquals){

                    if(alreadyDisplayed.charAt(i)=='+'){
                        result = Double.parseDouble(alreadyDisplayed.substring(0,i)) + Double.parseDouble(alreadyDisplayed.substring(i+1,alreadyDisplayed.length()));
                        tf.setText(alreadyDisplayed + "=" + result);
                    }else if(alreadyDisplayed.charAt(i)=='-'){
                        result = Double.parseDouble(alreadyDisplayed.substring(0,i)) - Double.parseDouble(alreadyDisplayed.substring(i+1,alreadyDisplayed.length()));
                        tf.setText(alreadyDisplayed + "=" + result);
                    }else if(alreadyDisplayed.charAt(i)=='/'){
                        result = Double.parseDouble(alreadyDisplayed.substring(0,i)) / Double.parseDouble(alreadyDisplayed.substring(i+1,alreadyDisplayed.length()));
                        tf.setText(alreadyDisplayed + "=" + result);
                    }else if(alreadyDisplayed.charAt(i)=='*'){
                        result = Double.parseDouble(alreadyDisplayed.substring(0,i)) * Double.parseDouble(alreadyDisplayed.substring(i+1,alreadyDisplayed.length()));
                        tf.setText(alreadyDisplayed + "=" + result);
                    }
                }
            }
        }
    }
}

The part I am having difficulties with is getting a number and storing it so that I can let a user enter more than two values. So for example if I take out the for loop at the end of the above code and replaced it with this;

我遇到困难的部分是获取一个数字并存储它,以便我可以让用户输入两个以上的值。例如,如果我取出上述代码末尾的 for 循环并将其替换为:

double []num1=new double[10];
    double []num2=new double[10];
    //double num1 = 0;
    double temp =0;
    String str[] = new String [10];
    String []str1 = new String[10];
    if(e.getActionCommand().equals("+"))
    if(e.getSource() == opButtonEquals)
        for( int i = 0; i<alreadyDisplayed.length(); i++){

            if(alreadyDisplayed.charAt(i)=='+')
             str[i] = alreadyDisplayed.substring(0,i);
             num1[i] = Double.parseDouble(str[i]);
             str1[i+1] = alreadyDisplayed.substring(i+1,alreadyDisplayed.length());
             num2[i+1] = Double.parseDouble(str1[i]);

             temp += num1[i] + num2[i+1];

            tf.setText(Double.toString(temp));

        }System.out.println(temp);
    }
}

So when I try to test to see if temp has any value in the console, it simply prints 0 out each time. The string text is showing up in the text field, however there is no actual calculation working. I thought this would work by storing a number and then storing another number and then adding them together but it has not.

因此,当我尝试在控制台中测试 temp 是否有任何值时,它每次只打印 0。字符串文本显示在文本字段中,但没有实际计算工作。我认为这可以通过存储一个数字然后存储另一个数字然后将它们加在一起来工作,但事实并非如此。

回答by Sh4d0wsPlyr

Why not store the values into a string (much easier to manipulate), and then parse it as an arithmetic expression later? For example..

为什么不将值存储到字符串中(更容易操作),然后稍后将其解析为算术表达式?例如..

Person presses the buttons "(", "sin(8)", "+", "8", ")", "+", "1", "="

人按下按钮 "(", "sin(8)", "+", "8", ")", "+", "1", "="

That quickly evaluates to an easy string of (sin(8)+8)+1=

这很快就会评估为一个简单的字符串 (sin(8)+8)+1=

You can parse the string and look for the obvious things that need to be parsed (e.g. look for sin, then parse everything between the brackets recursively). Use the Math functions to evaluate the complex expressions, and parse the simple ones.

您可以解析字符串并查找需要解析的明显内容(例如查找 sin,然后递归解析括号之间的所有内容)。使用 Math 函数计算复杂的表达式,并解析简单的表达式。

I might recommend writing your own functions to solve the complex expressions though - something similar to this...

不过,我可能会建议您编写自己的函数来解决复杂的表达式 - 类似于此...

public double solveSin(String inside) {
  if(NumberUtils.isNumber(inside)) {
    return Math.sin(Double.parseDouble(inside);
  } else {
    //Call back to original function to direct based on inputs
    return Math.sin(parseEquation(inside));
  }
}

回答by zookastos

Try to make the operator tree as soon a button is pressed. Keep on updating the tree as more buttons are pressed. Parsing a whole equation string can be a difficult task.

尝试在按下按钮后立即制作操作员树。随着更多按钮被按下,继续更新树。解析整个方程字符串可能是一项艰巨的任务。

After the user press Enter, solve your operator tree. This has many benefits. 1) You will not have to deal with parsing one operand/operator at a time. 2) A correct in-order tree traversal will take care of BODMAS rule and other nitty-gritty of mathematical operators. 3) An in-order traversal will give you the original equation the user typed, which you can show him back.

用户按 Enter 后,求解您的运算符树。这有很多好处。1) 您不必一次解析一个操作数/运算符。2) 正确的有序树遍历将处理 BODMAS 规则和其他数学运算符的细节。3)有序遍历将为您提供用户键入的原始方程式,您可以将其展示给他。