计算器的GUI编程可以手动写代码,因为计算器的组件不是很多,手动写组件工作量不是很大,因为我在这两天在学习使用WindowBulider插件,所以我就使用插件完成的计算器GUI设计。
程序可能由BUG,能力有限,希望大家理解,也希望给大家有所帮助
1.首先是GUI部分
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.GridLayout;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.SwingConstants;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.UIManager;
import java.awt.Color;
public class Caltulator_UI extends JFrame {
private JPanel contentPane;
private JTextField textField;
public static int count=1;
/**
* Launch the application.
* 创建计算器基本图形
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
//计算机界面
Caltulator_UI frame = new Caltulator_UI();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* 创建textField的GET方法
*/
public String getTextField() {
return textField.getText();
}
/**
* Create the frame.
* 构造方法
*/
public Caltulator_UI() {
//窗体基本设置
setTitle("\u8BA1\u7B97\u5668");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(600, 200, 550, 550);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
//第一个JPanel面板,包含文本框,显示计算数据
JPanel panel = new JPanel();
panel.setBounds(5, 5, 516, 70);
contentPane.add(panel);
panel.setLayout(null);
textField = new JTextField();
textField.setEditable(false);
textField.setBackground(UIManager.getColor("TextPane.selectionBackground"));
textField.setFont(new Font("宋体", Font.PLAIN, 30));
textField.setHorizontalAlignment(JTextField.RIGHT);
textField.setBounds(56, 13, 415, 57);
panel.add(textField);
textField.setColumns(10);
//第二个JPaner面板,主要是按钮组件,并设置监听器
JPanel panel_1 = new JPanel();
panel_1.setBounds(5, 110, 520, 316);
contentPane.add(panel_1);
panel_1.setLayout(new GridLayout(5, 5, 10, 10));
JButton btnNewButton = new JButton("7");
btnNewButton.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton);
JButton btnNewButton_1 = new JButton("8");
btnNewButton_1.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_1);
JButton btnNewButton_2 = new JButton("9");
btnNewButton_2.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_2);
JButton btnNewButton_3 = new JButton("/");
btnNewButton_3.setForeground(new Color(138, 43, 226));
btnNewButton_3.setBackground(UIManager.getColor("Desktop.background"));
btnNewButton_3.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_3);
JButton btnNewButton_4 = new JButton("4");
btnNewButton_4.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_4);
JButton btnNewButton_5 = new JButton("5");
btnNewButton_5.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_5.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_5);
JButton btnNewButton_6 = new JButton("6");
btnNewButton_6.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_6.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_6);
JButton btnNewButton_7 = new JButton("*");
btnNewButton_7.setBackground(UIManager.getColor("Desktop.background"));
btnNewButton_7.setForeground(new Color(138, 43, 226));
btnNewButton_7.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_7.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_7);
JButton btnNewButton_8 = new JButton("1");
btnNewButton_8.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_8.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_8);
JButton btnNewButton_9 = new JButton("2");
btnNewButton_9.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_9.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_9);
JButton btnNewButton_10 = new JButton("3");
btnNewButton_10.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_10.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_10);
JButton btnNewButton_11 = new JButton("+");
btnNewButton_11.setBackground(UIManager.getColor("Desktop.background"));
btnNewButton_11.setForeground(new Color(138, 43, 226));
btnNewButton_11.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_11.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_11);
JButton btnNewButton_12 = new JButton("0");
btnNewButton_12.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_12.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_12);
JButton btnNewButton_13 = new JButton(".");
btnNewButton_13.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_13.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_13);
JButton btnNewButton_14 = new JButton("=");
btnNewButton_14.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_14.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
String ss=textField.getText();
System.out.println(ss); //测试
Calculate calculate=new Calculate();
String num=calculate.calcluate(ss);
System.out.println(num); //测试
textField.setText(num);
}
});
panel_1.add(btnNewButton_14);
JButton btnNewButton_19 = new JButton("-");
btnNewButton_19.setBackground(UIManager.getColor("Desktop.background"));
btnNewButton_19.setForeground(new Color(138, 43, 226));
btnNewButton_19.setFont(new Font("微软雅黑", Font.BOLD | Font.ITALIC, 50));
btnNewButton_19.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_19);
JButton btnNewButton_15 = new JButton("AC");
btnNewButton_15.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_15.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText("");
}
});
panel_1.add(btnNewButton_15);
//负号
JButton btnNewButton_16 = new JButton("_");//为便于与减号进行区分,此处用中文输入法的负号
btnNewButton_16.setFont(new Font("微软雅黑", Font.BOLD | Font.ITALIC, 10));
btnNewButton_16.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
/**
* 设置静态成员变量控制负号的输入
*/
if(count%2==0) {//按第二次
String str=textField.getText()+e.getActionCommand();
textField.setText(str.substring(0,str.length()-2));
}
if(count%2==1) {
textField.setText(textField.getText()+e.getActionCommand());
}
count++;
}
});
panel_1.add(btnNewButton_16);
JButton btnNewButton_17 = new JButton("(");
btnNewButton_17.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_17.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_17);
JButton btnNewButton_18 = new JButton(")");
btnNewButton_18.setFont(new Font("宋体",Font.BOLD,30));
btnNewButton_18.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+e.getActionCommand());
}
});
panel_1.add(btnNewButton_18);
JPanel panel_2 = new JPanel();
panel_2.setBounds(103, 439, 259, 50);
contentPane.add(panel_2);
panel_2.setLayout(null);
JButton btnNewButton_20 = new JButton("DEL");
btnNewButton_20.setFont(new Font("宋体", Font.BOLD, 30));
btnNewButton_20.setBounds(48, 0, 211, 45);
btnNewButton_20.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String sa=textField.getText();
textField.setText(sa.substring(0, sa.length()-1));
}
});
panel_2.add(btnNewButton_20);
}
}
2.然后是核心代码计算部分,在这一块使用栈的数据结构,并且直接是进行中缀表达式计算,这就要求我们必须设置加减乘除和括号的优先级。具体的说明代码上有相应的注释,大家仔细看看。
import java.awt.TextField;
import java.math.BigDecimal;
import java.util.Stack;
public class Calculate {
private String str_textField=null;//获取GUI文本框的字符串
/**
* 进行整数计算所用的栈
*/
private Stack<Character> stack_char;//创建栈用来存储运算字符
private Stack<Double> stack_int;//创建栈用来存储运算数字
/**
* 进行浮点数计算所用的栈
* @param c
*/
private Stack<Character> stack_char2=null;//创建栈用来存储运算字符
private Stack<BigDecimal> stack_double=null;//创建栈用来存储运算浮点数数字
//将计算的字符串的值传入到该类的成员变量中
public void setStr(Caltulator_UI c) {
str_textField=c.getTextField();
}
//获取文本框中的字符串
public String getStr() {
return str_textField;
}
//判断从字符串中取出的字符是否是数字
public boolean isNumber(char c) {
if(c>='0'&&c<='9') {
return true;
}else {
return false;
}
}
//判断括号和运算符的优先级
/**
* 第1级: (
第2级: * /
第3级: + -
第4级: )
* @param symbol
* @return
*/
public boolean comparePri(char symbol,boolean b) {
//浮点数
if(b==true) {
if(stack_char2.empty()) {//如果符号栈为空,返回true,即能直接入栈
return true;
}else {
char top=(char)stack_char2.peek();//查看栈顶元素,将栈顶元素和当前字符进行比较并判断是进行运算还是入栈
if(top=='(') {
return false;
}
//进行优先级的比较
switch(symbol) {
case'('://左括号优先级最高
return false;
case'*':{
if (top == '+' || top == '-') // 优先级比+和-高
return false;
else
return true;
}
case'/':{
if (top == '+' || top == '-') // 优先级比+和-高
return false;
else
return true;
}
case'+':
return false;//优先级最低
case'-':
return false;//优先级最低
case ')': // 优先级最高
return true;
case '=': // 优先级最高
return true;
default:
break;
}
}
}
if(b==false) {
//整数
if(stack_char.empty()) {//如果符号栈为空,返回true,即能直接入栈
return true;
}else {//若栈不为空
char top=(char)stack_char.peek();//查看栈顶元素,将栈顶元素和当前字符进行比较并判断是进行运算还是入栈
if(top=='(') {
return false;
}
//进行优先级的比较
switch(symbol) {
case'('://左括号优先级最高
return false;
case'*':{
if (top == '+' || top == '-') // 优先级比+和-高
return false;
else
return true;
}
case'/':{
if (top == '+' || top == '-') // 优先级比+和-高
return false;
else
return true;
}
case'+':
return false;//优先级最低
case'-':
return false;//优先级最低
case ')': // 优先级最高
return true;
case '=': // 优先级最高
return true;
default:
break;
}
}
}
return true;
}
//添加方法判断字符串是整数字符串还是浮点数字符串
public boolean compare(String ss) {
boolean bool = false;
for(int i=0;i<ss.length();i++) {
if(ss.charAt(i)=='.') {
bool= true;
break;
}else {
bool= false;
}
}
return bool;
}
//计算方法 将运算式转换为后缀表达式,然后计算后缀表达式
public String calcluate(String s) {
String ss=null;//返回的字符串
//开始时进行字符串判断,即浮点数字符串和整数字符串判断,false为整数,true为浮点数
/**
* 将最终的返回类型设置为字符串类型,
*/
boolean bool;
bool=compare(s);//调用字符串判断方法判断是整数字符串还是浮点数字符串
//整数计算
if(bool==false) {
//初始化栈
stack_char=new Stack();//字符栈实例化
stack_int=new Stack();//数字栈实例化
//设置字符缓冲 用于缓存数字,因为数字可能是多位的
StringBuffer temp = new StringBuffer();
//从获取的表达式的第一个字符串进行处理操作
for(int i=0;i<s.length();i++) {
char ch1=s.charAt(i);//获取一个字符
if(isNumber(ch1)||ch1=='_') {//如果该字符是数字
if(ch1=='_') {
ch1='-';
}
temp.append(ch1);//将数字添加到缓冲中
}else {//如果不是数字
String string=temp.toString();//将数字缓冲转换成字符串 例如12
if (!string.isEmpty()) {
double num = Double.parseDouble(string); // 将数字字符串转为长整型数 12
stack_int.push(num); // 将数字压栈
temp = new StringBuffer(); // 重置数字缓存
}
// 判断运算符的优先级,若当前优先级低于栈顶的优先级,则先把计算前面计算出来
// && !stack_char.empty()
while (comparePri(ch1,bool)!=false && stack_char.empty()!=true) {
double b=stack_int.pop();
double a=stack_int.pop();//出栈
//将取出的数字进行运算,并且将当前运算的计算结果在此压入栈中
//查看符号栈顶符号
char z=stack_char.pop();
switch(z) {
case'+':
stack_int.push(a+b);
break;
case'-':
stack_int.push(a-b);
break;
case'*':
stack_int.push(a*b);
break;
case'/':
stack_int.push(a/b);
break;
default:
break;
}
}//while循环结束
if(ch1!='=') {
stack_char.push(new Character(ch1));//符号入栈
if(ch1==')') {//进行去括号操作
stack_char.pop();
stack_char.pop();
//stack_char.pop();
}
}
}//else
}//for循环
double ab=stack_int.pop();
ss=String.valueOf(ab);
}//if语句结束
//浮点数计算
if(bool==true) {
//实例化栈
stack_char2=new Stack();
stack_double=new Stack();
//设置字符缓冲 用于缓存数字,因为数字可能是多位的
StringBuffer temp2 = new StringBuffer();
for(int i=0;i<s.length();i++) {
char ch2=s.charAt(i);//获取第一个字符
if(isNumber(ch2)) {
temp2.append(ch2);
}else if(ch2=='.') {
temp2.append(ch2);
}
else {//如果不是数字并且不是小数点
String string=temp2.toString();
if(!string.isEmpty()) {
BigDecimal num=new BigDecimal(string);
stack_double.push(num);
temp2=new StringBuffer();
}
while(comparePri(ch2,bool)!=false && stack_char2.empty()!=true) {
BigDecimal b=stack_double.pop();
BigDecimal a=stack_double.pop();
char z2=stack_char2.pop();
switch(z2) {
case'+':
stack_double.push(a.add(b));
break;
case'-':
stack_double.push(a.subtract(b));
break;
case'*':
stack_double.push(a.multiply(b));
break;
case'/':
try {
stack_double.push(a.divide(b));
}catch(java.lang.ArithmeticException e){
// 进行除法出现无限循环小数时,就会抛异常,此处设置精度重新计算
// stack_double.push(a.divide(b, this.scale,
// BigDecimal.ROUND_HALF_EVEN));
}
break;
default:
break;
}
}//while循环结束
if(ch2!='=') {
stack_char2.push(new Character(ch2));//符号入栈
if(ch2==')') {//进行去括号操作
stack_char2.pop();
stack_char2.pop();
}
}
}
}//for循环结束
BigDecimal ab=stack_double.pop();
ss=String.valueOf(ab);
}
return ss;
}
public static void main(String[] args) {
}
}
3简单的测试:输入计算式,按等号按钮即可输出结果