java新手,写了个简单的计算器,求高手指点一二
生活随笔
收集整理的這篇文章主要介紹了
java新手,写了个简单的计算器,求高手指点一二
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
package y2019.m08.d24;import java.awt.*;
import java.awt.event.*;
import java.math.BigDecimal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** 簡單的計算器* * @author luther* @日期 2019.8.25* @version 1.0* * 有待優(yōu)化的地方 BUG:* 1,Button增加回退按鍵監(jiān)聽* 2,增加括號運算(),指數(shù)運算* 3,界面優(yōu)化* 4,末尾去0和小數(shù)點* 5,文本框全選輸入時 覆蓋* 6,增加回退,清空,括號等Button按鍵* 7,* */
public class MyCalc {public static void main(String[] args) {new MyCalc().init();}/*多次需要使用的正則表達(dá)式,運算符,減號需要轉(zhuǎn)義,否則表示范圍了,如[a-z];運算數(shù),包含整數(shù)或小數(shù)*/private static final String OPERS = "[\\+\\-\\*/]";private static final String NUMBER = "((\\d+\\.\\d*)|\\d+)";//定義是否剛剛進(jìn)行過計算,用于下一次輸入前清空文本框private boolean isDoCalc = false;//按鍵4*4按鈕文本private static final String[] BUTTS = {"7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", "0", ".", "=", "/"};//按鍵4*4按鈕private Button[] bs = new Button[BUTTS.length];//主窗口,使用默認(rèn)的5方向管理器private Frame f = new Frame("計算器");//輸入框private TextField tf = new TextField(30);//4*4按鍵區(qū)private Panel p = new Panel(new GridLayout(4, 4));/*** 初始化入口*/public void init() {//輸入框背景色,銀色tf.setBackground(new Color(0xE6E8FA));//輸入框注冊按鍵監(jiān)聽器,實現(xiàn)1,ESC退出程序,//2,計算后,清空文本區(qū);3,Enter回車鍵進(jìn)行計算tf.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {System.exit(0);}else if(isDoCalc) {tf.setText("");isDoCalc = false;}else if(e.getKeyCode() == KeyEvent.VK_ENTER){doCalc();}}});//4*4按鈕Button監(jiān)聽器ActionListener bListener = new ActionListener() {public void actionPerformed(ActionEvent e) {if(e.getActionCommand().equals("=")) {doCalc();}else{String cmd = e.getActionCommand();tf.setText(isDoCalc ? (isDoCalc = false) ? "" : cmd : tf.getText() + cmd);}}};//4*4按鍵監(jiān)聽器KeyAdapter bkListener = new KeyAdapter() {public void keyPressed(KeyEvent e) {String code = KeyEvent.getKeyText(e.getKeyCode());if(code.equals("Enter")) {doCalc();}else if(code.startsWith("NumPad") || code.matches("\\d")) {code = code.substring(code.length() - 1);tf.setText(isDoCalc ? (isDoCalc = false) ? "" : code : tf.getText() + code);}else{//System.out.println(code);}}};//初始化按鍵,注冊監(jiān)聽器ActionListener和KeyListener,并組合成4*4按鍵區(qū)for(int i = 0; i < BUTTS.length; i++) {bs[i] = new Button(BUTTS[i]);bs[i].addActionListener(bListener);bs[i].addKeyListener(bkListener);p.add(bs[i]);}//Frame注冊WindowListener監(jiān)聽器,實現(xiàn)關(guān)閉按鈕f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {Runtime.getRuntime().exit(0);}});//Frame組合,初始化f.add(tf, BorderLayout.NORTH);f.add(p);f.setLocation(800, 300);f.pack();f.setVisible(true);}/*** 獲取計算表達(dá)式,顯示計算結(jié)果*/private void doCalc() {tf.setText(recCalc(tf.getText()));}/*** 遞歸計算recursive algorithm* @param repre 需要計算的字符串* @return 計算的結(jié)果*/private String recCalc(String exp) {//去掉末尾的小數(shù)點和0//表達(dá)式校驗1,無法計算的表達(dá)式,2只有一個數(shù)的表達(dá)式,3只需一次計算的表達(dá)式,4多次運算if(!exp.matches("^" + NUMBER + "(" + OPERS + NUMBER + ")*$")) {isDoCalc = true;return "無法計算";}else if(exp.matches(NUMBER)) {return exp;}else if(exp.matches("^" + NUMBER + OPERS + NUMBER + "$")) {return simpleCalc(exp);}else {//兩個字符串:子計算結(jié)果和新表達(dá)式,進(jìn)入該分支必定是包含2個運算符及以上String subResult = "";String result = exp;//獲取子表達(dá)式,先獲取乘除表達(dá)式Matcher m = Pattern.compile(NUMBER + "(\\*|/)" + NUMBER).matcher(exp);if (m.find()) {subResult = m.group();}else {m = Pattern.compile(NUMBER + OPERS + NUMBER).matcher(exp);m.find();subResult = m.group();}//替換子表達(dá)式轉(zhuǎn)換成正則表達(dá)式即子字符串的+和*需要轉(zhuǎn)義String regex = subResult.replaceFirst("\\b+(?=[\\+\\*])", "\\\\");//把子表達(dá)式替換成計算結(jié)果result = result.replaceFirst(regex, simpleCalc(subResult));return recCalc(result);}}/*** 二目運算,兩個數(shù)的加減乘除計算,使用BigDecimal的精確計算* @param repre 兩個需要計算的數(shù),中間帶一個運算符* @return 返回計算結(jié)果,如果計算失敗返回"未知錯誤!"* */private String simpleCalc(String repre) {//合法性校驗if(!repre.matches(NUMBER + OPERS + NUMBER)) {return "未知錯誤1!";}//獲取運算符Matcher m = Pattern.compile(OPERS).matcher(repre);m.find();String oper = m.group();//獲取2個數(shù)字String[] nums = repre.split(OPERS);BigDecimal b1 = new BigDecimal(nums[0]);BigDecimal b2 = new BigDecimal(nums[1]);//精確計算switch (oper) {case "+" :return b1.add(b2).doubleValue()+"";case "-" :return b1.subtract(b2).doubleValue()+"";case "*" :return b1.multiply(b2).doubleValue()+"";case "/" :return b1.divide(b2, 20, BigDecimal.ROUND_HALF_UP).doubleValue()+"";default :return "未知錯誤2!";}}}
自己寫了一整天,希望大佬能夠指點一下,提供下示例代碼也好啊
非常感謝!
總結(jié)
以上是生活随笔為你收集整理的java新手,写了个简单的计算器,求高手指点一二的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# 传递数组参数_一维数组_二维数组
- 下一篇: 重磅!美图技术团队发布开源 ethere