import java.awt.*;
import java.awt.event.*;
import java.awt.GridBagConstraints.*;
import javax.swing.*;
import java.util.regex.*;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Stack;
public class Calculator extends JFrame implements ActionListener
{
static JDialog dig=new JDialog();
static JDialog dig1=new JDialog();
static Calculator f=new Calculator();
static JTextField t=new JTextField();
static JButton[] b=new JButton[10];
static JButton bt1,bt2,bt3,bt4,bt5,bt6,bt7,bt8,bt9,bt10,bt11,bt12;
private Stack<BigDecimal> numbers =new Stack<BigDecimal>();
private Stack<Character> chs=new Stack<Character>();
public static void main(String[] args)
{
JTextArea jta,jta1;
JPanel p1,p2;
JMenuBar m;
JMenu me1,me2;
f.setTitle("计算器");
f.setSize(350, 350);
f.setLocation(200,140);
f.setLayout(new GridBagLayout()); //设置为网格包布局
GridBagConstraints gbc =new GridBagConstraints(); //创建网格包约束条件
gbc.fill = GridBagConstraints.BOTH; //设置组件具有的填充模式为both
gbc.anchor=GridBagConstraints.CENTER; //设置当组件小于显示区域时,居中显示;
Container conta=f.getContentPane(); //初始化容器获取窗口f的内容窗格
Container conta1=dig.getContentPane(); //初始化容器
dig.setTitle("关于计算器");
dig.setBounds(200, 200, 350, 150);
jta =new JTextArea();
jta.setBounds(0, 0, 350, 150);
dig.add(jta);
jta.setLineWrap(true);
jta.setEditable(false);
jta.setFont(new Font("宋体",Font.BOLD+Font.ITALIC,20));
jta.setText("此计算器可用于一些简单的计算,比如加减乘除,求倒数,开方等等");
jta.setForeground(Color.red);
dig1.setTitle("提示");
dig1.setBounds(200, 200, 200, 150);
jta =new JTextArea();
jta.setBounds(0, 0, 200, 150);
dig1.add(jta);
jta.setLineWrap(true);
jta.setEditable(false);
jta.setFont(new Font("宋体",Font.BOLD+Font.ITALIC,20));
jta.setText("开方数不能为负数");
jta.setForeground(Color.red);
m=new JMenuBar(); //创建一个菜单栏
me1=new JMenu("文件");
me2=new JMenu("帮助");
m.add(me1);
m.add(me2);
me1.add(new JMenuItem("打开"));
me1.addSeparator();
me1.add(new JMenuItem("保存"));
me1.addSeparator(); //加入分隔线;
JMenuItem exitItem=new JMenuItem("退出");
exitItem.addActionListener(f);
me1.add(exitItem);
JMenuItem about=new JMenuItem("关于计算器");
about.addActionListener(f);
me2.add(about);
for(int i=0;i<b.length;i++)
{
b[i]=new JButton(""+i);
b[i].setFont(new Font("",Font.BOLD,16));
b[i].addActionListener(f);
}
bt1=new JButton("Back");
bt2=new JButton("C");
bt3=new JButton("/");
bt4=new JButton("*");
bt5=new JButton("+");
bt6=new JButton("-");
bt7=new JButton("=");
bt8=new JButton(".");
bt9=new JButton("sqrt");
bt10=new JButton("%");
bt11=new JButton("1/x");
bt12=new JButton("+/-");
JButton b1[]={bt1,bt2,bt3,bt4,bt5,bt6,bt7,bt8,bt9,bt10,bt11,bt12};
for(int i=0;i<12;i++)
{
b1[i].setFont(new Font("",Font.BOLD,16));
b1[i].addActionListener(f);
}
p1 = new JPanel();
p1.setLayout(new GridLayout(1,2));
p1.add(bt1);
p1.add(bt2);
p2 = new JPanel();
p2.setLayout(new GridLayout(5,4));
p2.add(b[7]);
p2.add(b[8]);
p2.add(b[9]);
p2.add(bt3);
p2.add(b[4]);
p2.add(b[5]);
p2.add(b[6]);
p2.add(bt4);
p2.add(b[1]);
p2.add(b[2]);
p2.add(b[3]);
p2.add(bt5);
p2.add(b[0]);
p2.add(bt12);
p2.add(bt8);
p2.add(bt6);
p2.add(bt11);
p2.add(bt10);
p2.add(bt9);
p2.add(bt7);
f.addCom(m, conta, gbc, 0, 0, 1, 1, 1, 1);
f.addCom(t, conta, gbc, 1, 0, 1, 0, 1, 1);
f.addCom(p1, conta, gbc, 2, 0, 1, 0, 1, 1);
f.addCom(p2, conta, gbc, 3, 0, 5, 4, 1, 5);
t.setHorizontalAlignment(JTextField.LEFT);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
private void addCom(Component c,Container con,GridBagConstraints gbc,int row,int col,int nuRow
,int nuCol,int weightx,int weighty) //自定义方法
{
gbc.gridx=col;
gbc.gridy=row;
gbc.gridwidth=nuCol;
gbc.gridheight=nuRow;
gbc.weightx=weightx;
gbc.weighty=weighty;
con.add(c,gbc);
}
private boolean compare(char str)
{
if(chs.empty())
{//栈为空时优先级最低返回高
return true;
}
char last=(char)chs.lastElement();
switch(str)
{
case'*':
{
if(last=='+' || last=='-')
return true;
else
return false;
}
case'/':
{
if(last=='+'||last=='-')
return true;
else
return false;
}
case'%':
{
if(last=='+'||last=='-')
return true;
else
return false;
}
case'+':
return false;
case'-':
return false;
}
return true;
}
public BigDecimal calculate(String str)
{
StringBuffer sb = new StringBuffer(str);
StringBuffer num = new StringBuffer();
String tem=null;
char next;
//private boolean isNum(String num)
//{
// return num.matches("[0-9]");
//}
while(sb.length()>0)
{
tem = sb.substring(0, 1); //取第一位字符
sb.delete(0, 1); //去掉一位
if(isNum(tem)==true||tem.matches("\\.")==true)
{
num.append(tem); //如果是数字就将其放入num当中
}
else //取得字符不是数据是,则认为num放置的是一个完整的数字,
{ //比如123+2,123就被认为是一个完整的数
if(num.length()>0 && !"".equals(num.toString()))
{
BigDecimal bd=new BigDecimal(num.toString());//将num转换成BigDeciamal类型的数据
numbers.push(bd); //将其放入栈中
num.delete(0, num.length()); //将num清空,等待放入新值
}
if(!chs.isEmpty())
{
while(compare(tem.charAt(0))==false)
{//当当前的运算符优先级等于或小于栈顶运算符时,将栈中运算符从栈顶依次弹出进行运算
calculate();
}
}
if(numbers.isEmpty()) //数字栈为空时,运算式的第一个数字为负数
{
num.append(tem);
}
else
{
chs.push(new Character(tem.charAt(0))); //如果不为空,将其压入栈内
}
next = sb.charAt(0);
if(next =='-') //判断开头字符是否为'-',如果是,则认为该数字是负数,类似1*-2
{
num.append(next);
sb.delete(0,1); //同时去掉一位
}
}
}
//由于前面将数字放入栈内,是通过获取服饰处理的,导致最后一个数字没有放入栈中,因此将最后一个数字放入栈中
BigDecimal bd=new BigDecimal(num.toString());
numbers.push(bd);
//此时栈上面最多只有2个符号,根据优先级符号进行运算
while(!chs.isEmpty())
{
calculate();
}
return numbers.pop();
}
private void calculate() //计算方法
{
BigDecimal b=numbers.pop();//弹出栈顶的数
BigDecimal a= null;
a = numbers.pop(); //弹出栈顶第二个数
char ope = chs.pop(); //弹出栈顶符号
BigDecimal result = null; //运算结果
switch(ope)
{
case'+':
result = a.add(b);
numbers.push(result); //将结果放入操作数栈内
break;
case'-':
result = a.subtract(b);
numbers.push(result);
break;
case'*':
result = a.multiply(b);
numbers.push(result);
break;
case'/':
result = a.divide(b,3,RoundingMode.HALF_UP);
numbers.push(result);
break;
case'%':
result = a.remainder(b);
numbers.push(result);
break;
}
}
private boolean isNum(String num) //判断是否为数字
{
return num.matches("[0-9]");
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand()=="退出")
System.exit(0);
if(e.getActionCommand()=="关于计算器")
dig.setVisible(true);
if(e.getSource()==bt2) //清空C的设置
{
t.setText("");
}
if(e.getSource()==bt1) //back设置
{
StringBuilder strb=new StringBuilder(t.getText());
if(t.getText().length()!=0)
{
t.setText(strb.delete(strb.length()-1, strb.length()).toString());
}
}
for(int i=0;i<b.length;i++) //1到9按键
{
if(e.getSource()==b[i])
{ String str=t.getText();
str +=(""+i);
t.setText(str);
}
}
JButton[] b2={bt3,bt4,bt5,bt6,bt8,bt10}; //加,减,乘,除,小数点,百分号
for(int i=0;i<b2.length;i++)
{
if(e.getSource()==b2[i])
{
String str=t.getText();
str=str+b2[i].getActionCommand();
t.setText(str);
}
}
if(e.getSource()==bt12) //负号
{
String str=t.getText();
t.setText(str+"-");
}
if(e.getSource()==bt7) //等于号
{
String str=t.getText();
String str1=calculate(str)+"";
t.setText(str1);
}
if(e.getSource()==bt9) //开方
{
String str=t.getText();
if(str.charAt(0)=='-')
{
dig1.setVisible(true);
}
else
{
double db=Math.sqrt(calculate(str).doubleValue());
t.setText(db+"");
}
}
if(e.getSource()==bt11) //求倒数
{
String str = t.getText();
double a=calculate(str).doubleValue();
double b=1/a;
t.setText(b+"");
}
}
}