最近刚开始学习GUI界面的知识,就尝试做了一个计算器。
其实我主要做的是个界面,监听部分还是查询了资料。
package moder02;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
@SuppressWarnings("serial")
public class Calculator extends JFrame implements ActionListener {
private JTextField resultText = new JTextField("0");;
private JPanel contentPane;
private String[] M = {"MC", "MR", "M+", "M-", "MS"};
private JButton m[] = new JButton[M.length];
private String[] One = {"%", "sqrt", "x^2", "1/x", "CE", "C", "Del", "/",
"7", "8", "9", "*", "4", "5", "6", "-", "1", "2", "3", "+", "+/-", "0", ".","="};
private JButton o[] = new JButton[One.length];
private static boolean first;
private static String operator = "=";
private boolean operateValidFlag = true;
private double resultNum = 0.0;
public Calculator() {
super("【Chase Calculator");
setBounds(500, 150, 375, 375);//设置大小和出现位置
setResizable(false);//设置窗口为不可缩放
setBackground(Color.WHITE);
setVisible(true);//设置为可见
init();
}
public void init() {
contentPane = new JPanel(); //指定容器
setContentPane(contentPane);//设置 contentPane 属性
contentPane.setOpaque(false);//设置面板背景为透明
contentPane.setLayout(null);//设置为绝对布局
resultText.setHorizontalAlignment(JTextField.RIGHT);//设置文本框的文字为右对齐
resultText.setBackground(Color.WHITE);//设置文本框背景颜色
resultText.setBounds(0, 2, this.getWidth()-10, 50);//设置位置大小
Font f = new Font("黑体", Font.BOLD, 30);
resultText.setFont(f);//设置文本框中字体的大小
resultText.setEditable(false);//设置文本框中的内容不被修改
contentPane.add(resultText);//面板添加文本框
//添加按钮
for(int i = 0; i= 0) {//按下数字的响应
handleNumber(key);
}
else if("Del".equals(key)) {//按下Del键的响应
int i = resultText.getText().length();
if(i == 0) {
resultText.setText("0");
}else {
String s = resultText.getText().substring(0, i-1);
resultText.setText(s);
}
}
else if("C".equals(key)) {//初始化计算机信息
operateValidFlag = true;
operator = "=";
resultText.setText("0");
}
else if("CE".equals(key)) {//按下CE键响应
resultText.setText("0");//即重置文本框为0
}
else if("+".equals(key)||"-".equals(key)||"*".equals(key)||"/".equals(key)||"=".equals(key)
||"sqrt".equals(key)||"%".equals(key)||"1/x".equals(key)||"+/-".equals(key)) {//操作符处理
handleOperator(key);
}
}
/*
* 按下数字事件
*/
public void handleNumber(String s) {
if(first) {
resultText.setText(s);
}else if ((s.equals(".")) && (resultText.getText().indexOf(".") < 0)) {
resultText.setText(resultText.getText() + ".");
} else if (!s.equals(".")) {
resultText.setText(resultText.getText() + s);
}
first = false;
}
/*
* 得到当前文本数字
*/
private double getNumber() {
double result = 0;
try {
result = Double.valueOf(resultText.getText());
} catch (NumberFormatException e) {
}
return result;
}
/*
* 按下操作符事件
*/
private void handleOperator(String key) {
if (operator.equals("/")) {
if (getNumber() == 0.0) {
operateValidFlag = false;
resultText.setText("除数不能为零");
} else {
resultNum /= getNumber();
}
} else if (operator.equals("1/x")) { // 倒数运算
if (resultNum == 0.0) {
operateValidFlag = false;
resultText.setText("零没有倒数"); // 操作不合法
} else {
resultNum = 1 / resultNum;
}
} else if (operator.equals("+")) { // 加法运算
resultNum += getNumber();
} else if (operator.equals("-")) {// 减法运算
resultNum -= getNumber();
} else if (operator.equals("*")) {//乘法运算
resultNum *= getNumber();
} else if (operator.equals("sqrt")) {//平方根算法
resultNum = Math.sqrt(resultNum);
} else if (operator.equals("%")) {// 百分号运算,除以100
resultNum = resultNum / 100;
} else if (operator.equals("=")) { // 赋值运算
resultNum = getNumber();
}
else if (operator.equals("+/-")) {// 正数负数运算
resultNum = resultNum * (-1);
}
if (operateValidFlag) { // 双精度浮点数的运算
long t1;
double t2;
t1 = (long) resultNum;
t2 = resultNum - t1;
if (t2 == 0) {
resultText.setText(String.valueOf(t1));
} else {
resultText.setText(String.valueOf(resultNum));
}
}
operator = key;// 运算符等于用户按的按钮
first = true;
operateValidFlag = true;
}
public static void main(String[] args) {
new Calculator ();
}
}
计算器界面实现图片
中缀表达式
package com.rong.mycaculator;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
* 中缀表达式实现计算机(栈)
*/
public class MyCalculator {
private MyStack numStack;
private MyStack operStack;
private List sourceExp;
public MyCalculator() {
numStack = new MyStack(10);
operStack = new MyStack(10);
sourceExp = new ArrayList<>();
}
public int calculate(String exp) {
getExp(exp);
inStack(sourceExp);
return Integer.valueOf(numStack.peek());
}
public void inStack(List list) {
for(String str:sourceExp) {
if(isOper(str)){
if(operStack.isEmpty()) {
operStack.push(str);
}else{
if(prority(str) <= prority(operStack.peek())) {
int num1 = Integer.valueOf(numStack.pop());
int num2 = Integer.valueOf(numStack.pop());
String oper = operStack.pop();
int result = cal(num1, num2, oper);
numStack.push(String.valueOf(result));
operStack.push(str);
}else {
operStack.push(str);
}
}
}else if(isNum(str)) {
numStack.push(str);
}
}
while(!operStack.isEmpty()){
int num1 = Integer.valueOf(numStack.pop());
int num2 = Integer.valueOf(numStack.pop());
String oper = operStack.pop();
int result = cal(num1, num2, oper);
numStack.push(String.valueOf(result));
}
}
/**
* 加减运算
* @param num1
* @param num2
* @param oper
* @return
*/
public int cal(int num1,int num2,String oper){
int result = 0;
if(oper.equals("+")){
result = num2 + num1;
}
else if(oper.equals("-")) {
result = num2 - num1;
}
else if(oper.equals("*")) {
result = num2 * num1;
}
else if (oper.equals("/")) {
result = num2 / num1;
}
return result;
}
/**
*判断是否是数字
* @param str
*/
public boolean isNum(String str) {
return str.matches("[0-9]+");
}
/**
* 判断是否是操作符
*/
public boolean isOper(String str) {
return str.matches("[\\+\\-\\*\\/]");
}
/**
* 比较操作符的优先级,乘除大于加减
*/
public int prority(String oper) {
switch (oper) {
case"*":
case"/":
return 2;
case"+":
case"-":
return 1;
default:
return 0;
}
}
/**
* 将原始表达式拆分
* @param expression
*/
private void getExp(String expression) {
StringTokenizer st = new StringTokenizer(expression,"+-*/",true);
while (st.hasMoreTokens()) {
sourceExp.add(st.nextToken());
}
}
}
//栈
package com.rong.mycaculator;
public class MyStack {
//用数组来实现栈
private String[] stack;
//top指向栈顶元素
private int top;
//指定栈的大小
private int size;
public MyStack(int size) {
if(size < 0 ) {
System.out.println("栈大小不能小于0");
return;
}
this.size = size;
stack = new String[size];
top = -1;
}
/**
* 进栈操作
* @param num
*/
public void push(String num){
//判断是否栈满
if(isFull()) {
System.out.println("栈已满");
return;
}
stack[++top] = num;
}
/**
* 出栈操作
* @return
*/
public String pop() {
if(isEmpty()) {
return "栈为空";
}
return stack[top--];
}
/**
* 查看当前栈顶元素
*/
public String peek(){
return stack[top];
}
/**
* 判断栈是否已满
* @return
*/
public boolean isFull(){
return top == size-1;
}
/**
* 判断栈是否为空
* @return
*/
public boolean isEmpty() {
return top == -1;
}
}
测试
public class Mytest {
public static void main(String[] args) {
//中缀表达式
String exp = "2*3*2+4-5*1";
MyCalculator myCalculator = new MyCalculator();
System.out.println("===========计算结果===================");
System.out.println(exp+"="+myCalculator.calculate(exp));
}
}
//后缀表达式,这里使用MyStack类跟上面一样,如需测试别忘加入上面的MyStack类
package com.rong.mycaculator;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
* 中缀表达式转化为后缀表达式
*/
public class NewCalculator {
private MyStack operStack;
private List postFixList;
private List sourceExp;
public NewCalculator(){
operStack = new MyStack(10);
postFixList = new ArrayList<>();
sourceExp = new ArrayList<>();
}
/**
* 将中缀表达式转化为后缀表达式
* @param expression
* @return
*/
public List inFixConvertPostFix(String expression) {
//分解字符串
getExp(expression);
for(String str:sourceExp){
//如果是数字直接加入到集合里
if(isNum(str)) {
postFixList.add(str);
//如果操作符,先看当前操作符栈是否为空,为空直接压入栈
}else if(isOper(str)) {
if(operStack.isEmpty()) {
operStack.push(str);
//如果操作符栈不为空,如果当前栈顶操作符是(直接压入栈
} else {
//如果是(直接压入栈
if("(".equals(operStack.peek())){
operStack.push(str);
continue;
}
switch (str){
case"(":
operStack.push(str);
break;
case")":
String oper =operStack.pop();
while (!"(".equals(oper)) {
//将弹出地操作符添加到后缀表达式中
postFixList.add(oper);
oper = operStack.pop();
}
break;
case"+":
case"-":
case"*":
case"/":
while (!operStack.isEmpty() && prority(str) <= prority(operStack.peek())) {
postFixList.add(operStack.pop());
}
operStack.push(str);
break;
default:
break;
}
}
}
}
postFixList.add(operStack.pop());
return postFixList;
}
/**
* 判断是否为数字
* @param str
* @return
*/
public boolean isNum(String str){
return str.matches("[0-9]+");
}
/**
* 判断是否为操作符
* @param str
* @return
*/
public boolean isOper(String str) {
return str.matches("[\\+\\-\\*\\/\\(\\)]");
}
public int prority(String str) {
switch (str) {
case "(":
return 1;
case"+":
case"-":
return 2;
case"*":
case"/":
return 3;
default:
return 0;
}
}
/**
* 先将字符串分解
* @param exp
*/
public void getExp(String exp) {
StringTokenizer st = new StringTokenizer(exp,"+-*/()",true);
while (st.hasMoreTokens()){
sourceExp.add(st.nextToken());
}
}
/**
* 用后缀表达式进行计算
* @return
*/
public int calculator(List strings){
MyStack stack = new MyStack(10);
strings.forEach(str->{
if(isNum(str)){
stack.push(str);
}else if(isOper(str)) {
int num1 = Integer.valueOf(stack.pop());
int num2= Integer.valueOf(stack.pop());
int result = cal(num1, num2, str);
stack.push(result+"");
}
});
return Integer.valueOf(stack.pop());
}
public int cal(int num1,int num2,String oper) {
int result = 0;
if(oper.equals("+")){
result = num2 + num1;
}
else if(oper.equals("-")) {
result = num2 - num1;
}
else if(oper.equals("*")) {
result = num2 * num1;
}
else if (oper.equals("/")) {
result = num2 / num1;
}
return result;
}
}
测试
public class Mytest {
public static void main(String[] args) {
//后缀表达式
String exp = "(1+2)*(4+5)";
NewCalculator nc = new NewCalculator();
List strings = nc.inFixConvertPostFix(exp);
System.out.println("================后缀表达式===============");
strings.forEach(s->{
System.out.print(s+"\t");
});
System.out.println();
System.out.println("================计算结果================");
int calculator = nc.calculator(strings);
System.out.println(exp+"="+calculator);
}
}