Java實現(xiàn)圖形界面計算器
更新時間:2021年11月22日 11:48:45 作者:我不會JAVA!
這篇文章主要為大家詳細介紹了Java實現(xiàn)圖形界面計算器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了Java實現(xiàn)圖形界面計算器的具體代碼,供大家參考,具體內容如下
?
代碼:
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Stack; public class Calculator extends JFrame implements ActionListener { private final String[] ButtonNames = {"(", ")", "←", "C", "7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", ".", "0", "=", "/"}; private JTextField DisplayBox = new JTextField("0.0"); private JTextField Cache = new JTextField(""); private JButton[] Buttons = new JButton[ButtonNames.length]; public Calculator() { super(); setTitle("計算器"); init(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 400, 600); setResizable(false); //窗口不可調整大小 setVisible(true); } private void init() { //完成布局以及定義監(jiān)聽器 DisplayBox.setHorizontalAlignment(JTextField.RIGHT); //文本框右對齊 DisplayBox.setFont(new Font("DIN", Font.BOLD, 30)); //DIN:一種數(shù)字常用字體 Cache.setFont(new Font("DIN", Font.BOLD, 30)); GridBagLayout gridBagLayout = new GridBagLayout(); //采取網(wǎng)格包布局 GridBagConstraints gridBagConstraints = new GridBagConstraints(); gridBagConstraints.fill = GridBagConstraints.BOTH; //該方法是為了設置如果組件所在的區(qū)域比組件本身要大時的顯示情況 gridBagConstraints.weightx = 1; //使組件的大小取得最大空間 gridBagConstraints.weighty = 1; setLayout(gridBagLayout); gridBagConstraints.gridx = 0; //緩存區(qū)起始位置為(0,0),橫向占據(jù)4格,縱向1格 gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 4; gridBagConstraints.gridheight = 1; gridBagLayout.setConstraints(Cache, gridBagConstraints); this.add(Cache); gridBagConstraints.gridx = 0; //文本框起始位置為(0,0),橫向占據(jù)4格,縱向2格 gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 4; gridBagConstraints.gridheight = 2; gridBagLayout.setConstraints(DisplayBox, gridBagConstraints); this.add(DisplayBox); gridBagConstraints.gridy = 3; //按鈕起始位置為(0,3) gridBagConstraints.gridwidth = 1; //每個按鈕占據(jù)1格 gridBagConstraints.gridheight = 1; for (int i = 0; i < ButtonNames.length; i++) { Buttons[i] = new JButton(ButtonNames[i]); } int n = 0; //記錄每一行輸出的按鈕數(shù),滿4換行 for (int i = 0; i < Buttons.length; i++) { gridBagLayout.setConstraints(Buttons[i], gridBagConstraints); this.add(Buttons[i]); n++; if (n == 4) { gridBagConstraints.gridx = 0; gridBagConstraints.gridy++; n = 0; } else { gridBagConstraints.gridx++; } } for (int i = 0; i < Buttons.length; i++) { //事件監(jiān)聽器 Buttons[i].addActionListener(this); } } @Override public void actionPerformed(ActionEvent e) { //對事件的處理 String str; String value = e.getActionCommand(); //獲取按鈕的值 char v = value.charAt(0); switch (v) { case 'C': DisplayBox.setText("0.0"); break; case '←': DeleteOne(); break; case '=': String string = DisplayBox.getText(); Cache.setText(string + "="); if (isTrue(string)) { //若格式正確 str = retureResult(); DisplayBox.setText(str); } else { DisplayBox.setText("輸入格式不合法"); } break; default: AddOne(value); break; } } private void DeleteOne() { //刪除一個字符 String str; str = DisplayBox.getText(); if (str.length() == 1) { DisplayBox.setText("0.0"); } else if(!str.equals("0.0")) { str = str.substring(0, str.length() - 1); //去掉最后一個元素 DisplayBox.setText(str); } } private void AddOne(String value) { //增加一個字符 String str; str = DisplayBox.getText(); if (str.equals("0.0")) { //第一次輸入 DisplayBox.setText(value); } else { str = str + value; DisplayBox.setText(str); } } private String retureResult() { //對輸入的式子進行運算;基本方法:逆波蘭法,中綴轉后綴 String string = DisplayBox.getText(); String[] Midfix = breakDown(string); //中綴表達式的數(shù)組 String[] suffix = Conversion(Midfix); //得到后綴表達式 String result = Calculation(suffix); //計算后綴表達式結果 return result; } private String Calculation(String[] suffix) { Stack<String> stack = new Stack<>(); String symbols = "+-*/"; //轉換為后綴表達式的式子只會有 +-*/ 符號不會有 () for (int i = 0; i < suffix.length; i++) { if (suffix[i] == null) { //suffix后面可能出現(xiàn)null 故對其篩選不進行下列的操作 continue; } if (symbols.indexOf(suffix[i]) >= 0) { //為符號時進行運算 double top1; double top2; double top; switch (suffix[i]) { case "+": top1 = Double.parseDouble(stack.pop()); //取棧頂將其轉化為double top2 = Double.parseDouble(stack.pop()); top = top2 + top1; stack.push(String.valueOf(top)); //將top轉化為String入棧 break; case "-": top1 = Double.parseDouble(stack.pop()); top2 = Double.parseDouble(stack.pop()); top = top2 - top1; stack.push(String.valueOf(top)); break; case "*": top1 = Double.parseDouble(stack.pop()); top2 = Double.parseDouble(stack.pop()); top = top2 * top1; stack.push(String.valueOf(top)); break; case "/": top1 = Double.parseDouble(stack.pop()); top2 = Double.parseDouble(stack.pop()); if (top1 == 0) { return "運算過程中除數(shù)出現(xiàn)0"; } top = top2 / top1; stack.push(String.valueOf(top)); break; } } else { //為數(shù)字直接入棧 stack.push(suffix[i]); } } String result = stack.pop(); return result; } private String[] breakDown(String string) { //將(2+3.14)+9分解成 ( 2 + 3.14 ) + 9便于后續(xù)計算 String[] split = string.split(""); String DigitString = "0123456789."; String afterSplit = ""; for (int i = 0; i < split.length; i++) { //將 2+3.14 變成 2,+,3.14 便于拆分 if (DigitString.indexOf(split[i]) >= 0) { afterSplit = afterSplit + split[i]; } else if(afterSplit.equals("") && DigitString.indexOf(split[i]) < 0) { //第一個為符號時只在后面加。 afterSplit = afterSplit + split[i] + ","; } else { //為 () 或 =-*/ 在其兩側加上 , afterSplit = afterSplit + "," + split[i] + ","; } } afterSplit = afterSplit.replace(",,", ","); //避免(2+3)+2產生……3,),,+,2 split = afterSplit.split(","); //產生的字符串數(shù)組中只會含+-*/()整數(shù)和小數(shù) return split; } private String[] Conversion(String[] strings) { //中綴轉后綴 String[] suffix = new String[strings.length]; //后綴表達式 int n = 0; //suffix的下標 Stack<String> stack = new Stack<>(); String first = "*/"; String symbols = "+-*/()"; for (int i = 0; i < strings.length; i++) { if(symbols.indexOf(strings[i]) >= 0) { //為符號時 if (stack.empty()) { stack.push(strings[i]); } else { //棧不為空 if(first.indexOf(strings[i]) >= 0 || strings[i].equals("(")) { //為 +/( 直接入棧 stack.push(strings[i]); } else if(strings[i].equals(")")) { String top = stack.peek(); while(!top.equals("(")) { top = stack.pop(); suffix[n] = top; n++; top = stack.peek(); } stack.pop(); // ( 出棧 } else { //符號為 +- if(first.indexOf(stack.peek()) < 0) { //當棧頂不為為 */ 直接入棧 stack.push(strings[i]); } else { while (!stack.empty() && first.indexOf(stack.peek()) >= 0) //棧頂運算符先于當前運算符時,出棧到棧頂運算符低于或棧為空為止 { String s = stack.pop(); suffix[n] = s; n++; } stack.push(strings[i]); //當前運算符入棧 } } } } else { //為數(shù)字直接成為后綴一部分 suffix[n] = strings[i]; n++; } } while (!stack.empty()) { //清除棧內剩余符號 String s = stack.pop(); suffix[n] = s; n++; } return suffix; } private boolean isTrue(String str) { if (!BracketMatching(str)) { //括號匹配 return false; } if (!OperatorIsTrue(str)) { //符號格式正確 return false; } return true; } private boolean OperatorIsTrue(String string) { //運算數(shù)數(shù)量 = 運算符號數(shù)+1 String[] split = breakDown(string); String symblos = "+-*/"; String bracket = "()"; int NumberOfDigits = 0; int NumberOfSymblos = 0; for (int i = 0; i < split.length; i++) { if(symblos.indexOf(split[i]) >= 0) { NumberOfSymblos++; } else if(bracket.indexOf(split[i]) < 0) { //不是括號 不是運算符一定為運算數(shù) NumberOfDigits++; } } if (NumberOfDigits != NumberOfSymblos + 1) { return false; } return true; } private boolean BracketMatching(String string) { //判斷括號是否匹配,否則報錯 char[] split = string.toCharArray(); Stack<Character> stack = new Stack<>(); for (int i = 0; i < split.length; i++) { if (split[i] == '(') { stack.push(split[i]); } else if (!stack.empty() && split[i] == ')') { stack.pop(); } else if (stack.empty() && split[i] == ')') { return false; } } if (!stack.empty()) { return false; } return true; } public static void main(String[] args) { Calculator calculator = new Calculator(); } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Spring Boot2與Spring Boot3的區(qū)別小結
SpringBoot2和SpringBoot3之間有一些重要的區(qū)別,本文就來探討SpringBoot2和SpringBoot3之間的區(qū)別,具有一定的參考價值,感興趣的可以了解一下2023-10-10FreeMarker如何調用Java靜態(tài)方法及靜態(tài)變量方法
這篇文章主要介紹了FreeMarker如何調用Java靜態(tài)方法及靜態(tài)變量方法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12Spring BPP中如何優(yōu)雅的創(chuàng)建動態(tài)代理Bean詳解
這篇文章主要給大家介紹了關于Spring BPP中如何優(yōu)雅的創(chuàng)建動態(tài)代理Bean的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-03-03SpringBoot @Async如何自定義線程池及使用教程
這篇文章主要介紹了SpringBoot @Async如何自定義線程池及使用教程,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01@PreAuthorize、@PostAuthorize、@PreFilter、@PostFilter注解的用法詳解
這篇文章主要介紹了@PreAuthorize、@PostAuthorize、@PreFilter、@PostFilter注解的用法詳解,通過在方法上添加@PreAuthorize注解,可以指定需要滿足的權限條件,只有滿足條件的用戶才能執(zhí)行該方法,需要的朋友可以參考下2023-10-10Java編程中快速排序算法的實現(xiàn)及相關算法優(yōu)化
這篇文章主要介紹了Java編程中快速排序算法的實現(xiàn)及相關算法優(yōu)化,快速排序算法的最差時間復雜度為(n^2),最優(yōu)時間復雜度為(n\log n),存在優(yōu)化的空間,需要的朋友可以參考下2016-05-05