Java實現圖形界面計算器
本文實例為大傢分享瞭Java實現圖形界面計算器的具體代碼,供大傢參考,具體內容如下
代碼:
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() { //完成佈局以及定義監聽器 DisplayBox.setHorizontalAlignment(JTextField.RIGHT); //文本框右對齊 DisplayBox.setFont(new Font("DIN", Font.BOLD, 30)); //DIN:一種數字常用字體 Cache.setFont(new Font("DIN", Font.BOLD, 30)); GridBagLayout gridBagLayout = new GridBagLayout(); //采取網格包佈局 GridBagConstraints gridBagConstraints = new GridBagConstraints(); gridBagConstraints.fill = GridBagConstraints.BOTH; //該方法是為瞭設置如果組件所在的區域比組件本身要大時的顯示情況 gridBagConstraints.weightx = 1; //使組件的大小取得最大空間 gridBagConstraints.weighty = 1; setLayout(gridBagLayout); gridBagConstraints.gridx = 0; //緩存區起始位置為(0,0),橫向占據4格,縱向1格 gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 4; gridBagConstraints.gridheight = 1; gridBagLayout.setConstraints(Cache, gridBagConstraints); this.add(Cache); gridBagConstraints.gridx = 0; //文本框起始位置為(0,0),橫向占據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; //每個按鈕占據1格 gridBagConstraints.gridheight = 1; for (int i = 0; i < ButtonNames.length; i++) { Buttons[i] = new JButton(ButtonNames[i]); } int n = 0; //記錄每一行輸出的按鈕數,滿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++) { //事件監聽器 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); //中綴表達式的數組 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後面可能出現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 "運算過程中除數出現0"; } top = top2 / top1; stack.push(String.valueOf(top)); break; } } else { //為數字直接入棧 stack.push(suffix[i]); } } String result = stack.pop(); return result; } private String[] breakDown(String string) { //將(2+3.14)+9分解成 ( 2 + 3.14 ) + 9便於後續計算 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(","); //產生的字符串數組中隻會含+-*/()整數和小數 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 { //為數字直接成為後綴一部分 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) { //運算數數量 = 運算符號數+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) { //不是括號 不是運算符一定為運算數 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(); } }
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。