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); } }