import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class A extends JFrame implements ActionListener,KeyListener{
/**
*
*/
static ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript"); //JDK自带的类可以实现调用JS的功能,可以实现执行字符串中的运算公式的功能
private static final long serialVersionUID = 1L;
private final String[] KEYS = {
"CE", "C", "←", "/",
"7", "8", "9", "*",
"4", "5", "6", "-",
"1", "2", "3", "+",
"+/-","0",".","=",};
private final String[] COMMAND = {"MC", "M+", "M-", "MR",
"N!", "Sin", "Cos", "Tan",
"%", "sqrt", "X^y", "1/X",};
private JButton keys[] = new JButton[KEYS.length];
private JButton commands[] = new JButton[COMMAND.length];
//private JMenuBar createMenuBar= new JMenuBar();// 创建菜单栏
private JTextField resultText = new JTextField("0");
// 计算的中间结果。
private double resultNum = 0.0;
private boolean firstDigit = true;
// 计算的中间结果。
// 当前运算的运算符
private String operator = "=";
// 操作是否合法
private boolean operateValidFlag = true;
/**
* 构造函数
* */
public A(){
super();
// 初始化计算器
init();
// 设置计算器的背景颜色
this.setBackground(Color.LIGHT_GRAY);
this.setTitle("计算器");
this.setFont(new Font("宋体",Font.BOLD,20));
// 在屏幕(800, 400)坐标处显示计算器
this.setLocation(800, 400);
// 不许修改计算器的大小
//this.setResizable(false);
// 使计算器中各组件大小合适
this.pack();
createMenuBar();// 创建菜单栏
}
private void createMenuBar() {// 创建菜单栏的方法
JMenuBar menubar = new JMenuBar();
setJMenuBar(menubar);
JMenu menu1 = new JMenu("查看");
JMenu menu2 = new JMenu("编辑");
JMenu menu3 = new JMenu("帮助");
menubar.add(menu1);
menubar.add(menu2);
menubar.add(menu3);
final String[] MENULITEM = {"标准型(T) Alt+1",
"科学型(S) Alt+2",
"程序员(P) Alt+3",
"统计信息(A) Alt+4",
"历史记录(Y) Ctrl+H",
"数字分组(I)",
"基本(B) Ctrl+F4",
"单位转换(U) Ctrl+U",
"科日期计算(D) Ctrl+E",
"工作表(W)"};
JMenuItem menu1items[] = new JMenuItem[MENULITEM.length];
JMenuItem menu2item1 = new JMenuItem("复制 Ctrl+C");
JMenuItem menu2item2 = new JMenuItem("粘贴 Ctrl+V");
JMenuItem menu2item3 = new JMenuItem("科学分组");
JMenuItem menu3item1 = new JMenuItem("帮助主题");
JMenuItem menu3item2 = new JMenuItem("关于计算器");
for(int i=0; i < MENULITEM.length; i++){
menu1items[i]= new JMenuItem(MENULITEM[i]);
menu1.add( menu1items[i]);
}
menu2.add(menu2item1);
menu2.add(menu2item2);
menu2.add(menu2item3);
menu3.add(menu3item1);
menu3.add(menu3item2);
}
private void init() {
// 文本框中的内容采用右对齐方式
resultText.setHorizontalAlignment(JTextField.RIGHT);
// 不允许修改结果文本框
resultText.setEditable(false);
// 设置文本框背景颜色为白色
resultText.setBackground(Color.WHITE);
// 初始化计算器上键的按钮,将键放在一个画板内
JPanel calckeysPanel = new JPanel();
// 用网格布局器,5行,4列的网格,网格之间的水平方向间隔为3个象素,垂直方向间隔为3个象素
calckeysPanel.setLayout(new GridLayout(5, 4, 3, 3));
for (int i = 0; i < KEYS.length; i++) {
keys[i] = new JButton(KEYS[i]);
calckeysPanel.add(keys[i]);
keys[i].setForeground(Color.black);
keys[i].setBackground(Color.WHITE);
}
// 背景浅灰色键
keys[0].setBackground(new Color(228,220,217));
keys[1].setBackground(new Color(228,220,217));
keys[2].setBackground(new Color(228,220,217));
keys[3].setBackground(new Color(228,220,217));
keys[7].setBackground(new Color(228,220,217));
keys[11].setBackground(new Color(228,220,217));
keys[15].setBackground(new Color(228,220,217));
// “CE C ←键字体颜色”
keys[0].setForeground(new Color(255,25,25));
keys[1].setForeground(new Color(255,25,25));
keys[2].setForeground(new Color(255,25,25));
// “0键字体及背景颜色”
keys[19].setBackground(new Color(238,76,12));
keys[19].setForeground(Color.white);
// 运算符键用红色标示,其他键用蓝色表示
// 初始化功能键,都用红色标示。将功能键放在一个画板内
JPanel commandsPanel = new JPanel();
// 用网格布局器,3行,4列的网格,网格之间的水平方向间隔为3个象素,垂直方向间隔为3个象素
commandsPanel.setLayout(new GridLayout(3, 4, 3, 3));
for (int i= 0; i <4; i++) {
commands[i] = new JButton(COMMAND[i]);
commandsPanel.add(commands[i]);
commands[i].setForeground(Color.white);
commands[i].setBackground(Color.black);
}
for (int i= 4; i < COMMAND.length; i++) {
commands[i] = new JButton(COMMAND[i]);
commandsPanel.add(commands[i]);
commands[i].setForeground(Color.black);
commands[i].setBackground(new Color(228,220,217));
}
// 下面进行计算器的整体布局,将calckeysPanel和command画板放在计算器的中部,
// 将文本框放在北部,将calms画板放在计算器的西部。
// 新建一个大的画板,将上面建立的command和calckeysPane画板放在该画板内
JPanel panel1 = new JPanel();
// 画板采用边界布局管理器,画板里组件之间的水平和垂直方向上间隔都为3象素
panel1.setLayout(new BorderLayout(3, 3));
panel1.add("Center", commandsPanel);
panel1.add("South", calckeysPanel);
// 建立一个画板放文本框
JPanel top = new JPanel();
top.setLayout(new BorderLayout());
top.add("Center", resultText);
// 整体布局
getContentPane().setLayout(new BorderLayout(3,5));
getContentPane().add("North", top);
getContentPane().add("Center", panel1);
if (operateValidFlag) {
// 双精度浮点数的运算
long t1;
double t2;
t1 = (long) resultNum;
t2 = resultNum - t1;
if (t2 == 0) {
resultText.setText(String.valueOf(t1));
}
else {
resultText.setText(String.valueOf(resultNum));
}
}
//设置监听器
for (int i = 0; i < KEYS.length; i++) {
keys[i].addActionListener(this);
keys[i].addKeyListener(this);
}
for (int i = 0; i < COMMAND.length; i++) {
commands[i].addActionListener(this);
}
resultText.addKeyListener(new KeyAdapter()
{ //监听resultText
public void keyPressed(KeyEvent e){
char label=e.getKeyChar();
String k=String.valueOf(label);
if(label==KeyEvent.VK_ENTER){ //如果按下回车键 则将结果展示
handleResult();
}
else{ //否则处理该算式
handleEquation(k);
}
}});
}
public void keyTyped(KeyEvent e)
{
}
public void keyPressed(KeyEvent e) { //按键监听
char label=e.getKeyChar();
String k=String.valueOf(label);
if(label==KeyEvent.VK_ENTER){
handleResult();
}
else{
handleEquation(k);
}
}
public void keyReleased(KeyEvent e) {
}
private void handleEquation(String label) {
if(resultText.getText().equals("0"))
{
resultText.setText(label);
}
else
{
resultText.setText(resultText.getText()+label);
}
}
@Override
public void actionPerformed(ActionEvent e) {
String label=e.getActionCommand(); //获取该按键内容
for(int i=0;i<KEYS.length;i++){
handleEquation(label);
if(label.equals("=")){
handleResult();
}
else if(label.equals("+/-")){
handleOppositeNumber(label);
}
}
/*switch(COMMAND.getText()){
case 'N!': handleN(label);break;
case 'Sin': handleSin(label);break;
case 'Cos': handleCos(label);break;
case 'Tan': handleTan(label);break;
case '%': handleBFH(label);break;
case 'sqrt': handlesqrt(label);break;
case 'X^y': handleZS(label);break;
case '1/X': handleDS(label);break;
case '=': handleResult();break;
case 'C': handleC();break;
case 'CE': handleCE();break;
//case '=': handleResult();break;
//case '+/-': handleOppositeNumber(label);break;
}*/
if(label.equals("N!")){
handleN(label);
}
else if(label.equals("Sin")){
handleSin(label);
}
else if(label.equals("Cos")){
handleCos(label);
}
else if(label.equals("Tan")){
handleTan(label);
}
else if(label.equals("%")){
handleBFH(label);
}
else if(label.equals("sqrt")){
handlesqrt(label);
}
else if(label.equals("X^y")){
handleZS(label);
}
else if(label.equals("1/X")){
handleDS(label);
}
else if(label.equals("C")){
handleC();
}
else if(label.equals("CE")){
handleCE();
}else if(label.equals("←")){
handleBackSpace(label);
}
/*else if(label.equals("=")){
handleResult();
}
else if(label.equals("+/-")){
handleOppositeNumber(label);
}*/
}
//N!方法
public void handleN(String command){ //将存储的数据归零
// N的阶乘运算
long resultNum=0;
if( resultNum <0){
resultText.setText("只有整数才有阶乘");
}else if( resultNum ==0) {
resultText.setText("0的阶乘等于1");
}else if( resultNum >0){
for (int i = (int) resultNum-1; i > 0; i--){
resultNum*=i;
}
}
}
//Sin方法
private void handleSin(String command){
// 正弦运算
double a = Math.toRadians(getNumberFromText());//把数字转换成 90度
resultNum =Math.sin(a);//计算Sin
}
//Cos方法
private void handleCos(String command) {
// 余弦运算
double b = Math.toRadians(getNumberFromText());//把数字转换成 90度
resultNum =Math.cos(b);//计算Cos
}
//Tan方法
public void handleTan(String command){
// 正切运算
double c = Math.toRadians(getNumberFromText());//把数字转换成 90度
resultNum =Math.tan(c);//计算Tan
}
//%方法
public void handleBFH(String command){
// 百分号运算,除以100
resultNum = getNumberFromText() / 100;
}
//sqrt方法
public void handlesqrt(String command){
// 平方根运算
resultNum = Math.sqrt(resultNum);
}
//指数方法
public void handleZS(String command){
// 指数运算
/*double a= Math.pow(resultNum,getNumberFromText());
resultNum =a;*/
resultNum = getNumberFromText() *getNumberFromText() ;
}
//倒数方法
public void handleDS(String command){
// 倒数运算
if (resultNum == 0.0) {
// 操作不合法
operateValidFlag = false;
resultText.setText("零没有倒数");
}
else {
resultNum = 1 / getNumberFromText();
}
}
//C方法
public void handleC(){
// 初始化计算器的各种值
resultText.setText("0");
firstDigit = true;
operator = "=";
}
//CE方法
public void handleCE(){
// 初始化计算器的各种值
resultText.setText("0");
}
//BackSpace方法
public void handleBackSpace(String key){
String text = resultText.getText();
int i = text.length();
if (i > 0) {
// 退格,将文本最后一个字符去掉
text = text.substring(0, i - 1);
if (text.length() == 0) {
// 如果文本没有了内容,则初始化计算器的各种值
resultText.setText("0");
firstDigit = true;
operator = "=";
} else {
// 显示新的文本
resultText.setText(text);
}
}
}
//+/-方法
public void handleOppositeNumber(String key){
/*Pattern pattern = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
String strText = resultText.getText();
Matcher isNum = pattern.matcher(strText);
if(isNum.matches()){
int a = Integer.parseInt(strText);
a=a*(-1);
strText=String.valueOf(a);
resultText.setText(strText);
}*/
// 正数负数运算
resultNum = resultNum*(-1) ;
if (operateValidFlag) {
// 双精度浮点数的运算
long t1;
double t2;
t1 = (long) resultNum;
t2 = resultNum - t1;
if (t2 == 0) {
resultText.setText(String.valueOf(t1));
}
else {
resultText.setText(String.valueOf(resultNum));
}
}
// 运算符等于用户按的按钮
operator = key;
firstDigit = true;
operateValidFlag = true;
}
//=方法
private void handleResult() {
String text=resultText.getText();
try
{
Object a=jse.eval(text);
text=String.valueOf(a);
resultText.setText(text);
}
catch (ScriptException e)
{
e.printStackTrace();
resultText.setText("算式格式不正确!");
}
/*// 赋值运算
resultNum = getNumberFromText();*/
}
//获取数值
private double getNumberFromText() {
double result = 0;
try {
result = Double.valueOf(resultText.getText()).doubleValue();
} catch (NumberFormatException e) {
}
return result;
}
public static void main(String args[]) {
A calculator1 = new A();
calculator1.setVisible(true);
calculator1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}