计算器可以完成简单的四则运算
实现效果如下:
首先是主界面:
import javax.swing.JFrame;
public class MainView {
public static void main(String[] args) {
JFrame frame=new MyCalculator();
frame.setVisible(true);
}
}
然后是实现:
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.MenuItem;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class MyCalculator extends JFrame implements ActionListener{
/**
*
*/
private static final Insets insets = new Insets(0, 0, 0, 0);
private static final long serialVersionUID = -5113379074442808199L;
JMenu editMenu,helpMenu;
JMenuItem copyMenuItem,pasteMenuItem,lookhelpMenuItem,aboutsMenuItem;
JPanel panel;
JPanel panel2;
JButton buttonMC,buttonMR,buttonMS,buttonM1,buttonM2,buttonBS,buttonCE,buttonC;
JButton buttonFC,buttongen,button7,button8,button9,buttonchu,buttonbai,button4;
JButton button5,button6,buttoncheng,buttonx,button1,button2,button3,buttonjian;
JButton button0,buttondian,buttonjia,buttondeng;
JTextArea showText;
JMenuBar menuBar;
public MyCalculator() {
initMenu();
initFrame();
}
public void initMenu(){
//设置菜单栏
menuBar=new JMenuBar();
//编辑菜单
editMenu=new JMenu("编辑(E)");
editMenu.setMnemonic('E');
//菜单里的内容
copyMenuItem=new JMenuItem("复制(C)");
copyMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,InputEvent.CTRL_MASK));
copyMenuItem.setMnemonic('C');
pasteMenuItem=new JMenuItem("粘贴(P)");
pasteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,InputEvent.CTRL_MASK));
pasteMenuItem.setMnemonic('P');
//向编辑菜单添加
editMenu.add(copyMenuItem);
editMenu.add(pasteMenuItem);
//帮助菜单
helpMenu=new JMenu("帮助(H)");
helpMenu.setMnemonic('H');
//菜单里的内容
lookhelpMenuItem=new JMenuItem("查看帮助(V)");
lookhelpMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1,0));
lookhelpMenuItem.setMnemonic('V');
aboutsMenuItem=new JMenuItem("关于计算器(A)");
aboutsMenuItem.setMnemonic('A');
//向帮助菜单添加
helpMenu.add(lookhelpMenuItem);
helpMenu.add(aboutsMenuItem);
//向菜单栏添加编辑和帮助
menuBar.add(editMenu);
menuBar.add(helpMenu);
this.setJMenuBar(menuBar);
showText =new JTextArea();
showText.setRows(2);
showText.setText("");
panel=new JPanel();
panel2=new JPanel();
panel.setLayout(new BorderLayout());
//设置上方为文本
panel.add(showText,BorderLayout.NORTH);
panel.add(panel2);
//嵌套布局
panel2.setBackground(new Color(66, 166, 166));
panel2.setLayout(new GridBagLayout());
//第一行
buttonMC=new JButton("MC");
addComponent(panel2, buttonMC, 0, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonMR=new JButton("MR");
addComponent(panel2, buttonMR, 1, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonMS=new JButton("MS");
addComponent(panel2, buttonMS, 2, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonM1=new JButton("M+");
addComponent(panel2, buttonM1, 3, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonM2=new JButton("M-");
addComponent(panel2, buttonM2, 4, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
//第二行
buttonBS=new JButton("←");
addComponent(panel2, buttonBS, 0, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonBS.addActionListener(this);
buttonCE=new JButton("CE");
addComponent(panel2, buttonCE, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonC=new JButton("C");
addComponent(panel2, buttonC, 2, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonC.addActionListener(this);
buttonFC=new JButton("+-");
addComponent(panel2, buttonFC, 3, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttongen=new JButton("√");
addComponent(panel2, buttongen, 4, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
//第三行
button7=new JButton("7");
addComponent(panel2, button7, 0, 2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
button7.addActionListener(this);
button8=new JButton("8");
addComponent(panel2, button8, 1, 2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
button8.addActionListener(this);
button9=new JButton("9");
addComponent(panel2, button9, 2, 2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
button9.addActionListener(this);
buttonchu=new JButton("/");
addComponent(panel2, buttonchu, 3, 2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonchu.addActionListener(this);
buttonbai=new JButton("%");
addComponent(panel2, buttonbai, 4, 2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonbai.addActionListener(this);
//第四行
button4=new JButton("4");
addComponent(panel2, button4, 0, 3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
button4.addActionListener(this);
button5=new JButton("5");
addComponent(panel2, button5, 1, 3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
button5.addActionListener(this);
button6=new JButton("6");
addComponent(panel2, button6, 2, 3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
button6.addActionListener(this);
buttoncheng=new JButton("*");
addComponent(panel2, buttoncheng, 3, 3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttoncheng.addActionListener(this);
buttonx=new JButton("1/x");
addComponent(panel2, buttonx, 4, 3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
//第五行
button1=new JButton("1");
addComponent(panel2, button1, 0, 4, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
button1.addActionListener(this);
button2=new JButton("2");
addComponent(panel2, button2, 1, 4, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
button2.addActionListener(this);
button3=new JButton("3");
addComponent(panel2, button3, 2, 4, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
button3.addActionListener(this);
buttonjian=new JButton("-");
addComponent(panel2, buttonjian, 3, 4, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonjian.addActionListener(this);
buttondeng=new JButton("=");
addComponent(panel2, buttondeng, 4, 4, 1, 2, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttondeng.addActionListener(this);
//第六行
button0=new JButton("0");
addComponent(panel2, button0, 0, 5, 2, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
button0.addActionListener(this);
buttondian=new JButton(".");
addComponent(panel2, buttondian, 2, 5, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonjia=new JButton("+");
addComponent(panel2, buttonjia, 3, 5, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
buttonjia.addActionListener(this);
this.add(panel);
}
public void initFrame(){
//设置关闭窗体即关闭程序
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置窗体大小位置
this.setSize(280, 320);
this.setLocation(100, 100);
//设置标题
this.setTitle("呱?呱!");
//设置图标
Toolkit kit=Toolkit.getDefaultToolkit();
Image img=kit.getImage("img/ico.jpg");
this.setIconImage(img);
this.setResizable(false);
//设置可视(置于构造函数最后)
}
private static void addComponent(Container container, Component component, int gridx, int gridy,
int gridwidth, int gridheight, int anchor, int fill) {
//建立网格包对象
GridBagConstraints gbc = new GridBagConstraints(gridx, gridy, gridwidth, gridheight, 1.0, 1.0,
anchor, fill, insets, 0, 0);
//添加到容器中
container.add(component, gbc);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource()==button0) {
int pos=showText.getCaretPosition();
showText.insert("0", pos);
}
else if (e.getSource()==button1) {
int pos=showText.getCaretPosition();
showText.insert("1", pos);
}
else if (e.getSource()==button2) {
int pos=showText.getCaretPosition();
showText.insert("2", pos);
}
else if (e.getSource()==button3) {
int pos=showText.getCaretPosition();
showText.insert("3", pos);
}
else if (e.getSource()==button4) {
int pos=showText.getCaretPosition();
showText.insert("4", pos);
}
else if (e.getSource()==button5) {
int pos=showText.getCaretPosition();
showText.insert("5", pos);
}
else if (e.getSource()==button6) {
int pos=showText.getCaretPosition();
showText.insert("6", pos);
}
else if (e.getSource()==button7) {
int pos=showText.getCaretPosition();
showText.insert("7", pos);
}
else if (e.getSource()==button8) {
int pos=showText.getCaretPosition();
showText.insert("8", pos);
}
else if (e.getSource()==button9) {
int pos=showText.getCaretPosition();
showText.insert("9", pos);
}
else if (e.getSource()==buttonjia) {
int pos=showText.getCaretPosition();
showText.insert("+", pos);
}
else if (e.getSource()==buttonjian) {
int pos=showText.getCaretPosition();
showText.insert("-", pos);
}
else if (e.getSource()==buttoncheng) {
int pos=showText.getCaretPosition();
showText.insert("*", pos);
}
else if (e.getSource()==buttonchu) {
int pos=showText.getCaretPosition();
showText.insert("/", pos);
}
else if (e.getSource()==buttonBS) {
int pos=showText.getCaretPosition();
if( !( showText.getText().equals("")) ) {
StringBuffer sb = new StringBuffer();
sb.append(showText.getText());
sb.delete(pos-1 , pos);
showText.setText(sb.toString());
}
}
else if (e.getSource()==buttondeng) {
int pos=showText.getCaretPosition();
String cmd = showText.getText();
Calculate cl = new Calculate();
String resultMsg = cl.calResult(cmd);
if ( resultMsg.equals("算式格式错误") || resultMsg.equals("除数不能为0") ) {
JOptionPane.showMessageDialog(null, resultMsg, "错误", JOptionPane.WARNING_MESSAGE);
}
else {
showText.insert("="+resultMsg, pos);
}
}
else if (e.getSource()==buttonC) {
showText.setText("");
}
}
}
最后是计算的工具类:
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JFrame;
//import sun.security.krb5.internal.ccache.CCacheInputStream;
public class Calculate {
private Stack<Double> numStack = new Stack<Double>();
private Stack<Character> sybStack = new Stack<Character>();
public String calResult ( String equation ) {
//替换乘除号
equation = equation.replace("X", "*");
equation = equation.replace("÷", "/");
//处理负号
equation = negativeNumTransfer(equation);
if ( !checkFormat(equation) ) {
return "算式格式错误";
}
equation += "#";
StringBuffer tempNum = new StringBuffer();
StringBuffer exp = new StringBuffer().append(equation);
while ( exp.length() != 0 ) {
String temp = exp.substring(0,1);
exp.delete(0, 1);
if( isNum(temp) ) { // temp是数字
tempNum.append(temp);
}
else { // temp不是数字
if (!"".equals(tempNum.toString())) {
// 当表达式的第一个符号为括号
double num = Double.parseDouble(tempNum.toString());
numStack.push(num);
tempNum.delete(0, tempNum.length());
}
// 用当前取得的运算符与栈顶运算符比较优先级:若高于,则因为会先运算,放入栈顶;若等于,因为出现在后面,
// 所以会后计算,所以栈顶元素出栈,取出操作数运算;若小于,则同理,取出栈顶元素运算,将结果入操作数栈。
// 判断当前运算符与栈顶元素优先级,取出元素,进行计算(因为优先级可能小于栈顶元素,还小于第二个元素等等,需要用循环判断)
while ( !compare(temp.charAt(0)) && (!sybStack.empty()) ) {
double a = numStack.pop();
double b = numStack.pop();
char ope = sybStack.pop();
// 进行简单的计算
if( simpleCal(ope, a, b) == false ) {
return "除数不能为0";
}
}
// 判断当前运算符与栈顶元素优先级, 如果高,或者低于平,计算完后,将当前操作符号,放入操作符栈
refreshSybStack(temp);
}
}
return getResultStr(numStack.pop());
}
private void refreshSybStack ( String temp) {
if (temp.charAt(0) != '#') {
sybStack.push(new Character(temp.charAt(0)));
if (temp.charAt(0) == ')') {// 当栈顶为'(',而当前元素为')'时,则是括号内以算完,去掉括号
sybStack.pop();
sybStack.pop();
}
}
}
private boolean simpleCal ( char ope, double a, double b ) {
double result = 0;
switch (ope) {
case '+':
result = b + a;
numStack.push(result);
break;
case '-':
result = b - a;
numStack.push(result);
break;
case '*':
result = b * a;
numStack.push(result);
break;
case '/':
if ( a == 0.0 ) {
return false;
}
else {
result = b / a;
numStack.push(result);
break;
}
}
return true;
}
private String negativeNumTransfer( String equation ) {
// 处理算式,将表示负数的部分进行改动,转成calResult方法支持的
if( equation.length() <= 1 ) {
return equation;
}
StringBuffer str = new StringBuffer().append(equation);
for ( int i = 0; i < str.length()-1; ++i ) {
if( !str.substring(i, i+1).equals("-") ) {
continue;
}
if ( i == 0 ) {
char temp = str.charAt(1);
if( isNumChar(temp) || isDecimalPoint(temp) || isLeftBracket(temp) ) {
str.insert(0, "0");
i++;
}
}
else {
char last = str.charAt(i-1);
char next = str.charAt(i+1);
if( isLeftBracket(last) &&
( isNumChar(next) || isDecimalPoint(next) || isLeftBracket(next) ) ) {
str.insert(i, "0");
i++;
}
}
}
return str.toString();
}
private boolean checkFormat ( String equation ) {
char[] c = equation.toCharArray();
int singleBracket = 0;
for( int i = 0; i < c.length; ++i ) {
if( isLeftBracket(c[i]) ) {
singleBracket++;
}
if ( isRightBracket(c[i]) ) {
singleBracket--;
}
if ( i == 0 ) { //第1个元素只能是[0-9]或者是左括号
if( !isLeftBracket(c[i]) && !isNumChar(c[i]) ) {
return false;
}
}
else if ( isNumChar(c[i]) || isDecimalPoint(c[i]) ) { //数字左边不能是右括号
if ( isRightBracket(c[i-1]) ) {
return false;
}
}
else if( isLeftBracket(c[i]) ) { // 左括号的左边不能是数字和右括号
if ( isNumChar(c[i-1]) || isDecimalPoint(c[i-1]) || isRightBracket(c[i-1]) ) {
return false;
}
}
else { // 右括号和四则运算符的左边只能是数字或者右括号
if ( !isNumChar(c[i-1]) && !isRightBracket(c[i-1]) ) {
return false;
}
}
}
return singleBracket == 0;
}
private static boolean isNum ( String temp ) {
return temp.matches("[0-9]") || temp.equals(".");
}
private static boolean isLeftBracket ( char c ) {
return c == '(';
}
private static boolean isRightBracket ( char c ) {
return c == ')';
}
private static boolean isDecimalPoint ( char c ) {
return c == '.';
}
private static boolean isNumChar ( char c ) {
return ( c >= '0' && c <= '9' );
}
private boolean compare (char str) {
if ( sybStack.empty() ) {
// 当为空时,显然 当前优先级最低,返回高
return true;
}
char last = (char) sybStack.lastElement();
// 如果栈顶为'('显然,优先级最低,')'不可能为栈顶。
if (last == '(') {
return true;
}
switch (str) {
case '#':
return false;// 结束符
case '(':
// '('优先级最高,显然返回true
return true;
case ')':
// ')'优先级最低,
return false;
case '*': {
// '*/'优先级只比'+-'高
if (last == '+' || last == '-')
return true;
else
return false;
}
case '/': {
if (last == '+' || last == '-')
return true;
else
return false;
}
// '+-'为最低,一直返回false
case '+':
return false;
case '-':
return false;
}
return true;
}
private String getResultStr ( double result ) {
StringBuffer s = new StringBuffer().append( result + "" );
if ( s.substring(s.length() - 2).equals(".0") ) {
s.delete( s.length()-2 , s.length() );
}
return s.toString();
}
}