程序的运行环境为Windows10 ,编译环境为IDEA。
计算器有以下功能和要求:能够计算复杂表达式,实现对多位数和负数以及小数的多则复杂计算
已完善功能(Bug):
1,能够计算大数字,小数,负数
2,小数点,运算符等不能连续输入(例如 ..,++,**等)
3,小数点前没有数字时自动补0并在输入框显示“0.”若小数点前是数字,且前面的数字串里含有".",则不能继续输入小数点(“.”---”0.“ ,1.11后面不能继续输入小数点)
4,‘(’左边和‘)’右边输入数字时,有运算符不做操作,无运算符自动补"*",")"后跟"(',在中间加‘*’(例如“7(”--“7*(”,“)7”--“(*7)”,“(1+1)(2+2)”--“(1+1)*(2+2)”)
5,输入的")"不能多于"(",且相邻()之间不能为空(“()”--X,“((1+2)))--X)
6,能计算负数,符号前面没有数字则补0 (-6-1 -- 0-6-1)
7,运算符除"-"号外不能第一个输入,若不是第一次计算,则可以直接输入,将上一个表达式的结果作为此次表达式的第一个运算数
8,查看历史记录,清空当前记录,清空历史记录,退格操作
运行结果如图:
实现过程:
一,计算器界面设计
1,初始化界面
通过 this 方法设置包括界面的大小,界面的位置(可根据屏幕设置中间位置),按键北面和中间排版及其颜色和大小,采用GridLayout网格布局
通过循环设置按键的位置,并将运算符加粗,并将所有按键和排版串联到界面上
class Main {
public static class Calculator extends JFrame implements ActionListener {
// 初始化界面
public void init() {
this.setTitle("计算器");
history.setEditable(false);
history.setFont(new Font("宋体", Font.PLAIN, 30));
this.setSize(477, 577); //界面大小
this.setLayout(new BorderLayout());
this.setResizable(false);
this.setLocationRelativeTo(null); //界面位置设置居中
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//北面的控件
private final JPanel key_north = new JPanel();
private final JTextField input_text = new JTextField();
private final JTextArea history = new JTextArea();
private final JButton c_btn = new JButton("C");
private final JButton ALLc_btn = new JButton("AC");
//中间的控件
private final JPanel center = new JPanel();
//将界面串联
public Calculator() throws HeadlessException {
this.init();
this.addNorthCompent();
this.addCenterButton();
}
//添加北面控键
public void addNorthCompent() {
this.history.setPreferredSize(new Dimension(350, 200));
this.input_text.setPreferredSize(new Dimension(450, 30));//输入框的大小
input_text.setBackground(new Color(127,255,212));
this.key_north.setBackground(new Color(193,255,193));
this.history.setBackground(new Color(193,255,120));
key_north.add(input_text);
key_north.add(history);
this.c_btn.setForeground(new Color(0,139,139));//按键颜色
this.ALLc_btn.setBackground(new Color(0,205,205));
key_north.add(c_btn);
key_north.add(ALLc_btn);
c_btn.setBackground(Color.CYAN);
c_btn.addActionListener(new ActionListener() { //为清除操作设置监听
@Override
public void actionPerformed(ActionEvent e) {
firstint = "";
input_text.setText("");
}
});
ALLc_btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
input_text.setText("");
firstint = "";
hitory = "";
history.setText("");
}
});
this.add(key_north, BorderLayout.NORTH);
}
//添加中间按键
public void addCenterButton() {
String key_text = "H()←123+456-789*0.=/";//中间控件排版
this.center.setLayout(new GridLayout(5, 4));
String regex = "[+\\-*/=H()←]";
for (int i = 0; i < 20; i++) { //初始化按键
String temp = key_text.substring(i, i + 1);
JButton key = new JButton();
key.setFont(new Font("宋体",Font.BOLD,20));
key.setForeground(new Color(69,139,116));
key.setBackground(new Color(193,255,193));
key.setText(temp);
if (temp.matches(regex)) { //将运算符加粗并更改颜色
key.setFont(new Font("粗体", Font.BOLD, 30));
key.setForeground(new Color(102,205,170));
}
key.addActionListener(this);
center.add(key);
}
this.add(center, BorderLayout.CENTER);
}
2,计算器功能设计
设置监听
设两个空字符串,一个用来保存表达式,另一个用来保存历史记录
为所有按键设置监听功能,将输入的表达式显示到文本框的右边,并实现计算结果,查看历史记录,清空历史记录,计算器表达式退格功能,判断表达式合法性.
@Override
public void actionPerformed(ActionEvent e) { //监听功能
String strings = e.getActionCommand();//保存记录
//JOptionPane.showMessageDialog(this,strings);//监听
if ("0123456789".contains(strings)) {
if (Objects.equals(firstint, "")) { //输入新的表达式,清除掉上一个表达式结果
firstint+=strings;
this.input_text.setText(strings);
this.input_text.setHorizontalAlignment(JTextField.RIGHT);//显示到右边
}else if(strings.equals("0")){
if (Objects.equals(firstint, "0")) {
this.input_text.setText(firstint);
}else {
int index = 0;
for ( int i=firstint.length()-1;i >=0;i-- ) {
if(isSymbol(firstint.substring(index))){
index=i;
}
}
if (!firstint.substring(index+1, firstint.length() - 1).equals("0")) {
firstint += strings;
}
this.input_text.setText(firstint);
}
} else if(firstint.charAt(firstint.length()-1)==')'){ //)后输入数字补*号
firstint+="*"+strings;
this.input_text.setText(firstint);
}else {this.input_text.setText(input_text.getText() + strings);//将输入的数记录并将之前的数放到前面
this.input_text.setHorizontalAlignment(JTextField.RIGHT);//显示到右边
firstint += strings;
System.out.println(firstint);}
} else if (strings.equals(".")) {
if (Objects.equals(firstint, "")) {
if (!Objects.equals(ans, "")) {
firstint = ans + ".";
this.input_text.setText(firstint);
}else {this.input_text.setText(input_text.getText() + "0" + strings);
this.input_text.setHorizontalAlignment(JTextField.RIGHT); //自带补0
firstint = "0" + strings;}
} else if(firstint.charAt(firstint.length() - 1) == ')'){ //)后输入小数点补0
firstint =firstint+ "*0"+strings;
this.input_text.setText(firstint);
}
else if (firstint.charAt(firstint.length() - 1) == '.') { //不能连续小数点
this.input_text.setText(firstint);