Java使用Swing實現(xiàn)一個模擬電腦計算器
自己寫了一個計算器類似效果如下:
直接上源碼,后上講解。
一、源碼
import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.text.DecimalFormat; import java.util.function.ToDoubleBiFunction; public class MyCalculator { private JFrame frame=new JFrame("CSDN--哈__"); private String[] keys = {"%","C","CE","Back","1?x","X2","√x","÷","7","8","9", "X","4","5","6","-","1","2","3","+","+/-","0",".","="};//計算器的功能鍵保存 private JButton [] buttons=new JButton[keys.length];//創(chuàng)建按鈕 private JTextField resultText=new JTextField("0");//結(jié)果保存用于在計算器上顯示 private double resultNum =0.0000;//用于保存運算的結(jié)果 private boolean firstDigit=true;//判斷是否是第一個輸入的數(shù)字,或者是運算符后第一個數(shù)字 private String operate ="=";//記錄當前的運算符 private boolean opearteValidFlag =true;//判斷當前輸入是否合法 //構(gòu)造函數(shù) public MyCalculator(){ frame.setLocation(300,200); frame.setSize(new Dimension(366,439)); frame.setVisible(true); frame.setResizable(true);//窗口大小可修改 //這里采用awt組件來關(guān)閉窗口 事件監(jiān)聽 frame.addWindowListener(new WindowAdapter() { @Override public void windowClosed(WindowEvent e) { System.exit(0); } }); } public void init(){ //先定義三種顏色 用于背景板的填充 數(shù)值為網(wǎng)上查找 Color c1=new Color(181,181,181); Color c2=new Color(126,192,238); Color c3=new Color(232,232,232); //計算器功能面板初始化 JPanel pText =new JPanel();//用于保存文本域 JPanel pKey =new JPanel();//用于保存功能按鍵 //對文本域進行初始化 pText.setLayout(new BorderLayout()); pText.add(resultText); resultText.setFont(new Font("楷體",Font.BOLD,43));//設(shè)置文本框中字體的格式 resultText.setHorizontalAlignment(JTextField.RIGHT);//文本框默認右對齊 resultText.setEditable(false);//文本域不可編輯 resultText.setBorder(null);//設(shè)置邊框為無 resultText.setBackground(c1); //對功能案件進行初始化 pKey.setLayout(new GridLayout(6,4,2,2)); //六行四列,相鄰兩個按鈕上下間隔均為兩個像素 //開始在按鍵區(qū)加入前八個功能鍵 for (int i = 0; i < 8; i++) { buttons[i]=new JButton(keys[i]); pKey.add(buttons[i]); buttons[i].setBackground(c3); buttons[i].setForeground(Color.BLACK); buttons[i].setFont(new Font(Font.SERIF,Font.PLAIN,18)); buttons[i].setBorderPainted(false);//設(shè)置無邊框 buttons[i].addActionListener(myActionListener);//添加監(jiān)聽器 } for (int i = 8; i < keys.length; i++) { buttons[i]=new JButton(keys[i]); pKey.add(buttons[i]); if((i+1)%4==0) buttons[i].setBackground(c3); else buttons[i].setBackground(Color.white); buttons[i].setForeground(Color.BLACK); buttons[i].setFont(new Font(Font.SERIF,Font.PLAIN,18)); buttons[i].setBorderPainted(false);//設(shè)置無邊框 buttons[i].addActionListener(myActionListener);//添加監(jiān)聽器 } //最后將=號的背景色改為藍色,也就是c2 buttons[keys.length-1].setBackground(c2); pKey.setBackground(c1); frame.add(pText,BorderLayout.NORTH); frame.add(pKey); /* pText.setBorder(BorderFactory.createMatteBorder(25,3,1,3,c1)); pKey.setBorder(BorderFactory.createMatteBorder(6,3,3,3,c1));*/ } public class MyActionListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { String key = e.getActionCommand(); //對于具有清除刪除功能按鍵的處理(CE C BACK) if(key.equals(keys[1])||key.equals(keys[2])||key.equals(keys[3])){ doDeleteKey(key); } //對只需要一個數(shù)值的按鍵處理(% 1/x x2 √x +/- ) else if(key.equals(keys[0])||key.equals(keys[4])||key.equals(keys[5])||key.equals(keys[6])|| key.equals(keys[20])){ doOperator1(key); } //對需要兩個數(shù)值的按鍵的處理(÷ X - += ) else if(key.equals(keys[7])||key.equals(keys[11])||key.equals(keys[15])||key.equals(keys[19])|| key.equals(keys[23])){ doOperator2(key); } //對數(shù)字按鍵進行處理(1 2 3 4 5 6 7 8 9 .) else{ doNumberKey(key); } } } private void doDeleteKey(String key){ if(key.equals("CE")){ resultText.setText("0"); } else if(key.equals("C")){ resultText.setText("0"); resultNum=0.0000; firstDigit=true; opearteValidFlag=true; operate="="; } else{ String text=resultText.getText(); if(text.length()>1){ resultText.setText(text.substring(0,text.length()-1)); //如果內(nèi)容長度大于1,那么直接刪掉最后一個字符 }else{ //內(nèi)容長度等于1 resultText.setText("0"); firstDigit=true; } } } private void doOperator1(String key){ //對只需要一個數(shù)值的按鍵處理(% 1/x x2 √x +/- ) operate=key; if(operate.equals("%")){ resultNum=getNumFromText()/100; } else if(operate.equals("1?x")){ if(getNumFromText()==0){ //System.out.println("0沒有倒數(shù)!"); resultText.setText("零沒有倒數(shù)!"); opearteValidFlag=false; }else{ resultNum=resultNum+1.0/getNumFromText(); } } else if(operate.equals("√x")){ if(getNumFromText()<0){ //System.out.println("負數(shù)不能開方!"); resultText.setText("負數(shù)不能開方!"); opearteValidFlag=false; }else{ resultNum=resultNum+Math.sqrt(getNumFromText()); } } else if(operate.equals("X2")){ resultNum=resultNum+getNumFromText()*getNumFromText(); } else if(key.equals("+/-")){ resultNum=-getNumFromText(); firstDigit=true; opearteValidFlag=true; } } //兩個數(shù)進行運算 ÷ X - + = private void doOperator2(String key){ if(operate.equals("÷")){ if(getNumFromText()==0){ //System.out.println("零不能做除數(shù)!"); resultText.setText("零不能做除數(shù)!"); opearteValidFlag=false; }else{ resultNum/=getNumFromText(); } } else if(operate.equals("X")){ resultNum*=getNumFromText(); } else if(operate.equals("+")){ resultNum+=getNumFromText(); } else if(operate.equals("-")){ resultNum-=getNumFromText(); } else if(operate.equals("=")){ resultNum=getNumFromText(); } if(opearteValidFlag){ long t1=(long)resultNum; double t2=resultNum-t1; if(t2==0){ resultText.setText(String.valueOf(t1)); }else{ resultText.setText(String.valueOf(new DecimalFormat("0.0000").format(resultNum))); } } operate=key; firstDigit=true; opearteValidFlag=true; } private void doNumberKey(String key){ //如果是第一個輸入的數(shù)字或者符號后第一個數(shù)字 if(firstDigit){ if(key.equals(".")) /*resultText.setText(resultText.getText()+".");*/{ //上來直接按. if(resultNum==0&&operate=="=") resultText.setText(resultText.getText()+"."); //上來先按了個別的運算符 在按. else{ resultText.setText("0."); // resultText.setText("出錯!"); //opearteValidFlag=false; } } else resultText.setText(key); }else if(key.equals(".")&&resultText.getText().indexOf(".")<0){ resultText.setText(resultText.getText()+"."); }else if(!key.equals(".")){ resultText.setText(resultText.getText()+key); } firstDigit=false; } private double getNumFromText(){ double result = 0; try { result = Double.valueOf(resultText.getText()).doubleValue(); } catch (NumberFormatException e) { } return result; } MyActionListener myActionListener=new MyActionListener(); public static void main(String[] args) { new MyCalculator().init(); } }
二、講解
1、創(chuàng)建我們所需的變量
計算器上的按鍵不少,我們都定義在一個keys數(shù)組當中,并且初始化一個buttons按鈕數(shù)組。
除了我們的按鈕之外,還有我們的輸出顯示窗口resultText,輸出的結(jié)果我們都用resultNum來記錄,之后在放到我們的輸出窗口上。
其他的都寫成注解了。
private JFrame frame=new JFrame("CSDN--哈__"); private String[] keys = {"%","C","CE","Back","1?x","X2","√x","÷","7","8","9", "X","4","5","6","-","1","2","3","+","+/-","0",".","="};//計算器的功能鍵保存 private JButton [] buttons=new JButton[keys.length];//創(chuàng)建按鈕 private JTextField resultText=new JTextField("0");//結(jié)果保存用于在計算器上顯示 private double resultNum =0.0000;//用于保存運算的結(jié)果 private boolean firstDigit=true;//判斷是否是第一個輸入的數(shù)字,或者是運算符后第一個數(shù)字 private String operate ="=";//記錄當前的運算符 private boolean opearteValidFlag =true;//判斷當前輸入是否合法
2.面板初始化
面板初始化就是init方法,注釋我都寫了,這里不在講了,也沒啥重要的,就是美化一下面板。
3.添加按鈕事件監(jiān)聽機制
當我們點擊計算機上的按鈕的時候,計算器要給出反饋,這時就需要我們添加一個事件監(jiān)聽機制了。注釋寫好了,當我們點擊不同的按鈕的時候要處理不同的功能。
public class MyActionListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { String key = e.getActionCommand(); //對于具有清除刪除功能按鍵的處理(CE C BACK) if(key.equals(keys[1])||key.equals(keys[2])||key.equals(keys[3])){ doDeleteKey(key); } //對只需要一個數(shù)值的按鍵處理(% 1/x x2 √x +/- ) else if(key.equals(keys[0])||key.equals(keys[4])||key.equals(keys[5])||key.equals(keys[6])|| key.equals(keys[20])){ doOperator1(key); } //對需要兩個數(shù)值的按鍵的處理(÷ X - += ) else if(key.equals(keys[7])||key.equals(keys[11])||key.equals(keys[15])||key.equals(keys[19])|| key.equals(keys[23])){ doOperator2(key); } //對數(shù)字按鍵進行處理(1 2 3 4 5 6 7 8 9 .) else{ doNumberKey(key); } } }
4.處理對于具有清除刪除功能按鍵的處理(CE C BACK)
計算器上有個清空按鍵C大家都用過吧,點了這個C之后我們所有的輸入都會被初始化。倘若點了退格鍵那我們就把面板上的文字域刪掉一個符號。比如我們輸入的是111,點了退格之后就是11,當然你會想這只是文字域的變化,那我們保存的要計算的值為什么不變?別著急,真正開始計算是在我們點擊了加減乘除這一類的符號的時候才會從面板讀取值的。
private void doDeleteKey(String key){ if(key.equals("CE")){ resultText.setText("0"); } else if(key.equals("C")){ resultText.setText("0"); resultNum=0.0000; firstDigit=true; opearteValidFlag=true; operate="="; } else{ String text=resultText.getText(); if(text.length()>1){ resultText.setText(text.substring(0,text.length()-1)); //如果內(nèi)容長度大于1,那么直接刪掉最后一個字符 }else{ //內(nèi)容長度等于1 resultText.setText("0"); firstDigit=true; } } }
5.兩個數(shù)進行運算加減乘除
上來先判斷你當前的的符號是什么,并且也進行了一些錯誤情況的判斷,如除數(shù)不能為0什么的。
下邊你就能看到我們的resultNum被使用了。最后來個操作是否合法判斷,如果合法并且輸出結(jié)果最后是0那我們直接就把0輸出到面板上,但是倘若我們的輸出結(jié)果有精度差,那我們就得自己將0放到面板上了。
注:我使用的浮點數(shù)計算并不是BigDecimal,所以存在精度差。
private void doOperator2(String key){ if(operate.equals("÷")){ if(getNumFromText()==0){ //System.out.println("零不能做除數(shù)!"); resultText.setText("零不能做除數(shù)!"); opearteValidFlag=false; }else{ resultNum/=getNumFromText(); } } else if(operate.equals("X")){ resultNum*=getNumFromText(); } else if(operate.equals("+")){ resultNum+=getNumFromText(); } else if(operate.equals("-")){ resultNum-=getNumFromText(); } else if(operate.equals("=")){ resultNum=getNumFromText(); } if(opearteValidFlag){ long t1=(long)resultNum; double t2=resultNum-t1; if(t2==0){ resultText.setText(String.valueOf(t1)); }else{ resultText.setText(String.valueOf(new DecimalFormat("0.0000").format(resultNum))); } } operate=key; firstDigit=true; opearteValidFlag=true; }
到此這篇關(guān)于Java使用Swing實現(xiàn)一個模擬計算器的文章就介紹到這了,更多相關(guān)Java Swing模擬計算器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中使用HTTP客戶端工具Retrofit
這篇文章主要為大家介紹了SpringBoot中使用HTTP客戶端工具Retrofit方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06Java求解兩個非負整數(shù)最大公約數(shù)算法【循環(huán)法與遞歸法】
這篇文章主要介紹了Java求解兩個非負整數(shù)最大公約數(shù)算法,結(jié)合實例形式分析了java求解最大公約數(shù)的實現(xiàn)方法,并附帶了循環(huán)法與遞歸法算法思路,需要的朋友可以參考下2018-03-03Spring AOP + 注解實現(xiàn)統(tǒng)一注解功能
本文我們通過Spring AOP和Java的自定義注解來實現(xiàn)日志的插入功能,非常不錯,具有一定的參考借鑒價值,需要的朋友一起看看吧2018-05-05java數(shù)據(jù)結(jié)構(gòu)圖論霍夫曼樹及其編碼示例詳解
這篇文章主要為大家介紹了java數(shù)據(jù)結(jié)構(gòu)圖論霍夫曼樹及其編碼示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2021-11-11