功能描述:
1.能够实现整数和浮点数的“加减乘除”功能
2.有【回退】、【清空】功能
网上有很多关于计算器的代码,但是大都是界面设计和监听事件都放在一个Calculator类中实现的逻辑,我将这种实现进行了拆分。
这样做的好处在于,将界面设计和具体业务逻辑相分离,降低耦合度,有利于程序的可扩展性和可维护性。主要拆分成这样几个部分:
【CalculatorView类】
package com.sugon.calculator;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
/**
* @date: 2020/12/26 20:47
* @description:To realize the function of addition, subtraction, multiplication and division of calculator
*/
public class CalculatorView extends JFrame {
private JTextField txtResult = new JTextField();
private ActionListener listener;
public JTextField getTxtResult() {
return txtResult;
}
public void setTxtResult(JTextField txtResult) {
this.txtResult = txtResult;
}
public ActionListener getListener() {
return listener;
}
public void setListener(ActionListener listener) {
this.listener = listener;
}
public CalculatorView() {
}
public void init() {
setTitle("计算器");
setSize(300, 270);
setResizable(false);
//When the window is set to null, the window will be displayed at the center of the screen,
// otherwise it will be displayed in the upper left corner.
setLocationRelativeTo(null);
// Set the closing mode of the form
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Get a container object
Container contentPane = this.getContentPane();
// Border layout
contentPane.setLayout(new BorderLayout(1, 5));
// Create two new panel objects
JPanel pnlNorth = new JPanel();
JPanel pnlCenter = new JPanel();
// Set panel layout
pnlNorth.setLayout(new BorderLayout());
pnlCenter.setLayout(new GridLayout(4, 4, 3, 3));
// Define font style
Font font = new Font(CalConstant.FONT_STYLE, Font.BOLD, 20);
// Add two panels to the container
contentPane.add(BorderLayout.NORTH, pnlNorth);
contentPane.add(BorderLayout.SOUTH, pnlCenter);
// Set text box
// txtResult = new JTextField();
txtResult.setFont(font);
txtResult.setEnabled(false);
// listner
// ComActionListener listener = new ComActionListener(txtResult);
// Set the clear button and backspace button
JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.setPreferredSize(new Dimension(300, 20));
JButton btnBack = new JButton(CalConstant.BACK);
JButton btnClear = new JButton(CalConstant.CLEAR);
btnBack.addActionListener(listener);
btnClear.addActionListener(listener);
panel.add(btnBack);
panel.add(btnClear);
contentPane.add(BorderLayout.CENTER, panel);
// Place the text box and clear button in the top panel
pnlNorth.add(BorderLayout.CENTER, txtResult);
// Put numbers and operators into the pnlcentre panel, and set font size and bind listening events
String[] captions = {"7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", "0", ".", "/", "=",};
int length = captions.length;
for (int i = 0; i < length; i++) {
JButton button = new JButton(captions[i]);
button.setFont(font);
pnlCenter.add(button);
button.addActionListener(listener);
}
setVisible(true);
}
}
【ComActionListener类】
package com.sugon.calculator;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
*
* @date: 2020/12/29 14:15
* @description:
*/
public class ComActionListener implements ActionListener{
private JTextField txtResult;
private static StringBuffer number = new StringBuffer("");
private BigDecimal number1 = new BigDecimal("0");
private BigDecimal number2 = new BigDecimal("0");
// Used to identify operators
private static String flag = "=";
//Judge whether divisor is zero
private boolean validFlag = true;
public JTextField getTxtResult() {
return txtResult;
}
public void setTxtResult(JTextField txtResult) {
this.txtResult = txtResult;
}
public ComActionListener(){
}
public ComActionListener(JTextField jTextField){
this.txtResult = jTextField;
}
/**
* Invoked when an action occurs.
*
* @param e
*/
@Override
public void actionPerformed(ActionEvent e) {
String label = e.getActionCommand();
if (CalConstant.BACK.equals(label)) {
// Backspace button
// To prevent crossing the border, add a judgment
if (number.length() > 0) {
number.deleteCharAt(number.length() - 1);
txtResult.setText(number.toString());
} else {
txtResult.setText(CalConstant.ZERO);
}
}else if (CalConstant.CLEAR.equals(label)) {
// Clear button
number.delete(0,number.length());
txtResult.setText(CalConstant.ZERO);
} else if (CalConstant.POINT.equals(label)){
point();
} else if ("0123456789".indexOf(label) >= 0) {
number.append(label);
txtResult.setText(number.toString());
}else {
handleOperator(label);
}
}
/**
*
* Logic of addition, subtraction, multiplication and division
* @param label
*/
private void handleOperator(String label) {
if (!number.toString().equals("")) {
if ("+-*/".indexOf(label) >= 0) {
flag = label;
number1 = new BigDecimal(number.toString());
number.delete(0, number.length());
txtResult.setText(null);
}
if (CalConstant.EQUAL.equals(label)) {
number2 = new BigDecimal(number.toString());
number.delete(0, number.length());
BigDecimal result = new BigDecimal(CalConstant.ZERO);
switch (flag) {
case CalConstant.MULTIPLY:
result = number1.multiply(number2);
break;
case CalConstant.REDUCE:
result = number1.subtract(number2);
break;
case CalConstant.PLUS:
result = number1.add(number2);
break;
case CalConstant.DIVIDE:
if (new BigDecimal(CalConstant.ZERO).equals(number2)){
validFlag = false;
}else {
// edit 2020.12.27 reason:When doing division, try to use divide (big decimal divisor, int scale, int roundingmode).
// If this method does not specify the number of decimal places to be reserved, an error will be reported in case of endless division
result = number1.divide(number2, 2, RoundingMode.HALF_UP);
}
break;
}
if (validFlag) {
txtResult.setText(String.valueOf(result));
}else {
txtResult.setText(CalConstant.DIVIDE_BYZERO_INFO);
validFlag = true;
}
number.append(result);
}
}else {
txtResult.setText(CalConstant.INPUT_FIRT_SIGN);
}
}
/**
* The logic of dealing with decimal point
*/
private void point(){
if (number.length()==0){
number.append("0.");
}else if (number.toString().indexOf(".")==-1){
number.append(".");
}else {
number.append("");
}
txtResult.setText(number.toString());
}
}
【CalConstant类】
package com.sugon.calculator;
/**
* @date: 2020/12/29 11:00
* @description:Defines constant classes for calculators
*
*/
public class CalConstant {
// Define clear and backspace keys
public static final String CLEAR = "清空";
public static final String BACK = "退格";
// Define zero
public static final String ZERO = "0";
// Define addition, subtraction, multiplication and division operator
public static final String PLUS = "+";
public static final String REDUCE = "-";
public static final String MULTIPLY = "*";
public static final String DIVIDE = "/";
public static final String EQUAL = "=";
public static final String POINT = ".";
public static final String DIVIDE_BYZERO_INFO = "除数不能为零!";
public static final String INPUT_FIRT_SIGN = "请输入第一个操作数!";
public static final String FONT_STYLE = "黑体";
}
【CalculatorApplication类】
package com.sugon.calculator;
import java.awt.event.ActionListener;
/**
*
* @date: 2020/12/29 14:30
* @description:Calculator startup class
*
*/
public class CalculatorApplication {
public static void main(String[] args) {
CalculatorView view = new CalculatorView();
ActionListener listener =new StackActionListener(view.getTxtResult());
view.setListener(listener);
view.init();
}
}
github地址:https://github.com/byli5/ZZU