From db90e6d528fb9d13ba32fcaa7038e197fbfa649f Mon Sep 17 00:00:00 2001 From: p64apj9i2 <3379823941@qq.com> Date: Thu, 11 Apr 2024 23:10:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AD=94=E7=9B=88=E7=9B=884.11=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Calculator.java | 316 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 src/Calculator.java diff --git a/src/Calculator.java b/src/Calculator.java new file mode 100644 index 0000000..db26317 --- /dev/null +++ b/src/Calculator.java @@ -0,0 +1,316 @@ +package ex12; +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.DecimalFormat; +import java.math.BigInteger; +//时间允许,可通过引入一下包,实现鼠标滑过按钮变色和键盘输入 +//import java.awt.event.MouseAdapter; +//import java.awt.event.MouseEvent; +//import java.awt.event.KeyAdapter; +//import java.awt.event.KeyEvent; +import java.math.BigDecimal;//控制小数点后几位 +import java.awt.* +;@SuppressWarnings("unused") +public class Calculator implements ActionListener { + + private JFrame frame = new JFrame();//界面应用程序,窗口 + + //计算器上各按键的符号 + private String[] keys = {"%", "CE", "C", "←", "n!", "aⁿ", "cos", "sin", "1/x", "x²", "√x", "÷", "7", "8", "9", + "×", "4", "5", "6", "-", "1", "2", "3", "+", "+/-", "0", ".", "="}; + private JButton button[] = new JButton[keys.length]; //计算器上按键的按钮(数组保存) + private JTextField resultText = new JTextField("0");//显示计算结果文本框 + private JTextField processText = new JTextField();//显示计算过程文本框 + private boolean firstDigit = true; // 标志用户按的是否是整个表达式的第一个数字,或者是运算符后的第一个数字 + private double resultNum = 0.0000; // 计算的中间结果 + private String operator = "="; // 当前运算的运算符(按键"C"时需要将其还原为"=") + private boolean operateValidFlag = true; // 判断操作是否合法 + + char charA; + + public Calculator() {//本类Calculator的构造函数 + init(); // 初始化计算器 + + frame.setTitle("计算器"); + frame.setSize(350, 550); + frame.setLocation(500, 300); + frame.setResizable(true); // 允许修改计算器窗口的大小 + frame.setVisible(true); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击关闭按钮后执行exit退出应用程序 + } + + + private void init() {//初始化变量,创建面板,添加按钮,面板布局 + Color color1 = new Color(181, 181, 181); + Color color2 = new Color(126, 192, 238); //等于号专属颜色 + Color color3 = new Color(232, 232, 232); //背景颜色//功能键和运算符颜色 + Color color4 = new Color(132, 132, 232);//紫色 + + JPanel resultTextPanel = new JPanel();// 建立一个画板放文本框 + resultTextPanel.setLayout(new BorderLayout()); + resultTextPanel.setSize(400, 50); + resultTextPanel.add(resultText); + resultText.setFont(new Font("黑体", Font.BOLD, 55)); //设置文本框中文字的字体以及大小,加粗 + resultText.setHorizontalAlignment(JTextField.RIGHT); //文本框中的内容采用右对齐方式 + resultText.setEditable(false); //不能修改结果文本框 + resultText.setBorder(null); //删除文本框的边框 + resultText.setBackground(color1);// 设置文本框背景颜色 + + JPanel processTextPanel = new JPanel(); + processTextPanel.setLayout(new BorderLayout()); + processTextPanel.setSize(400, 50); + processTextPanel.add(processText); + processText.setFont(new Font("黑体", Font.PLAIN, 25)); //设置文本框中文字的字体以及大小,加粗 + processText.setHorizontalAlignment(JTextField.RIGHT); //文本框中的内容采用右对齐方式 + processText.setEditable(false); //不能修改结果文本框 + processText.setBorder(null); //删除文本框的边框 + + processText.setBackground(color1); + + // 初始化计算器上键的按钮,将键放在一个画板内 + JPanel keysPanel = new JPanel(); + // 用网格布局器,6行,4列的网格,网格之间的水平方向垂直方向间隔均为2个像素 + keysPanel.setLayout(new GridLayout(7, 4, 2, 2)); + + //初始化功能按钮 + for (int i = 0; i < 12; i++) { + button[i] = new JButton(keys[i]); + Dimension preferredSize = new Dimension(95, 50); + button[i].setPreferredSize(preferredSize); + keysPanel.add(button[i]); + button[i].setBackground(color3); + button[i].setForeground(Color.black);//设置字体颜色 + button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 18)); + if (i == 11 || i == 3) button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 30)); + if (i == 1 || i == 2) button[i].setFont(new Font("黑体", Font.PLAIN, 18)); + button[i].setBorderPainted(false); //去除按钮的边框 + } + + //初始化运算符及数字键按钮 + for (int i = 12; i < keys.length; i++) { + button[i] = new JButton(keys[i]); + Dimension preferredSize = new Dimension(95, 50); + button[i].setPreferredSize(preferredSize); + keysPanel.add(button[i]); + if ((i + 1) % 4 == 0) { + button[i].setBackground(color3);//运算符按钮 + button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 30)); + } else { + button[i].setBackground(Color.white);//数字按钮 + button[i].setFont(new Font("黑体", Font.BOLD, 20)); + } + if (i == 19) button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 18)); + button[i].setForeground(Color.black); + + button[i].setBorderPainted(false); //去除按钮的边框 + } + button[27].setBackground(color4); // 用紫色 覆盖更改 标记'=' + + keysPanel.setBackground(color1); + + //将文本框所在的面板放在北部和中部,将keysPanel面板放在计算器的南部 + frame.getContentPane().add("North", processTextPanel); + frame.getContentPane().add("Center", resultTextPanel); + frame.getContentPane().add("South", keysPanel); + processTextPanel.setBorder(BorderFactory.createMatteBorder(25, 3, 0, 3, color1)); + resultTextPanel.setBorder(BorderFactory.createMatteBorder(0, 3, 5, 3, color1)); + keysPanel.setBorder(BorderFactory.createMatteBorder(5, 3, 5, 3, color1)); + + for (int i = 0; i < keys.length;i++){ + button[i].addActionListener(this);//为各按钮添加事件监听器,都使用同一个事件监听器 + } + } + public void actionPerformed(ActionEvent ev){//监听函数,将得到的事件选择对应的函数 + String command = ev.getActionCommand();//获取事件源 + if (command.equals(keys[3])) doBackspace();//用户按了"Back"鍵键 + else if (command.equals(keys[1])) resultText.setText("0");//用户按了"CE"键 + else if (command.equals(keys[2])) doC();//用户按了"C"键 + else if ("0123456789.".indexOf(command)>= 0) doNumber(command);//用户按了数字键 + else if (command.equals(keys[0])||command.equals(keys[4])||command.equals(keys[6]) + ||command.equals(keys[7])|| command.equals(keys[8])||command.equals(keys[9]) + ||command.equals(keys[10]) || command.equals(keys[24])) doOperator1(command); + //用户按了只需一个数的运算键(求倒数,%,开方,平方,取正负数) + else doOperator2(command); +} + private void doBackspace(){//删除鍵 + String text = resultText.getText(); + int i = text.length(); + if (i > 0){ + text = text.substring(0, i - 1);//退格,将文本最后一个字符去掉 + if (text.length()== 0){ + resultText.setText("0");//如果文本没有内容了,则初始化计算器的各种值 + firstDigit = true; + operator ="="; + } else { + resultText.setText(text);//显示新的文本 + } + } + } + + + private void doC(){//清除鍵 + //初始化计算器的各种值 + processText.setText(null); + resultText.setText("0"); + firstDigit = true; + operator ="="; + } + private void doNumber(String key){//得到数字,处理数字 + if (firstDigit){ + //输入的为第一个数 + resultText.setText(null); + resultText.setText(key); + } else if ((key.equals("."))&&(resultText.getText().indexOf(".")<0)){ + } else if ((key.equals("."))&&(resultText.getText().indexOf(".")< 0)){ + //index0f()返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回-1 + //输入的是小数点,并且之前没有小数点,则将小数点附在结果文本框的后面 + resultText.setText(resultText.getText()+"."); + } else if (!key.equals(".")){//如果输入的不是小数点,则将数字附在结果文本框的后面 + resultText.setText(resultText.getText()+ key); + } + firstDigit=false; + } + private void doOperator1(String key){//进行单目运算 + operator = key;//运算符为用户按的按钮 + if (operator.equals("1/x")){//倒数运算 + if (resultNum == 0){ + operateValidFlag = false;//操作不合法 + resultText.setText("除数不能为零"); + } else { + resultNum = 1 / getNumberFromText(); + processText.setText("1/("+ resultText.getText()+")"); + } + }else if (operator.equals("√x")){//平方根运算 + if (resultNum < 0){ + operateValidFlag = false;//操作不合法 + resultText.setText("无效输入"); + } else { + resultNum = Math.sqrt(getNumberFromText()); + processText.setText("√("+resultText.getText()+")"); + //resultNum=getNumberFromText(); + } + } else if (operator.equals("x²")){//平方运算X + resultNum = getNumberFromText()* getNumberFromText(); + processText.setText("sqr("+ resultText.getText()+")"); + } else if (operator.equals("%")){//百分号运算,除以100 + resultNum = getNumberFromText()/ 100; + } else if (operator.equals("n!")){ + BigInteger num = new BigInteger("1"); + BigInteger flat = new BigInteger("1"); + for (int i = 0; i < getNumberFromText(); i++){ + flat = flat.multiply(num); + num = num.add(new BigInteger("1")); + } + resultNum = flat.floatValue();//BigInteger转换为float + processText.setText("fact("+ resultText.getText()+")"); + } else if (operator.equals("cos")){ + resultNum = Math.cos(getNumberFromText()); + processText.setText("cos("+ resultText.getText()+")"); + } else if (operator.equals("sin")){ + resultNum = Math.sin(getNumberFromText()); + processText.setText("sin("+ resultText.getText()+")"); + } else if (operator.equals("+/-")){//正数负数运算 + resultNum =getNumberFromText()*(-1); + } + isOperateValidFlag(operateValidFlag); + firstDigit = true;//复位 + if (operateValidFlag == false) processText.setText(null); + operateValidFlag = true; + } + + + private void doOperator2(String key){//进行双目运算 + if (operator.equals("÷")){//除法运算//如果当前结果文本框中的值等于0 + if (getNumberFromText()== 0.0){ + operateValidFlag = false;//操作不合法 + resultText.setFont(new Font("黑体", Font.BOLD, 40)); + resultText.setText("除数不能为零"); + //resultText.setFont(new Font("黑体", Font.BOLD, 55)); + } else { + resultNum /= getNumberFromText(); + } + } else if (operator.equals("+")){//加法运算 + resultNum += getNumberFromText(); + } else if (operator.equals("-")){//减法运算 + resultNum -= getNumberFromText(); + } else if (operator.equals("×")){//乘法运算 + resultNum *= getNumberFromText(); + } else if (operator.equals("=")){//赋值运算 + resultNum = getNumberFromText(); + processText.setText(null); + } else if (operator.equals("aⁿ")){ + resultNum = Math.pow(resultNum, getNumberFromText()); + } + if (key.equals("+")|| key.equals("×")|| key.equals("÷")|| key.equals("=")){ + processText.setText(processText.getText()+ resultText.getText()+ key); + } else if (key.equals("-")){ + processText.setText(processText.getText()+ resultText.getText()+"-"); + } else if (key.equals("aⁿ")){ + processText.setText(processText.getText()+ resultText.getText()+"^"); + } + + isOperateValidFlag(operateValidFlag); + operator = key;//运算符为用户按的按钮 + firstDigit = true; + if (operateValidFlag == false){ + processText.setText(null); + } + operateValidFlag = true; + } + + private void isOperateValidFlag(boolean operateValidFlag) { + if(operateValidFlag){//操作合法的情况下,将小数点后的位数进行处理 + long t1 =(long) resultNum; + double t2 = resultNum - t1;//得到小数部分 + BigDecimal bd = new BigDecimal(String.valueOf(resultNum));//得到小数位数 + if (t2 == 0){ + resultText.setText(String.valueOf(t1));//转化为字符串 + } else if (bd.scale()== 1){ + resultText.setText(String.valueOf(new DecimalFormat("0.0").format(resultNum))); + } else if (bd.scale()== 2){ + resultText.setText(String.valueOf(new DecimalFormat("0.00").format(resultNum))); + } else if (bd.scale()== 3){ + resultText.setText(String.valueOf(new DecimalFormat("0.000").format(resultNum))); + } else if (bd.scale()== 4){ + resultText.setText(String.valueOf(new DecimalFormat("0.0000").format(resultNum))); + } else if (bd.scale()== 5){ + resultText.setText(String.valueOf(new DecimalFormat("0,00000").format(resultNum))); + } else if (bd.scale()== 6){ + resultText.setText(String.valueOf(new DecimalFormat("0.000000").format(resultNum))); + } else if (bd.scale()== 7){ + resultText.setText(String.valueOf(new DecimalFormat("0.0000000").format(resultNum))); + } else if (bd.scale()== 8){ + resultText.setText(String.valueOf(new DecimalFormat("0.00000000").format(resultNum))); + } else { + resultText.setText(String.valueOf(new DecimalFormat("0.000000000").format(resultNum))); + } + } + } + private double getNumberFromText() { + double result = 0; + try { + result = Double.valueOf(resultText.getText()).doubleValue(); + } catch (NumberFormatException e){ + } + return result; + } + public static void main(String[] args){ + new Calculator(); + } + } + + + + + + + + + + + + + + \ No newline at end of file