<pre name="code" class="java">import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Calculator
{
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
CalculatorDemo.createCalculator();
}
});
}
}
class CalculatorDemo
{
public final static String OPERATOR = "+-*/";
public final static String DIGIT_NUM = "0123456789";
public final static char DOT = '.';
public final static char EQUAL = '=';
public final static char CLEAR = 'C';
JTextArea txtAreaResult;
String[] btnText = {"MC","MR","MS","M+","M-",
"←","CE","C","±","√",
"7","8","9","/","%",
"4","5","6","*","1/x",
"1","2","3","-","=",
"0",".","+"};
JButton[] btnOfCenterPane;
JPanel northPaneOfCalc;
JPanel centerPaneOfCalc;
private CalculatorListener calcListener = new CalculatorListener();
public StringBuffer firstOperand;//操作数一
public StringBuffer secondOperand;//操作数二
public StringBuffer calculteResult;//计算结果
public StringBuffer displayResult;//显示结果
public boolean isSetedFirstOperand = false;//标示第一个操作数是否设置
public char setedOperator;//运算符号
public boolean isSetedSecondOperand = false;
public boolean isSetedOperator = false;
public boolean isClickedEqual = false;
/**
* 创建和初始化控件
* */
private void createAndInitialComponents()
{
/*textfield = new JTextField("0");
textfield.setHorizontalAlignment(JTextField.RIGHT);//设置文本从右开始显示
*/
northPaneOfCalc = new JPanel();
centerPaneOfCalc = new JPanel();
txtAreaResult = new JTextArea("0",2,5);
txtAreaResult.setBorder (BorderFactory.createLineBorder(Color.gray,1));//添加边框
//textarea.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);//
btnOfCenterPane = new JButton[btnText.length];
for(int i=0;i<btnOfCenterPane.length;i++)
{
btnOfCenterPane[i] = new JButton(btnText[i]);
if(i == 24)
{
btnOfCenterPane[24].setPreferredSize(new Dimension(32,54));
}
else if(i == 25)
{
btnOfCenterPane[25].setPreferredSize(new Dimension(68,25));
}
else
{
btnOfCenterPane[i].setPreferredSize(new Dimension(32,25));
}
btnOfCenterPane[i].addActionListener(calcListener);//添加监听器
btnOfCenterPane[i].setMargin(new Insets(0,0,0,0));//设置边距
btnOfCenterPane[i].setFont(new Font("TimesRoman",Font.PLAIN,12));
}
}
/**
* 私有构造方法,实现计算器的构造
*/
private CalculatorDemo()
{
createAndShowGUI();
}
/**
* 计算器创建方法
* @return 返回Calculator类对象
*/
public static CalculatorDemo createCalculator()
{
return new CalculatorDemo();
}
/**
* 显示GUI窗口
*/
private void createAndShowGUI()
{
JFrame frame = new JFrame("计算器");
Image iconImage = Toolkit.getDefaultToolkit().getImage("calc.jpg");
frame.setIconImage(iconImage);
JMenuBar menubar = new JMenuBar();
JMenu[] menu;
String[] menuStr = {"查看(V)","编辑(E)","帮助(H)"};
menu = new JMenu[menuStr.length];
for(int i=0;i<menuStr.length;i++)
{
menu[i] = new JMenu(menuStr[i]);
menubar.add(menu[i]);
}
menu[0].setMnemonic('V');
menu[1].setMnemonic('E');
menu[2].setMnemonic('H');
String[] Str = {"复制(C)","粘贴(P)","历史记录(H)","复制历史记录(I)","编辑(E)","取消编辑(N)","清除(L)"};
JMenuItem[] menuItem = new JMenuItem[Str.length - 1];
menuItem[0] = new JMenuItem(Str[0]);
menuItem[0].setMnemonic('C');
menuItem[0].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,InputEvent.CTRL_MASK));
menu[1].add(menuItem[0]);
menuItem[1] = new JMenuItem(Str[1]);
//menuItem[1].setAccelerator(KeyStroke.getKeyStroke('P'));
menu[1].add(menuItem[1]);
JMenu historyMenu = new JMenu(Str[2]);
menu[1].add(historyMenu);
menuItem[2] = new JMenuItem(Str[3]);
menuItem[3] = new JMenuItem(Str[4]);
menuItem[4] = new JMenuItem(Str[5]);
menuItem[5] = new JMenuItem(Str[6]);
//只有JMenu下面才可以添加JMenuItem
historyMenu.add(menuItem[2]);
historyMenu.add(menuItem[3]);
historyMenu.add(menuItem[4]);
historyMenu.add(menuItem[5]);
frame.setJMenuBar(menubar);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
createAndInitialComponents();
addComponentsToPane(centerPaneOfCalc,northPaneOfCalc);
frame.add(centerPaneOfCalc,BorderLayout.CENTER);
frame.add(northPaneOfCalc,BorderLayout.NORTH);
//Display the Window.
frame.pack();
//frame.setSize(new Dimension(225,325));
frame.setVisible(true);
}
/**
* 将所有控件添加到容器中
*/
private void addComponentsToPane(JPanel centerPane,JPanel northPane)
{
northPane.setLayout(new GridBagLayout());
//pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6),BorderFactory.createEtchedBorder()));
// pane2.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6),BorderFactory.createEtchedBorder()));
northPane.add(txtAreaResult,new GridBagConstraints(0, 0, 1, 2, 1.0, 1.0,GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(12, 8, 2, 8), 0, 0));
txtAreaResult.setFont(new Font("TimesRoman",Font.BOLD,18));
northPane.setPreferredSize(new Dimension(32*5,68));
centerPane.setLayout(new GridBagLayout());
centerPane.add(btnOfCenterPane[0],new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(3, 8, 3, 3), 0, 0));
centerPane.add(btnOfCenterPane[1],new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(3, 3, 3, 3), 0, 0));
centerPane.add(btnOfCenterPane[2],new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(3, 3, 3, 3), 0, 0));
centerPane.add(btnOfCenterPane[3],new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(3, 3, 3, 3), 0, 0));
centerPane.add(btnOfCenterPane[4],new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(3, 3, 3, 8), 0, 0));
centerPane.add(btnOfCenterPane[5],new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 8, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[6],new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[7],new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[8],new GridBagConstraints(3, 1, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[9],new GridBagConstraints(4, 1, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 8), 0, 0));
centerPane.add(btnOfCenterPane[10],new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 8, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[11],new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[12],new GridBagConstraints(2, 2, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[13],new GridBagConstraints(3, 2, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[14],new GridBagConstraints(4, 2, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 8), 0, 0));
centerPane.add(btnOfCenterPane[15],new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 8, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[16],new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[17],new GridBagConstraints(2, 3, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[18],new GridBagConstraints(3, 3, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[19],new GridBagConstraints(4, 3, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 8), 0, 0));
centerPane.add(btnOfCenterPane[20],new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 8, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[21],new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[22],new GridBagConstraints(2, 4, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[23],new GridBagConstraints(3, 4, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
centerPane.add(btnOfCenterPane[24],new GridBagConstraints(4, 4, 1, 2, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 12, 8), 0, 0));
centerPane.add(btnOfCenterPane[25],new GridBagConstraints(0, 5, 2, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 8, 12, 2), 0, 0));
centerPane.add(btnOfCenterPane[26],new GridBagConstraints(2, 5, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 12, 2), 0, 0));
centerPane.add(btnOfCenterPane[27],new GridBagConstraints(3, 5, 1, 1, 0.0, 0.0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 12, 0), 0, 0));
}
/**
* 显示操作结果到界面上
*/
private void showOperatorResultToGUI()
{
if(isClickedEqual)
{
displayResult = calculteResult;
if(displayResult.length()>18)
{
txtAreaResult.setFont(new Font("TimesRoman",Font.BOLD,16));
}
else
{
txtAreaResult.setFont(new Font("TimesRoman",Font.BOLD,20));
}
}
else if(isSetedSecondOperand)
{
displayResult = new StringBuffer(firstOperand+String.valueOf(setedOperator)+"\n"+secondOperand);
}
else if(isSetedOperator)
{
displayResult = new StringBuffer(firstOperand+String.valueOf(setedOperator));
}
else if(isSetedFirstOperand)
{
displayResult = new StringBuffer(firstOperand);
}
else
{
displayResult = new StringBuffer("0");
}
txtAreaResult.setText(displayResult.toString());
}
/**
* 去除小数点后无效的0
* 遗留问题:为什么使用void checkDecimalDot(StringBuffer str)不行
*/
private StringBuffer checkDecimalDot(StringBuffer str)
{
int index = str.indexOf(String.valueOf(DOT));
if(-1 != index){
//检查是否存在1.0100,后面无效0的情况
char[] tempCharArray = (str.toString()).toCharArray();
int getCount = tempCharArray.length - 1;//去掉'\0'
System.out.println("checkDecimalDot(): before deal:"+getCount);
label1:
for(int i=tempCharArray.length-1;i>0;i--){
if(tempCharArray[i] == '0'){
continue;
}
else{
if(tempCharArray[i] == '.'){
getCount = i;//1
}
else if(i == (tempCharArray.length-1) ){
//表示最后一个字符就是非0,那么此种情况下就直接不用处理了
return str;
}
else{
getCount = i + 1;//2
}
System.out.println("checkDecimalDot(): getCount="+getCount);
break label1;
}
}
//reset str
if(getCount != str.length()){
//注意此方法中getCount参数的含义,然后才知道如何设置上面的1,2处值了。
String tempStr = String.valueOf(tempCharArray,0,getCount);
str = new StringBuffer(tempStr);
System.out.println("checkDecimalDot():"+tempStr);
}
System.out.println("checkDecimalDot():"+str);
}
return str;
}
/**
* 监视器接口实现
*/
private class CalculatorListener implements ActionListener
{
@Override
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
if(source instanceof JButton){
String btnText = ((JButton)source).getText();
actionForButtonClicked(btnText);
}
//显示操作结果到GUI窗口
showOperatorResultToGUI();
}
/**
* JButton控件时的监测器处理
*/
private void actionForButtonClicked(String btnText)
{
if( -1 != DIGIT_NUM.indexOf(btnText))
{
//is digit number
verifyDigitNum(btnText);
}
else if(-1 != OPERATOR.indexOf(btnText))
{
//is operator
verifyOperator(btnText);
}
else
{
char[] tempCharArray = btnText.toCharArray();
switch(tempCharArray[0])
{
case DOT:
{
//is a '.'
verifyDot();break;
}
case EQUAL:
{
// is a '='
verifyEqual();break;
}
case CLEAR:
{
//is a 'C'
verifyClear();break;
}
default:
{
System.out.println("Unknown character! " + btnText);
}
}
}
}
/**
* 验证等于号'='
*/
private void verifyEqual()
{
if(isSetedFirstOperand && isSetedOperator && isSetedSecondOperand)
{
if(!isClickedEqual)
{
executeCalculate();
isClickedEqual = true;
}
else
{
//如果各个标志都是true的话,执行下面的操作,用上次计算的结果覆盖”操作数一“的值,然后在进行等号处理
firstOperand = new StringBuffer(calculteResult);
executeCalculate();
}
}
}
/**
* 执行计算
* */
private void executeCalculate()
{
double operator1 = Double.parseDouble(firstOperand.toString());
double operator2 = Double.parseDouble(secondOperand.toString());
System.out.println("verifyEqual(): operator1," + operator1);
System.out.println("verifyEqual(): operator2," + operator2);
switch(setedOperator)
{
case '+':
{
calculteResult = new StringBuffer(String.valueOf(operator1 + operator2));
break;
}
case '-':
{
calculteResult = new StringBuffer(String.valueOf(operator1 - operator2));
break;
}
case '*':
{
calculteResult = new StringBuffer(String.valueOf(operator1 * operator2));
break;
}
case '/':
{
if(operator2 == 0)
{
calculteResult = new StringBuffer("除数不能为零");
break;
}
calculteResult = new StringBuffer(String.valueOf(operator1 / operator2));
break;
}
default:
{
System.out.println("Unknown operator!");
}
}
//去除小数点后无效的0
calculteResult = checkDecimalDot(calculteResult);
System.out.println("verifyEqual():"+calculteResult);
}
/**
* 验证清除键'C'
*/
private void verifyClear()
{
firstOperand = null;//操作数一
secondOperand = null;//操作数二
setedOperator = ' ';//运算符号
calculteResult = null;//计算结果
isSetedFirstOperand = false;
isSetedSecondOperand = false;
isSetedOperator = false;
isClickedEqual = false;
txtAreaResult.setText("0");
txtAreaResult.setFont(new Font("TimesRoman",Font.BOLD,18));
}
/**
* 验证小数点'.'
*/
private void verifyDot()
{
if(!isSetedFirstOperand)
{
//"操作数一标志"为false,表示"操作数一"未设置过
//此时输入一个‘.’,则认为是输入:"0."
firstOperand = new StringBuffer("0.");
isSetedFirstOperand = true;
}
else if(!isSetedOperator)
{
//"运算符号标志"为false,表示当前还处于“操作数一”的设置过程中
//需要检查是否已经存在小数点,如果有的话,则忽略本次输入
if(-1 == ( firstOperand.toString() ).indexOf(DOT))
{
firstOperand.append(DOT);
}
}
else if(!isSetedSecondOperand)
{
//"操作数二标志"为false,表示"操作数二"未设置过
secondOperand = new StringBuffer("0.");
isSetedSecondOperand = true;
}
else
{
//"运算符号标志"为true,secondOperandFlag为true表示当前还处于“操作数二”的设置过程中
//需要检查是否已经存在小数点,如果有的话,则忽略本次输入
if(-1 == ( secondOperand.toString() ).indexOf(DOT))
{
secondOperand.append(DOT);
}
}
}
/**
* 验证运算符
*/
private void verifyOperator(String btnText)
{
//【特殊处理】如果在点击运算符时候,没有设置操作数一,那么就默认操作数一为零
if(!isSetedFirstOperand)
{
isSetedFirstOperand = true;
firstOperand = new StringBuffer("0");
}
//此处不能写为else if,否则在firstOperandFlag为false时,下面的语句执行不了。
if(!isSetedOperator)
{
//检查“操作数一”,当操作数为小数的时候,去除小数点尾部多余的0
//如:0.100,需要显示成0.1,0.000显示成0
//is decimal
firstOperand = checkDecimalDot(firstOperand);
System.out.println("verifyOperator(): firstOperand:"+firstOperand);
setedOperator = btnText.charAt(0);
isSetedOperator = true;
}
else if(!isSetedSecondOperand)
{
//覆盖之前的运算符
setedOperator = btnText.charAt(0);
}
else if(!isClickedEqual)
{
//不点击'='就直接接着输入运算符号时候的操作
//step1:计算前面的运算结果
verifyEqual();//复用该方法时候,该方法会设置clickEqualFlag标志为true需要重新设为false.
isClickedEqual = false;
//step2:用第一步得到的计算结果覆盖"操作数一"的值
firstOperand = new StringBuffer(calculteResult);
//step3:用当前输入的运算符覆盖之前的运算符
setedOperator = btnText.charAt(0);
//step4:设置操作数二标志为false
isSetedSecondOperand = false;
}
else
{
firstOperand = new StringBuffer(calculteResult);
setedOperator = btnText.charAt(0);
isSetedSecondOperand = false;
isClickedEqual = false;
}
}
/**
* 验证数字
*/
private void verifyDigitNum(String btnText)
{
if(!isSetedFirstOperand)
{
//"操作数一标志"为false,表示"操作数一"未设置过
firstOperand = new StringBuffer(btnText);
isSetedFirstOperand = true;
}
else if(!isSetedOperator)
{
//"运算符号标志"为false,表示当前还处于“操作数一”的设置过程中
//检查输入数字0后的特殊处理 比如:不允许出现02,0.20
if( 0 == (firstOperand.toString().compareTo("0")))
{
if(btnText.charAt(0) == '0')
{
return ;//skip
}
else
{
firstOperand.setCharAt(0,btnText.charAt(0));
}
}
else
{
firstOperand.append(btnText);
}
}
else if(!isSetedSecondOperand)
{
//"操作数二标志"为false,表示"操作数二"未设置过
secondOperand = new StringBuffer(btnText);
isSetedSecondOperand = true;
}
else if(!isClickedEqual)
{
//"运算符号标志"为true,表示当前处于“操作数二”的设置过程中
secondOperand.append(btnText);
}
else
{
verifyClear();//调用Clear验证函数
//重新开始各项设置
firstOperand = new StringBuffer(btnText);
isSetedFirstOperand = true;
}
}
}
}
【Java】简单计算器实现
最新推荐文章于 2022-12-02 09:55:32 发布