Java实现图形界面计算器
本文实例为大家分享了Java实现图形界面计算器的具体代码,供大家参考,具体内容如下
文章图片
代码:
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Stack; public class Calculator extends JFrame implements ActionListener {private final String[] ButtonNames = {"(", ")", "←", "C", "7", "8", "9", "+", "4", "5","6", "-", "1", "2", "3", "*", ".", "0", "=", "/"}; private JTextField DisplayBox = new JTextField("0.0"); private JTextField Cache = new JTextField(""); private JButton[] Buttons = new JButton[ButtonNames.length]; public Calculator() {super(); setTitle("计算器"); init(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 400, 600); setResizable(false); //窗口不可调整大小setVisible(true); } private void init() {//完成布局以及定义监听器DisplayBox.setHorizontalAlignment(JTextField.RIGHT); //文本框右对齐DisplayBox.setFont(new Font("DIN", Font.BOLD, 30)); //DIN:一种数字常用字体Cache.setFont(new Font("DIN", Font.BOLD, 30)); GridBagLayout gridBagLayout = new GridBagLayout(); //采取网格包布局GridBagConstraints gridBagConstraints = new GridBagConstraints(); gridBagConstraints.fill = GridBagConstraints.BOTH; //该方法是为了设置如果组件所在的区域比组件本身要大时的显示情况gridBagConstraints.weightx = 1; //使组件的大小取得最大空间gridBagConstraints.weighty = 1; setLayout(gridBagLayout); gridBagConstraints.gridx = 0; //缓存区起始位置为(0,0),横向占据4格,纵向1格gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 4; gridBagConstraints.gridheight = 1; gridBagLayout.setConstraints(Cache, gridBagConstraints); this.add(Cache); gridBagConstraints.gridx = 0; //文本框起始位置为(0,0),横向占据4格,纵向2格gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 4; gridBagConstraints.gridheight = 2; gridBagLayout.setConstraints(DisplayBox, gridBagConstraints); this.add(DisplayBox); gridBagConstraints.gridy = 3; //按钮起始位置为(0,3)gridBagConstraints.gridwidth = 1; //每个按钮占据1格gridBagConstraints.gridheight = 1; for (int i = 0; i < ButtonNames.length; i++) {Buttons[i] = new JButton(ButtonNames[i]); }int n = 0; //记录每一行输出的按钮数,满4换行for (int i = 0; i < Buttons.length; i++) {gridBagLayout.setConstraints(Buttons[i], gridBagConstraints); this.add(Buttons[i]); n++; if (n == 4) {gridBagConstraints.gridx = 0; gridBagConstraints.gridy++; n = 0; } else {gridBagConstraints.gridx++; }} for (int i = 0; i < Buttons.length; i++) {//事件监听器Buttons[i].addActionListener(this); }} @Overridepublic void actionPerformed(ActionEvent e) {//对事件的处理String str; String value = https://www.it610.com/article/e.getActionCommand(); //获取按钮的值char v = value.charAt(0); switch (v) {case'C':DisplayBox.setText("0.0"); break; case '←':DeleteOne(); break; case '=':String string = DisplayBox.getText(); Cache.setText(string + "="); if (isTrue(string)) {//若格式正确str = retureResult(); DisplayBox.setText(str); } else {DisplayBox.setText("输入格式不合法"); }break; default:AddOne(value); break; }} private void DeleteOne() {//删除一个字符String str; str = DisplayBox.getText(); if (str.length() == 1) {DisplayBox.setText("0.0"); } else if(!str.equals("0.0")) {str = str.substring(0, str.length() - 1); //去掉最后一个元素DisplayBox.setText(str); }} private void AddOne(String value) {//增加一个字符String str; str = DisplayBox.getText(); if (str.equals("0.0")) {//第一次输入DisplayBox.setText(value); } else {str = str + value; DisplayBox.setText(str); }} private String retureResult() {//对输入的式子进行运算;基本方法:逆波兰法,中缀转后缀String string = DisplayBox.getText(); String[] Midfix = breakDown(string); //中缀表达式的数组String[] suffix = Conversion(Midfix); //得到后缀表达式String result = Calculation(suffix); //计算后缀表达式结果return result; } private String Calculation(String[] suffix) {Stack stack = new Stack<>(); String symbols = "+-*/"; //转换为后缀表达式的式子只会有 +-*/ 符号不会有 ()for (int i = 0; i < suffix.length; i++) {if (suffix[i] == null) {//suffix后面可能出现null 故对其筛选不进行下列的操作continue; }if (symbols.indexOf(suffix[i]) >= 0) {//为符号时进行运算double top1; double top2; double top; switch (suffix[i]) {case "+":top1 = Double.parseDouble(stack.pop()); //取栈顶将其转化为doubletop2 = Double.parseDouble(stack.pop()); top = top2 + top1; stack.push(String.valueOf(top)); //将top转化为String入栈break; case "-":top1 = Double.parseDouble(stack.pop()); top2 = Double.parseDouble(stack.pop()); top = top2 - top1; stack.push(String.valueOf(top)); break; case "*":top1 = Double.parseDouble(stack.pop()); top2 = Double.parseDouble(stack.pop()); top = top2 * top1; stack.push(String.valueOf(top)); break; case "/":top1 = Double.parseDouble(stack.pop()); top2 = Double.parseDouble(stack.pop()); if (top1 == 0) {return "运算过程中除数出现0"; }top = top2 / top1; stack.push(String.valueOf(top)); break; }} else {//为数字直接入栈stack.push(suffix[i]); }}String result = stack.pop(); return result; } private String[] breakDown(String string) {//将(2+3.14)+9分解成 ( 2 + 3.14 ) + 9便于后续计算String[] split = string.split(""); String DigitString = "0123456789."; String afterSplit = ""; for (int i = 0; i < split.length; i++) {//将 2+3.14 变成 2,+,3.14 便于拆分if (DigitString.indexOf(split[i]) >= 0) {afterSplit = afterSplit + split[i]; } else if(afterSplit.equals("") && DigitString.indexOf(split[i]) < 0) { //第一个为符号时只在后面加。afterSplit = afterSplit + split[i] + ","; } else {//为 () 或 =-*/ 在其两侧加上 ,afterSplit = afterSplit + "," + split[i] + ","; }}afterSplit = afterSplit.replace(",,", ","); //避免(2+3)+2产生……3,),,+,2split = afterSplit.split(","); //产生的字符串数组中只会含+-*/()整数和小数return split; } private String[] Conversion(String[] strings) {//中缀转后缀String[] suffix = new String[strings.length]; //后缀表达式int n = 0; //suffix的下标Stack stack = new Stack<>(); String first = "*/"; String symbols = "+-*/()"; for (int i = 0; i < strings.length; i++) {if(symbols.indexOf(strings[i]) >= 0) {//为符号时if (stack.empty()) {stack.push(strings[i]); } else {//栈不为空if(first.indexOf(strings[i]) >= 0 || strings[i].equals("(")) {//为 +/( 直接入栈stack.push(strings[i]); }else if(strings[i].equals(")")) {String top = stack.peek(); while(!top.equals("(")) {top = stack.pop(); suffix[n] = top; n++; top = stack.peek(); }stack.pop(); // ( 出栈} else {//符号为 +-if(first.indexOf(stack.peek()) < 0) { //当栈顶不为为 */ 直接入栈stack.push(strings[i]); } else {while (!stack.empty() && first.indexOf(stack.peek()) >= 0)//栈顶运算符先于当前运算符时,出栈到栈顶运算符低于或栈为空为止{String s = stack.pop(); suffix[n] = s; n++; }stack.push(strings[i]); //当前运算符入栈}}}} else {//为数字直接成为后缀一部分suffix[n] = strings[i]; n++; }}while (!stack.empty()) {//清除栈内剩余符号String s = stack.pop(); suffix[n] = s; n++; }return suffix; } private boolean isTrue(String str) {if (!BracketMatching(str)) {//括号匹配return false; }if (!OperatorIsTrue(str)) {//符号格式正确return false; }return true; } private boolean OperatorIsTrue(String string) { //运算数数量 = 运算符号数+1String[] split = breakDown(string); String symblos = "+-*/"; String bracket = "()"; int NumberOfDigits = 0; int NumberOfSymblos = 0; for (int i = 0; i < split.length; i++) {if(symblos.indexOf(split[i]) >= 0) {NumberOfSymblos++; } else if(bracket.indexOf(split[i]) < 0) { //不是括号 不是运算符一定为运算数NumberOfDigits++; }}if (NumberOfDigits != NumberOfSymblos + 1) {return false; }return true; } private boolean BracketMatching(String string) {//判断括号是否匹配,否则报错char[] split = string.toCharArray(); Stackstack = new Stack<>(); for (int i = 0; i < split.length; i++) {if (split[i] == '(') {stack.push(split[i]); } else if (!stack.empty() && split[i] == ')') {stack.pop(); } else if (stack.empty() && split[i] == ')') {return false; }}if (!stack.empty()) {return false; }return true; }public static void main(String[] args) {Calculator calculator = new Calculator(); }}
【Java实现图形界面计算器】以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 事件代理
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Java|Java OpenCV图像处理之SIFT角点检测详解
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树