Java計算器


 

主函數:

import javax.swing.JFrame;

public class Main {
    public static void main(String[] args) {
        CalFrame f = new CalFrame();
        f.pack();
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

四則運算:

package cal;

import java.math.BigDecimal;

/**
 * 四則運算
 * @author lcp
 */

public class Math_lcp {

    private static BigDecimal BigDecimal(double num1) {
        // TODO Auto-generated method stub
        return new BigDecimal( num1 );
    }

    //加法
    public static double add(double num1, double num2 ) {
        BigDecimal first = BigDecimal( num1 );
        BigDecimal second = BigDecimal( num2 );
        return first.add(second).doubleValue();
    }
    
    //減法
    public static double subtract(double num1, double num2 ) {
        BigDecimal first = BigDecimal( num1 );
        BigDecimal second = BigDecimal( num2 );
        return first.subtract(second).doubleValue();
    }
    
    //乘法
    public static double multiply(double num1, double num2 ) {
        BigDecimal first = BigDecimal( num1 );
        BigDecimal second = BigDecimal( num2 );
        return first.multiply(second).doubleValue();
    }
    
    //除法
    public static double divide(double num1, double num2 ) {
        BigDecimal first = BigDecimal( num1 );
        BigDecimal second = BigDecimal( num2 );
        return first.divide(second, 20, BigDecimal.ROUND_HALF_UP).doubleValue();//四舍五入
    }
}

界面布局:

package cal;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class CalFrame extends JFrame {
    
    private JTextField textField = null;                        // 顯示計算結果的textField
    
    private String[] rOp = { "Back", "CE", "C" };                // 用一個數組保存結果操作符
                                                                // 用一個數組保存數字與其它操作符
    private String[] nOp = { "7", "8", "9", "/", "sqrt", "4", "5", "6", "*",
            "%", "1", "2", "3", "-", "1/x", "0", "+/-", ".", "+", "=" };
    
    private CalService service = new CalService();                // 業務邏輯類
    
    private ActionListener actionListener = null;                // 定義監聽器
    
    private final int PRE_WIDTH = 360;                            // 設置panel的寬
    
    private final int PRE_HEIGHT = 250;                            // 設置panel的高

    
    
    public CalFrame() {                                            // 默認構造器
        super();
        init();
    }

    
    private void init() {                                                // 初始化界面
        
        this.setTitle("我的第一個計算器");                                    // 設置窗口的標題        
        this.setResizable(false);                                        // 設置為不可改變大小
        
        JPanel panel = new JPanel();                                    // 增加計算輸入框
        panel.setLayout(new BorderLayout(10, 1));
        panel.add(getTextField(), BorderLayout.NORTH);
        panel.setPreferredSize(new Dimension(PRE_WIDTH, PRE_HEIGHT));        
        
        JButton[] rButton = getRButton();                                // 增加結果操作鍵
        JPanel panel2 = new JPanel();
        panel2.setLayout(new BorderLayout(1, 5));        
        
        JPanel panel21 = new JPanel();                                    // 新建一個panel,用於放置按鈕        
        panel21.setLayout(new GridLayout(1, 3, 3, 3));                    // 設置布局管理器        
        for (JButton b : rButton) {                                        // 迭代增加按鈕
            panel21.add(b);
        }        
        
        JButton[] nButton = getNButton();                                // 增加數字與其它運算符        
        JPanel panel22 = new JPanel();                                    // 新建一個panel,用於放置按鈕        
        panel22.setLayout(new GridLayout(4, 5, 3, 5));                    // 設置布局管理器        
        for (JButton b : nButton) {                                        // 迭代增加按鈕
            panel22.add(b);
        }
        
        panel2.add(panel21, BorderLayout.NORTH);                        // 把新增加的面板加到frame
        panel2.add(panel22, BorderLayout.CENTER);
        panel.add(panel2, BorderLayout.CENTER);
        this.add(panel);
    }

    public ActionListener getActionListener() {                            // 這個方法用來獲取監聽器
        if (actionListener == null) {
            actionListener = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    String cmd = e.getActionCommand();
                    String result = null;
                    try {                                                // 計算操作結果                        
                        result = service.callMethod(cmd, textField.getText());
                    } catch (Exception e1) {
                        System.out.println(e1.getMessage());
                    }                    
                    if (result != null) {                                // 設置計算結果
                        textField.setText(result);
                    }
                }
            };
        }
        return actionListener;
    }
    

    
    private JTextField getTextField() {                        // 這個方法初始化輸入框
        
        if (textField == null) {            
            textField = new JTextField("0");                // 設置默認值為0            
            textField.setEditable(false);                    // 設置為不可編輯            
            textField.setBackground(Color.white);            // 設置背景為白色
        }
        return textField;
    }

    private JButton[] getRButton() {                        // 此方法獲得計算器的結果操作鍵
        JButton[] result = new JButton[rOp.length];
        for (int i = 0; i < this.rOp.length; i++) {            
            JButton b = new JButton(this.rOp[i]);            // 新建按鈕            
            b.addActionListener(getActionListener());        // 為按鈕增加事件            
            b.setForeground(Color.red);                        // 設置按鈕顏色
            result[i] = b;
        }
        return result;
    }
    
    private JButton[] getNButton() {                        // 此方法獲得計算器的其它操作鍵        
        String[] redButton = { "/", "*", "-", "+", "=" };    // 這個數組保存需要設置為紅色的操作符
        JButton[] result = new JButton[nOp.length];
        for (int i = 0; i < this.nOp.length; i++) {
            
            JButton b = new JButton(this.nOp[i]);            // 新建按扭            
            b.addActionListener(getActionListener());        // 為按鈕增加事件            
            Arrays.sort(redButton);                            // 對redButton排序,才可以使用binarySearch方法
                                                            // 如果操作符在redButton出現
            if (Arrays.binarySearch(redButton, nOp[i]) >= 0) {
                b.setForeground(Color.red);
            } else {
                b.setForeground(Color.blue);
            }
            result[i] = b;
        }
        return result;
    }
}

業務邏輯:

package cal;

public class CalService {
        
        private double store = 0;                    // 存儲器,默認為0,用於保存需要暫時保存的計算結果        
        private String firstNum = null;                // 第一個操作數        
        private String lastOp = null;                // 去保存計算符號或者其它操作        
        private String secondNum = null;            // 第二個操作數        
        private boolean isSecondNum = false;        // 是否第二個操作數,如果是,點擊數字鍵時,則在文本框中重新輸入        
        private String numString = "0123456789.";    // 數字        
        private String opString = "+-*/";            // 四則運算
        
        public String callMethod(String cmd, String text) throws Exception {    //調用方法並返回計算結果
            if (cmd.equals("C")) {
                return clearAll();
            } else if (cmd.equals("CE")) {
                return clear(text);
            } else if (cmd.equals("Back")) {
                return backSpace(text);
            } else if (numString.indexOf(cmd) != -1) {
                return catNum(cmd, text);
            } else if (opString.indexOf(cmd) != -1) {
                return setOp(cmd, text);
            } else if (cmd.equals("=")) {
                return cal(text, false);
            } else if (cmd.equals("+/-")) {
                return setNegative(text);
            } else if (cmd.equals("1/x")) {
                return setReciprocal(text);
            } else if (cmd.equals("sqrt")) {
                return sqrt(text);
            } else {
                return cal(text, true);
            } 
        }
        /*如果secondNum為空,secondNum就等於最后輸入的數字,如果不為空,則等於原來的值,如果有“%”號操作,則secondNum再等於兩數相乘除以100的結果;
         * 然后根據lastOp的值(+、-、*、/)去調用MyMath類中的add、subtract、multiply、divide方法,
         * 並把返回的結果保存到firstNum;最后把secondNum設置為空,把firstNum當做結果返回。
         * */
        public String cal(String text, boolean isPercent) throws Exception {        //四則運算isPercent,這是計算器的“%”號操作,如果有這種操作,第二個操作數就等於兩數相乘再除以100
                                                                                    // 初始化第二個操作數
            double secondResult = secondNum == null ? Double.valueOf(text)
                    .doubleValue() : Double.valueOf(secondNum).doubleValue();
                                                                                    
            if (secondResult == 0 && this.lastOp.equals("/")) {                        // 如果除數為0,不處理
                return "0";
            }
                                                                                    // 如果有"%"操作,則第二個操作數等於兩數相乘再除以100
            if (isPercent) {
                secondResult = Math_lcp.multiply(Double.valueOf(firstNum), Math_lcp
                        .divide(secondResult, 100));
            }
                        
            if (this.lastOp.equals("+")) {                                            // 四則運算,返回結果賦給第一個操作數
                firstNum = String.valueOf(Math_lcp.add(Double.valueOf(firstNum),
                        secondResult));
            } else if (this.lastOp.equals("-")) {
                firstNum = String.valueOf(Math_lcp.subtract(Double.valueOf(firstNum),
                        secondResult));
            } else if (this.lastOp.equals("*")) {
                firstNum = String.valueOf(Math_lcp.multiply(Double.valueOf(firstNum),
                        secondResult));
            } else if (this.lastOp.equals("/")) {
                firstNum = String.valueOf(Math_lcp.divide(Double.valueOf(firstNum),
                        secondResult));
            }
            
            secondNum = secondNum == null ? text : secondNum;                // 給第二個操作數重新賦值                                                                            
            this.isSecondNum = true;                                        // 把isSecondNum標志為true
            return firstNum;
        }
                                                                                    
        public String setReciprocal(String text) {                            // 計算倒數
                                                                            
            if (text.equals("0")) {                                            // 如果text為0,則不求倒數
                return text;
            } else {                                                                            
                this.isSecondNum = true;                                        // 將isSecondNum標志為true                                                                            
                return String.valueOf(Math_lcp.divide(1, Double.valueOf(text)));// 計算結果並返回
            }
        }                                                                            
         
        public String sqrt(String text) {                                    // 計算開方
                                                                            
            this.isSecondNum = true;                                        // 將isSecondNum標志為true                                                                            
            return String.valueOf(Math.sqrt(Double.valueOf(text)));            // 計算結果並返回
        }

        public String setOp(String cmd, String text) {                        //設置操作符號
                                                                            
            this.lastOp = cmd;                                                // 將此操作符號設置為上次的操作            
            this.firstNum = text;                                            // 設置第一個操作數的值    代表下次輸入數字時,要清空輸入框並重新輸入。        
            this.secondNum = null;                                            // 將第二個操作數賦值為空            
            this.isSecondNum = true;                                        // 將isSecondNum標志為true            
            return null;                                                    // 返回空值
        }
        
        public String setNegative(String text) {                            // 設置正負數
                                                    
            if (text.indexOf("-") == 0) {                                    // 如果text是負數,就將它變為正數
                return text.substring(1, text.length());
            }                                                                            
            return text.equals("0") ? text : "-" + text;                    // 否則,將正數變成負數
        }
        
        /*首先判斷是第一個操作數還是第二個,如果是第一個,就把用戶新輸入的數字追加到原來數字的后面,並做為結果返回;
         * 如果是第二個,直接返回結果,並把isSecondNum標志為false,用戶繼續輸入數字的時候,就把數字追加到原來數字的后面做為結果返回
         */
        public String catNum(String cmd, String text) {                        // 連接輸入的數字,每次點擊數字 把新加的數字追加到后面
            String result = cmd;
            
            if (!text.equals("0")) {                                        // 如果目前的text不等於0
                if (isSecondNum) {                                                                            
                    isSecondNum = false;                                    // 將isSecondNum標志為false
                } else {                                                                            
                    result = text + cmd;                                    // 剛返回結果為目前的text加上新點擊的數字
                }
            }
            if (result.indexOf(".") == 0) {                                    // 如果有.開頭,剛在前面補0
                result = "0" + result;
            }
            return result;
        }

        /*將用戶輸入的數字進行截取,如果接收到的字符串是“0”或者為null,則不作任何操作,
         * 直接返回,否則,我們將使用String的substring方法進行處理,將輸入字符串的最后一位截取
         * */
        public String backSpace(String text) {                                // 實現backspace功能
            return text.equals("0") || text.equals("") ? "0" : text.substring(0,
                    text.length() - 1);
        }
        
        /*清除所有計算結果,把firstNum與secondNum都設置為原始值,並返回firstNum,
         * 在CalService中提供了一個clearAll方法,用於清除所有的計算結果。
         * */
        public String clearAll() {                                            // 清除所有計算結果
                                                                            
            this.firstNum = "0";                                            // 將第一第二操作數恢復為默認值
            this.secondNum = null;
            return this.firstNum;
        }

        public String clear(String text) {                                    // 清除上次計算結果
            return "0";
        }
        
        public double getStore() {                                            //返回存儲器中的結果
            return this.store;
        }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM