您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么用Java實現簡單計算器功能”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么用Java實現簡單計算器功能”吧!
實訓目的:掌握 Java GUI 開發中的布局管理和事件處理機制。
實訓要求:
(1)要使用 java 的 GUI 設計出計算器界面。
(2)通過界面按鈕,可以實現整數或浮點數的四則運算,并能將結果顯示在界面中。
(3)計算可以有小數點,和正負整數的計算。
(4)要有清零功能。
中綴表達式的計算solution(String str)
用來中算后綴表達式的值,并將結果返回。準備一個數字棧,一個運算符棧。大致的思路就是遇到,數字直接入數字棧,運算符看優先級進行處理,將要入運算符棧的運算符與棧頂的運算符進行比較,棧頂運算符優先級比較高的話,則把棧頂的運算符彈并且把數字棧的兩個數字進行彈出,進行運算,并且把結果再次放到數字棧中,最后剩下的就是最終結果。如果運算符優先級比運算符棧頂的小,則把運算符進棧,最后把運算符都出棧。
計算加減乘除余caculateResult(char optemp, double num1, double num2)
通過傳入的optemp(表達式符號)參數。是什么符號就進行什么樣的運算
判斷符號的優先級getOperlevel(char c)
先乘除后加減,通過0,1,2對運算符的優先級進行標記
首先先設計一個GUI界面,先設置一個JFrame容器,容器中創建兩個面板和若干按鈕,先把按鈕要顯示的文字存入字符串數組,然后依次創建幾個按鈕。在設置一個文本框,用來接收用戶輸入的內容,centerPanel.setLayout(new GridLayout(4, 4, 12, 16));設置中間面板的布局為網格布局,并指定該容器的行數和列數以及組件之間的水平、垂直間距。centerPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));為面板創建一個框,框的頭部為5像素,左為5像素,底部為5像素,右為5像素寬。再設置單行文本域的大小,字體,風格和字號,然后為各按鈕設置監聽器。定義一個StringBuffer類,用于保存觸發產生的內容,在用txt.setText(r.toString());方法將內容輸出在文本框中,clear按鈕觸發后,用r.delete(0,r.length());方法清空字符串中的內容并將結果顯示在文本框中,“=”按鈕是把觸發器觸發的數字保存StringBuffer里面,然后用該類的toString()方法返回StringBuffer緩沖區中的字符對象,用String類型的變量接收,該字符串接收到的就是一個中綴表達式,創建一個類,該類用于將輸入的中綴表達式進行計算,把計算的結果返回給“=”按鈕觸發器中的result變量,把該變量轉化為字符串輸出在文本框中。
首先,我看到這個題的第一反應是這個界面的布局要用到網格布局,開始我是想直接在觸發器里面實現相應的加減乘除功能的,發現如果要計算四則運算有點困難,單個的加減乘除還是挺容易的,后面寫了一些代碼后,果斷刪了重寫,采用了數據結構中的中綴表達式的計算算法(要用到棧),不過那個時候用的語言是C語言,所以關于棧的書寫就只能去百度了,之后我知道了棧和他的有關方法,自己也嘗試這寫了一段代碼進行了測試,更加熟練的掌握了棧的用法。
還順便看了一下廣大網友的代碼和算法,發現都大同小異,我自己也在他們寫的算法的基礎上寫了一段代碼,新增加了實現小數四則運算的功能,其中判斷運算符的優先級那段代碼直接搬運了網上的代碼。
經過測試,發現精度有一點問題,運算的結果有時是正確的,有時是無限接近正確結果(小數點后面的小數位太多了),還有就是實現不了負數的運算,但可以實現浮點數的四則運算。以我現在的水平,這個bug暫時還解決不了。所以就沒在修改了然后利用對象的調用把運算結果輸出在文本框里面。有一段時間這個程序的界面老是顯示不出來,控制臺console那里老是閃一下就滅了,我也非常納悶,之前我還可以顯示出來的啊,現在怎么就這樣的,百度了很久也沒找到答案,后面去請教同學,才發現原來我的聊天窗口沒有設置為可見frame.setVisible(true);。所以一般在設置容器的時候,就在他的后面寫完他的所有屬性,不要寫完運行出錯了,才發現沒有寫。`
Calculater:
package com.itcase_eight; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DateFormat; import java.util.Date; /** * @author 羅志剛 * @date 2020/12/16 22:09 */ public class Calculater { public static void createAndShowGUI() { Date date=new Date(); DateFormat format=DateFormat.getDateInstance(DateFormat.SHORT); // 對計算器整體框架的建立start JFrame f = new JFrame("計算器");// 窗口 JPanel centerPanel = new JPanel(); // 中間面板 JPanel startPanel=new JPanel(); // 初始化功能鍵 JButton left=new JButton("("); JLabel data=new JLabel(format.format(date),JLabel.CENTER); data.setFont(new Font("Times New Roman",Font.BOLD,17)); JButton clear=new JButton("Clear"); JButton right=new JButton(")"); String button[] = { "7", "8", "9", "/", "4", "5", "6", "*", "1", "2", "3", "-", ".", "0", "=", "+"}; JButton but0 = new JButton(button[0]); JButton but1 = new JButton(button[1]); JButton but2 = new JButton(button[2]); JButton but3 = new JButton(button[3]); JButton but4 = new JButton(button[4]); JButton but5 = new JButton(button[5]); JButton but6 = new JButton(button[6]); JButton but7 = new JButton(button[7]); JButton but8 = new JButton(button[8]); JButton but9 = new JButton(button[9]); JButton but10 = new JButton(button[10]); JButton but11 = new JButton(button[11]); JButton but12 = new JButton(button[12]); JButton but13 = new JButton(button[13]); JButton but14 = new JButton(button[14]); JButton but15 = new JButton(button[15]); // 單行輸入文本框 JTextField txt = new JTextField(); // 使用網格布局方式 centerPanel.setLayout(new GridLayout(5, 4, 12, 16)); // 左右上下間隔 centerPanel.add(left); centerPanel.add(clear); centerPanel.add(right); centerPanel.add(data); centerPanel.add(but0); centerPanel.add(but1); centerPanel.add(but2); centerPanel.add(but3); centerPanel.add(but4); centerPanel.add(but5); centerPanel.add(but6); centerPanel.add(but7); centerPanel.add(but8); centerPanel.add(but9); centerPanel.add(but10); centerPanel.add(but11); centerPanel.add(but12); centerPanel.add(but13); centerPanel.add(but14); centerPanel.add(but15); centerPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); // 設置容器大小 txt.setPreferredSize(new Dimension(465, 40)); // 設置字體,風格和字號 txt.setFont(new Font("宋體", Font.PLAIN, 28)); f.add(startPanel); f.add(txt, BorderLayout.NORTH); // 將單行文本框添加到窗口的 北部 f.add(centerPanel, BorderLayout.SOUTH); // 將中間面板添加到窗口的南部 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 點X關閉窗口 f.setLocation(400, 200); // 初始化時定位 f.setSize(500, 300); // 展示JFrame窗口 f.setVisible(true); f.setResizable(false); // 禁止拖曳改變窗口大小 f.pack(); // 讓窗口的大小自適應 // 對計算器整體框架的建立end // 為按鈕事件添加自定義監聽器start StringBuffer r=new StringBuffer(); but0.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("7"); txt.setText(r.toString()); } }); but1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("8"); txt.setText(r.toString()); } }); but2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("9"); txt.setText(r.toString()); } }); but4.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("4"); txt.setText(r.toString()); } }); but5.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("5"); txt.setText(r.toString()); } }); but6.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("6"); txt.setText(r.toString()); } }); left.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("("); txt.setText(r.toString()); } }); right.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append(")"); txt.setText(r.toString()); } }); but8.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("1"); txt.setText(r.toString()); } }); but9.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("2"); txt.setText(r.toString()); } }); but10.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("3"); txt.setText(r.toString()); } }); but13.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("0"); txt.setText(r.toString()); } }); but15.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("+"); txt.setText(r.toString()); } }); but3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("/"); txt.setText(r.toString()); } }); but7.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("*"); txt.setText(r.toString()); } }); but12.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("."); txt.setText(r.toString()); } }); but11.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("-"); txt.setText(r.toString()); } }); clear.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.delete(0,r.length()); //清空字符串中的內容 txt.setText(r.toString()); //將結果顯示在文本框中 } }); but14.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { r.append("="); String str=r.toString(); txt.setText(""); double result= Computer.solution(str); String string=String.valueOf(result); r.delete(0,r.length()); r.append(string); txt.setText(string); } }); } public static void main(String[] args) { SwingUtilities.invokeLater(Calculater::createAndShowGUI); } }
Computer類:
package com.itcase_eight; import java.util.Stack; /** * @author 羅志剛 * @date 2020/12/16 22:05 */ public class Computer { public static double solution(String str) { Stack<Double> numStack = new Stack<>(); Stack<Character> signalStack = new Stack<>(); int index = 0;// 記錄已經執行的符號數 int len = str.length(); while (index < len) { char c = str.charAt(index); // 取出這一步的符號 if (c == '(') { signalStack.push(c);// 若是左括號就進棧 } // 否則要先判斷優先級 else if (c == '+' || c == '-' || c == '*' || c == '/') { int currOperLevel = getOperlevel(c);// 當前符號的優先級 while (true) { int stackOperLevel = 0;// 棧頂元素的優先級 if (!signalStack.isEmpty()) { Object obj = signalStack.peek(); stackOperLevel = getOperlevel((char) obj); } // 若當前元素優先級大于棧頂元素的優先級則入棧 if (currOperLevel > stackOperLevel) { signalStack.push(c); break;// 直到讓比自己優先級高的符號都出棧運算了再把自己進棧 } else {// 不能入棧就進行計算 try { char optemp = '0'; double num1 = 0; double num2 = 0; if (!signalStack.isEmpty()) { optemp = (char) signalStack.pop();// 取出優先級大的那個符號 } if (!numStack.isEmpty()) { num1 = (double) numStack.pop(); num2 = (double) numStack.pop();// 取出數據棧中的兩個數 } numStack.push(caculateResult(optemp, num2, num1));// 將算出來的結果數據再次進入數據棧 } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } } else if (c == ')') {// 右括號就返回棧頂元素,右括號是不進棧的 while (true) { char theop = (char) signalStack.pop(); if (theop == '(') { break; } else { try { double num1 = (double) numStack.pop(); double num2 = (double) numStack.pop(); numStack.push(caculateResult(theop, num2, num1));// 運算括號內的內容 } catch (Exception e) { e.printStackTrace(); } } } } else if (c >= '0' && c <= '9') { int tempIndex = index + 1; while (tempIndex < len) { char temp = str.charAt(tempIndex);// 取字符串中處于當前字符的下一位 if ((temp >= '0' && temp <= '9') || temp == '.') { tempIndex++;// 若為數字則繼續向后取 } else { break;// 證明數字去完 } } String numstr = str.substring(index, tempIndex);// 截取這個字符串則為兩個符號之間的數字 try { double numnum = Double.parseDouble(numstr);// 將數字轉換成整型便于運算 numStack.push(numnum); index = tempIndex - 1; } catch (Exception e) { e.printStackTrace(); } } index++; } // 檢查符號棧是否為空 while (true) { Object obj = null; if (signalStack.isEmpty() == false) { obj = signalStack.pop(); } if (obj == null) { break;// 為空證明運算已結束 } else {// 不為空就出棧運算 char opterTemp = (char) obj; double num1 = (double) numStack.pop(); double num2 = (double) numStack.pop(); numStack.push(caculateResult(opterTemp, num2, num1)); } } double result = 0; try { result = (double) numStack.pop(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return result; } //計算加減乘除余 private static Double caculateResult(char optemp, double num1, double num2) { switch (optemp) { case '+': return num1 + num2; case '-': return num1 - num2; case '*': return num1 * num2; case '/': return num1 / num2; } return 0.0; } //返回符號優先級 private static int getOperlevel(char c) { switch (c) { case '(': return 0; case '+': case '-': return 1; case '*': case '/': return 2; default: return 0; } } }
感謝各位的閱讀,以上就是“怎么用Java實現簡單計算器功能”的內容了,經過本文的學習后,相信大家對怎么用Java實現簡單計算器功能這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。