Java实现简易版计算器

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Vector;
import java.math.BigDecimal;
import javax.swing.UIManager;

public class Calculat {  
    String str1="0"; // 操作数1,为了程序的安全,初值设置为0
    String str2="0"; // 操作数2
    String signal="+"; // 运算符
    String result="";// 运算结果
    
    // 以下k1至k5为状态开关
    int k1=1;// 开关1用于选择输入方向,将要写入str1或str2
    int k2=1;// 开关2用于记录符号键的次数,如果 k2>1 说明进行的是多符号运算
    int k3=1;// 开关3用于标识 str1 是否可以被清0 ,等于1时可以,不等于1时不能被清0
    int k4=1;// 开关4用于标识 str2 是否可以被清0,等于1时可以,不等于1时不能被清0
    int k5=1;// 开关5用于控制小数点可否被录入,等于1时可以,不为1时,输入的小数点被丢掉
    JButton store; // store的作用类似于寄存器,用于记录是否连续按下符号键
    
    @SuppressWarnings("rawtypes")//忽略rawtypes警告信息
    Vector vt=new Vector(20, 10);
  
    // 声明各个UI组件对象并初始化
    JFrame frame=new JFrame("Calculator");//JFrame是java里的一个窗体类,创建一个JFrame类的实例
    //设置主窗口出现在屏幕上的位置
    //frame.setLocation(300, 200);
    
    //设置窗体不能调大小
    //frame.setResizable(false);
    
    JTextField result_TextField=new JTextField(result, 20);//JTextField是一个轻量级组件,允许编辑单行文本,构造一个用result和20列的新TextField
    JButton clear_Button=new JButton("AC");//创建AC按钮
    JButton button0=new JButton("0");//创建0按钮
    JButton button1=new JButton("1");//创建1按钮
    JButton button2=new JButton("2");//创建2按钮
    JButton button3=new JButton("3");//创建3按钮
    JButton button4=new JButton("4");//创建4按钮
    JButton button5=new JButton("5");//创建5按钮
    JButton button6=new JButton("6");//创建6按钮
    JButton button7=new JButton("7");//创建7按钮
    JButton button8=new JButton("8");//创建8按钮
    JButton button9=new JButton("9");//创建9按钮
    JButton button_Dian=new JButton(".");//创建.按钮
    JButton button_jia=new JButton("+");//创建+按钮
    JButton button_jian=new JButton("-");//创建-按钮
    JButton button_cheng=new JButton("*");//创建*按钮
    JButton button_chu=new JButton("/");//创建/按钮
    JButton button_dy=new JButton("=");//创建=按钮
   
    // 计算机类的构造器
    public Calculat() {
        
        // 为按钮设置等效键,可以通过对应的键盘按键来代替点击它
        button0.setMnemonic(KeyEvent.VK_0);//按下Alt+0
        button1.setMnemonic(KeyEvent.VK_1);//按下Alt+1
        button2.setMnemonic(KeyEvent.VK_2);//按下Alt+2
        button3.setMnemonic(KeyEvent.VK_3);//按下Alt+3
        button4.setMnemonic(KeyEvent.VK_4);//按下Alt+4
        button5.setMnemonic(KeyEvent.VK_5);//按下Alt+5
        button6.setMnemonic(KeyEvent.VK_6);//按下Alt+6
        button7.setMnemonic(KeyEvent.VK_7);//按下Alt+7
        button8.setMnemonic(KeyEvent.VK_8);//按下Alt+8
        button9.setMnemonic(KeyEvent.VK_9);//按下Alt+9
        
        // 设置文本框为右对齐,使输入和结果都靠右显示
        result_TextField.setHorizontalAlignment(JTextField.RIGHT);

        // 将UI组件添加进容器内
        JPanel pan = new JPanel();//创建面板组件的一个实例pan
        pan.setLayout(new GridLayout(4, 4, 5, 5));//设置4行4列边距为5像素的表格布局
        pan.add(button7);//设置pan对象的边距
        pan.add(button8);
        pan.add(button9);
        pan.add(button_chu);
        pan.add(button4);
        pan.add(button5);
        pan.add(button6);
        pan.add(button_cheng);
        pan.add(button1);
        pan.add(button2);
        pan.add(button3);
        pan.add(button_jian);
        pan.add(button0);
        pan.add(button_Dian);
        pan.add(button_dy);
        pan.add(button_jia);
        pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));//创建一个框,头部、底部、左、右都为5像素
        JPanel pan2=new JPanel();
        pan2.setLayout(new BorderLayout());//设置布局为边框布局,分东南西北中5个方位
        pan2.add(result_TextField, BorderLayout.WEST);//将显示结果的文本框添加到pan2
        pan2.add(clear_Button, BorderLayout.EAST);//将AC按钮添加到pan2

        // 设置主窗口出现在屏幕上的位置
        frame.setLocation(300, 200);//窗口最初位置
        frame.setResizable(false); // 设置窗体不能调大小
        frame.getContentPane().setLayout(new BorderLayout());//设置一个具有hgap为横向间距、vgap为纵向间距的边框布局
        frame.getContentPane().add(pan2, BorderLayout.NORTH);//将pan2放到边框上方
        frame.getContentPane().add(pan, BorderLayout.CENTER);//将pan放到边框中间
        frame.pack();//根据窗口里面的布局及组件的preferedSize来确定frame的最佳大小
        frame.setVisible(true);//窗口显示frame对象

        // 事件处理程序

        // 数字键响应事件
        class Listener implements ActionListener {
            @SuppressWarnings("unchecked")//忽略unchecked的警告信息
            public void actionPerformed(ActionEvent e) {
                String ss=((JButton) e.getSource()).getText();//获取事件源,并从事件源获取输入数据
                store=(JButton) e.getSource();//读取存储的符号键
                vt.add(store);//将符号键添加到vt中
                if (k1==1) //输入是操作数1的部分,判断是否可以清零
                {
                    if (k3==1) 
                    {
                        str1="";
                        k5=1;// 还原开关k5状态
                    }
                    str1=str1+ss;//当输入完成后,需要给 k3 的值加 1,保证 操作数 1 不会被清空。并且还需要将操作数 1 打印到结果栏
                    k3=k3+1;
                    result_TextField.setText(str1);// 显示结果
                }
                else if (k1==2) //输入操作数是2的部分,判断是否可以清零
                {
                    if (k4==1) 
                    {
                        str2="";
                        k5=1; // 还原开关k5状态
                    }
                    str2=str2+ss;//当输入完成后,需要给 k4 的值加 1,保证 操作数 2 不会被清空。并且还需要将操作数 2 打印到结果栏
                    k4=k4+1;
                    result_TextField.setText(str2);//显示结果
                }

            }
        }

        // 输入的运算符号的处理
        class Listener_signal implements ActionListener {
            @SuppressWarnings("unchecked")
            public void actionPerformed(ActionEvent e) {
                String ss2=((JButton) e.getSource()).getText();//获取事件源,并从事件源获取输入数据
                store=(JButton) e.getSource();//读取存储的符号键
                vt.add(store);//将符号键添加到vt中去
                if (k2==1) 
                {
                    k1=2;// 开关 k1 为 1 时向数 1 写输入值,为2时向数2写输入值。
                    k5=1;//可以输入小数点
                    signal=ss2;//只能输入一个符号
                    k2=k2+1;// 按符号键的次数
                } 
                else 
                {
                    int a=vt.size();//表示输入的长度,读取上次的输入
                    JButton c=(JButton) vt.get(a - 2);//获取后面的运算符
                    if (!(c.getText().equals("+"))&& !(c.getText().equals("-"))&& !(c.getText().equals("*"))&& !(c.getText().equals("/")))//判断输入若不是这些的符号,就说明要进行多次运算
                    {
                        cal();//调用calc()运算并将结果存入str1中
                        str1=result;
                        k1=2;// 开关 k1 为 1 时,向数 1 写值,为2时向数2输入
                        k5=1;//可以输入小数点
                        k4=1;//可以连续计算
                        signal=ss2;//signal存储此次输入的符号
                    }
                    k2=k2+1;//增加已经输入的符号的次数
                }
            }
        }

        // 清除键的逻辑(Clear)
        class Listener_clear implements ActionListener {
            @SuppressWarnings("unchecked")
            public void actionPerformed(ActionEvent e) {
                store=(JButton) e.getSource();//读入存储的符号键
                vt.add(store);//将符号键添加到vt中去
                k5=1;//将所有的值清零或置为初值
                k2=1;
                k1=1;
                k3=1;
                k4=1;
                str1="0";
                str2="0";
                signal="";
                result="";
                result_TextField.setText(result);//显示结果
                vt.clear();
            }
        }

        // 等于键的逻辑
        class Listener_dy implements ActionListener {
            @SuppressWarnings("unchecked")
            public void actionPerformed(ActionEvent e) {
                store=(JButton) e.getSource();//按键按下后,调用calc()函数,还原开关的值
                vt.add(store);
                cal();
                
                // 还原各个开关的状态
                k1=1; 
                k2=1;
                k3=1;
                k4=1;
                str1=result; 
            }
        }
        
        // 小数点的处理
        class Listener_xiaos implements ActionListener {
            @SuppressWarnings("unchecked")
            public void actionPerformed(ActionEvent e) {
                store=(JButton) e.getSource();//获取相应源
                vt.add(store);//将相应源添加到vt中去
                if (k5==1) 
                {
                    String ss2=((JButton) e.getSource()).getText();//获取事件源,并从事件源获取输入的数据
                    if (k1==1) //输入是操作数1的部分,判断是否可以清零
                    {
                        if (k3==1) 
                        {
                            str1="";
                            k5=1; // 还原开关k5状态
                        }
                        str1=str1+ss2;
                        k3=k3+1;
                        result_TextField.setText(str1);//显示结果

                    } 
                    else if (k1==2) //输入是操作数2的部分,判断是否可以清零
                    {
                        if (k4==1) 
                        {
                            str2="";
                            k5=1;// 还原开关k5的状态
                        }
                        str2=str2+ss2;
                        k4=k4+1;
                        result_TextField.setText(str2);//显示结果
                    }
                }
                k5=k5+1;
            }
        }
        
        // 注册各个监听器,即绑定事件响应逻辑到各个UI组件上
        
        //监听等于键
        Listener_dy jt_dy=new Listener_dy();
        button_dy.addActionListener(jt_dy);
        
        // 监听数字键
        Listener jt=new Listener();
        button7.addActionListener(jt);
        button8.addActionListener(jt);
        button9.addActionListener(jt);
        button4.addActionListener(jt);
        button5.addActionListener(jt);
        button6.addActionListener(jt);
        button1.addActionListener(jt);
        button2.addActionListener(jt);
        button3.addActionListener(jt);
        button0.addActionListener(jt);
        // 监听符号键
        Listener_signal jt_signal=new Listener_signal();
        button_jia.addActionListener(jt_signal);
        button_jian.addActionListener(jt_signal);
        button_cheng.addActionListener(jt_signal);
        button_chu.addActionListener(jt_signal);
        
        // 监听清除键
        Listener_clear jt_c=new Listener_clear(); 
        clear_Button.addActionListener(jt_c);
        
        // 监听小数点键
        Listener_xiaos jt_xs=new Listener_xiaos();
        button_Dian.addActionListener(jt_xs);

        // 窗体关闭事件的响应程序
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);//退出程序
            }
        });
    }

    // 计算逻辑
    public void cal() {
        double a2;// 操作数1
        double b2;// 操作数2
        String c=signal;// 运算符
        double result2=0;// 运算结果
        if (c.equals("")) 
        {
            result_TextField.setText("Please input operator");
        }
        else 
        {
            
            // 手动处理小数点的问题
            if (str1.equals("."))
                str1="0.0";
            if (str2.equals("."))
                str2="0.0";
            a2=Double.valueOf(str1).doubleValue();//转换字符串为double型
            b2=Double.valueOf(str2).doubleValue();
            if (c.equals("+")) 
            {
                result2=a2+b2;
            }
            if (c.equals("-"))
            {
                result2=a2-b2;
            }
            if (c.equals("*")) 
            {
                BigDecimal m1=new BigDecimal(Double.toString(a2));//为保证精度,将double存入大的浮点数类型BigDecimal中
                    BigDecimal m2=new BigDecimal(Double.toString(b2));
                    result2=m1.multiply(m2).doubleValue();
            }
            if (c.equals("/"))
            {
                if (b2==0)
                {
                    result2=0;
                } 
                else
                {
                    result2=a2/b2;
                }
            }
            result=((new Double(result2)).toString());
            result_TextField.setText(result);
        }
    }
    @SuppressWarnings("unused")
    public static void main(String[] args) {
        // 设置程序显示的界面风格
    try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowaLookAndFeel");//Windows窗体风格
            /*Metal 风格(默认):javax.swing.plaf.metal.MetalLookAndFeel
            更换为 Motif 风格:com.sun.java.swing.plaf.motif.MotifLookAndFeel
            更换为 Mac 风格:com.sun.java.swing.plaf.mac.MacLookAndFeel
            更换为 GTK 风格:com.sun.java.swing.plaf.gtk.GTKLookAndFeel*/
        } 
    catch (Exception e) 
    {
            e.printStackTrace();
    }
        Calculat cal=new Calculat();
    }
}
posted @ 2021-06-03 21:41  zonkidd  阅读(130)  评论(0编辑  收藏  举报