wangflood

          精心維護(hù)一個技術(shù)blog,為了工作,也是愛好。

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            14 Posts :: 19 Stories :: 8 Comments :: 0 Trackbacks
          這是我在java課程設(shè)計上的一個作品。老師要求很簡單,我盡量做得完善,在要求之外,做了不少。
          在小數(shù)點,一些windows計算器怪異的地方(3+=+9++4=),參考網(wǎng)上的算法完成。

          算法簡介:
          [=]的功能:

          1.如果前次為一次有效的右數(shù)輸入則將當(dāng)前數(shù)賦給右數(shù)變量。

          2.檢查符變量是否存在運算符,若存在則計算表達(dá)式左數(shù) 運算符 右數(shù),并將結(jié)果賦給左數(shù)變量,同時顯示。若不存在,則不作操作。

          3.清空串變量。

          [四則運算符]的功能:

          1.若前次為一次運算數(shù)輸入,則執(zhí)行[=]

          2.將當(dāng)前數(shù)賦給左右數(shù)變量,將運算符賦給符變量。

          3.清空串變量。



          算法具體鏈接:http://blog.csdn.net/haochen_net/archive/2008/10/25/3143290.aspx
          Cal類的實現(xiàn):


          import java.awt.BorderLayout;
          import java.awt.CheckboxMenuItem;
          import java.awt.Container;
          import java.awt.GridLayout;
          import java.awt.Menu;
          import java.awt.MenuBar;
          import java.awt.MenuItem;
          import java.awt.event.ActionEvent;
          import java.awt.event.ActionListener;

          import javax.swing.JButton;
          import javax.swing.JFrame;
          import javax.swing.JOptionPane;
          import javax.swing.JPanel;
          import javax.swing.JTextField;
          import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;

          public class Cal extends JFrame implements ActionListener {
              
          // 菜單
              MenuBar myMenuBar = new MenuBar();
              
          // JPanel
              JPanel pdisplay = new JPanel();
              JPanel pm 
          = new JPanel(new GridLayout(5105));
              JPanel pc 
          = new JPanel(new GridLayout(1350));
              JPanel pb 
          = new JPanel(new GridLayout(4555));
              JPanel pbc 
          = new JPanel(new BorderLayout(55));
              JPanel pbcm 
          = new JPanel();

              
          static// 顯示
              JTextField tftext = new JTextField(25);
              JTextField tfm 
          = new JTextField(5);
              
          // 按鈕字符定義及按鈕
              String strB[] = { "MC""MR""MS""M+""Backspace""CE""C""7""8",
                      
          "9""/""sqrt""4""5""6""*""%""1""2""3""-",
                      
          "1/x""0""+/-"".""+""=" };
              JButton[] jb 
          = new JButton[27];

              
          public Cal() {

                  
          super("計算機(jī)-蕎葉制作");
                  addMenu();
                  initDisplay();
                  initPbcm();

                  Container pane 
          = this.getContentPane();
                  pane.setLayout(
          new BorderLayout(105));
                  pane.add(pdisplay, BorderLayout.NORTH);
                  pane.add(pbcm, BorderLayout.CENTER);

                  
          this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  
          this.setBounds(300200400260);
                  
          this.setResizable(false);
                  
          this.setVisible(true);

              }

              
          // 一些類變量
              static StringBuilder text = new StringBuilder("0");// 顯示符
              StringBuilder number = new StringBuilder("0");// 當(dāng)前數(shù).
              double rightOper;// 右數(shù)
              double leftOper;// 左數(shù)
              double result;// 結(jié)果
              int operator;// 操作符,默認(rèn)為0,沒有操作符
              int isFloat = 0;// 0不是浮點型,1輸入了一個.2真正的浮點
              boolean isZero = true;// 0顯示清空狀態(tài),不能輸入0.輸入1-9進(jìn)入1狀態(tài).可以輸入0-9進(jìn)入2;
              boolean isNeg;// 默認(rèn)為正數(shù)
              boolean isExcp;// 默認(rèn)沒有異常.
              StringBuilder m = new StringBuilder("0");// 存儲數(shù)串變量
              int isRightInput = 0;// 一次有效右輸入,輸入運算符后=1;再輸入數(shù)字后=2;

              
          // //////////////////////////////////////////////////////////////////////////////////////
              /**
               * number是用于給leftOper和rightOper賦值的.純純的能夠轉(zhuǎn)化為Double類型的StringBuilder.
               * 當(dāng)然text,number,m考慮到大量的String連接和轉(zhuǎn)換,StringBuilder效率更高.
               * 
          */
              
          public void actionPerformed(ActionEvent e) {
                  String cmd 
          = e.getActionCommand();
                  
          if (cmd == "0" || cmd == "1" || cmd == "2" || cmd == "3" || cmd == "4"
                          
          || cmd == "5" || cmd == "6" || cmd == "7" || cmd == "8"
                          
          || cmd == "9") {
                      
          if (isExcp)// 如果是三種錯誤之一,就不響應(yīng)了.只有CE和C能夠響應(yīng)
                          return;
                      
          if (isRightInput == 1)// 如果是待一次有效右輸入.也就是前一次輸入的是運算符.
                          isRightInput = 2;// 進(jìn)階真正的右輸入
                      if (isZero) {// 處于清空狀態(tài)
                          number = new StringBuilder(cmd);// number直接為一個數(shù)字串
                          isZero = false;// 有一位數(shù)字后,不在處于清空.后面就可以輸入運算符,單目,.,+/-
                      } else {
                          
          if (isFloat == 1) {// 待浮點狀態(tài),前一次輸入的是.
                              number.append('.');// number這時加入.
                              isFloat = 2;// 真正的浮點.
                          }
                          number.append(cmd);
          // 數(shù)字后連接數(shù)字.
                          if (number.charAt(0== '0' && isFloat != 2)// 如果不是浮點,
                              number.deleteCharAt(0);// 但以0開頭就刪去.這種方法不優(yōu)雅,但想不出更好的.
                      }
                      text 
          = number;// 只要輸入數(shù)字,無條件地顯示.
                  } else if (cmd == ".") {
                      
          if (isExcp)
                          
          return;
                      
          if (isFloat == 0)// 如果不是浮點型
                          isFloat = 1;// 待浮點型.
                  } else if (cmd == "+/-") {
                      
          if (isZero || isExcp)// 清空狀態(tài)或異常.
                          return;
                      
          if (isNeg) {// 如果是負(fù)數(shù)就變?yōu)檎龜?shù),如果是正數(shù)就變?yōu)樨?fù)數(shù).
                          isNeg = false;
                          number.deleteCharAt(
          0);// delete和insert操作可以推遲到完成數(shù)字輸入狀態(tài)后,根據(jù)isNeg來判斷更好.
                      } else {
                          isNeg 
          = true;
                          number.insert(
          0'-');
                      }
                      text 
          = number;
                  }
                  
          // 雙目運算功能
                  else if (cmd == "+" || cmd == "-" || cmd == "*" || cmd == "/") {
                      
          if (isExcp)
                          
          return;
                      
          if (isRightInput == 0)
                          isRightInput 
          = 1;// 變?yōu)榇淮斡行в逸斎霠顟B(tài).
                      if (isRightInput == 2) {// 如果已經(jīng)是一次有效右輸入了.就相當(dāng)于'='.比如1+2+的時候.
                          rightOper = Double.parseDouble(number.toString());// 當(dāng)前的number給右數(shù).
                          try {
                              result 
          = Util.calculate(leftOper, rightOper, operator);// 根據(jù)三個變量計算。如果/時右數(shù)為0,就拋異常.
                          } catch (ArithmeticException ae) {
                              isExcp 
          = true;
                              
          if (leftOper == 0)// 左數(shù),右數(shù)同時為0時.
                                  text = new StringBuilder("函數(shù)結(jié)果未定義。");
                              
          else
                                  text 
          = new StringBuilder("除數(shù)不能為零。");
                          }
                          rightOper 
          = leftOper = result;// 把得到的結(jié)果給左數(shù),同時也給右數(shù).
                          text = new StringBuilder(String.valueOf(result));
                          isZero 
          = true;
                          isRightInput 
          = 1;// 直接就是1狀態(tài).不經(jīng)過0
                      }
                      
          if (operator == 0)// 如果運算符沒有.如:1+
                          rightOper = leftOper = Double.parseDouble(number.toString());// 左數(shù)和右數(shù)均賦值.
                      
          // 據(jù)cmd初始化operator.此步一定進(jìn)行,不管是運算符功能還是=功能.
                      if (cmd == "+")// 很無奈的是不能用switch.enum太繁.
                          operator = 1;
                      
          else if (cmd == "-")
                          operator 
          = 2;
                      
          else if (cmd == "*")
                          operator 
          = 3;
                      
          else
                          operator 
          = 4;
                      isZero 
          = true;
                  }
                  
          // 單目運算
                  else if (cmd == "sqrt") {
                      
          if (isExcp)
                          
          return;
                      
          double dnum = Double.parseDouble(number.toString());
                      
          if (dnum < 0) {// 如果當(dāng)前數(shù)為負(fù),就錯誤.
                          isExcp = true;
                          text 
          = new StringBuilder("函數(shù)輸入無效。");
                      } 
          else {
                          result 
          = Math.sqrt(dnum);
                          number 
          = text = new StringBuilder(String.valueOf(result));
                          
          if (operator == 0)// 有運算符必賦值給右數(shù).
                              leftOper = result;
                          
          else {
                              rightOper 
          = result;
                          }
                          isZero 
          = true;
                      }
                  } 
          else if (cmd == "%") {
                      
          if (isExcp)
                          
          return;
                      
          double dnum = Double.parseDouble(number.toString());
                      result 
          = leftOper * dnum / 100;// 這種規(guī)則讓人很難適應(yīng),有點小變態(tài).
                      number = text = new StringBuilder(String.valueOf(result));
                      
          if (operator == 0)
                          leftOper 
          = result;
                      
          else {
                          rightOper 
          = result;
                      }
                      isZero 
          = true;
                  } 
          else if (cmd == "1/x") {
                      
          if (isExcp)
                          
          return;
                      
          double dnum = Double.parseDouble(number.toString());
                      
          if (dnum == 0) {
                          isExcp 
          = true;
                          text 
          = new StringBuilder("除數(shù)不能為零。");
                      } 
          else {
                          result 
          = 1 / Double.parseDouble(number.toString());
                          number 
          = text = new StringBuilder(String.valueOf(result));
                          
          if (operator == 0)
                              leftOper 
          = result;
                          
          else {
                              rightOper 
          = result;
                          }
                          isZero 
          = true;
                      }
                  } 
          else if (e.getActionCommand() == "=") {
                      
          if (isExcp)
                          
          return;
                      
          double dnum = Double.parseDouble(number.toString());
                      
          if (isRightInput == 2) {// 一次有效的右輸入.如1+2=-2.如1+2=3=.就不響應(yīng)3.
                          rightOper = dnum;// 當(dāng)前數(shù)賦給右數(shù).
                          isRightInput = 0;// =號破壞一次右輸入,必須得以+-*/開頭,后接數(shù)字
                      }
                      
          if (operator != 0) {// 1+2=
                          try {
                              result 
          = Util.calculate(leftOper, rightOper, operator);
                          } 
          catch (ArithmeticException ae) {
                              isExcp 
          = true;
                              
          if (leftOper == 0)// 左數(shù),右數(shù)同時為0時.
                                  text = new StringBuilder("函數(shù)結(jié)果未定義。");
                              
          else
                                  text 
          = new StringBuilder("除數(shù)不能為零。");
                          }
                          leftOper 
          = result;
                      } 
          else
                          
          // 1=
                          result = dnum;
                      text 
          = new StringBuilder(String.valueOf(result));
                      isZero 
          = true;
                  } 
          else if (e.getActionCommand() == "關(guān)于計算器") {
                      String temp 
          = "java模擬windows高模仿實用計算器.\n蕎葉制作.qq:494053175 \n blog:sina wangflood";
                      JOptionPane.showMessageDialog(
          null, temp, "關(guān)于計算器",
                              JOptionPane.INFORMATION_MESSAGE);
                  }
                  
          // BackSpace功能
                  else if (cmd == "Backspace") {
                      
          if (isExcp)
                          
          return;
                      
          if ((!isNeg && number.length() < 2)// 正數(shù)剩一位時,負(fù)數(shù)剩二位時.直接跳到0
                              || (isNeg && number.length() < 3)) {
                          isZero 
          = true;
                          number 
          = new StringBuilder("0");
                      } 
          else
                          number 
          = number.deleteCharAt(number.length() - 1);// 每次刪除最后一位.
                      text = number;
                  } 
          else if (cmd == "CE") {
                      isZero 
          = true;
                      isExcp 
          = false;// 清異常.
                      text = number;
                  } 
          else if (cmd == "C") {
                      operator 
          = 0;// 清運算符.
                      isZero = true;
                      leftOper 
          = 0;// 清左數(shù)
                      rightOper = 0;// 清右數(shù).
                      result = 0;// 清結(jié)果.
                      number = text = new StringBuilder("0");// 清當(dāng)前數(shù)
                      isExcp = false;// 清異常
                      isRightInput = 0;// 清一次有效右輸入.
                  } else if (cmd == "MC") {
                      
          if (isExcp)// 同樣也響應(yīng)不了.異常的時候.
                          return;
                      m 
          = new StringBuilder("0");

                  } 
          else if (cmd == "MR") {// 顯示存儲數(shù)到display.
                      if (isExcp)
                          
          return;
                      isRightInput 
          = 2;
                      number 
          = text = m;
                  } 
          else if (cmd == "MS") {
                      
          if (isExcp)
                          
          return;
                      m 
          = number;// 將當(dāng)前數(shù)賦給m.
                  } else if (cmd == "M+") {// 當(dāng)前數(shù)與m相加賦給m
                      if (isExcp)
                          
          return;
                      m 
          = new StringBuilder(String.valueOf((Double.parseDouble(m
                              .toString()) 
          + Double.parseDouble(number.toString()))));
                  } 
          else {// 一般不給出現(xiàn)這種情況.我們都會上天堂的.
                      System.out.println("歡迎來到地獄!");
                  }

                  
          // 按任何鍵都會觸發(fā)的.
                  tftext.setText(text.toString());
                  
          if (m.length() != 0)// m不空的話就顯示M
                      tfm.setText("M");
                  
          else
                      tfm.setText(
          "");
                  
          if (isZero) {// 為清空狀態(tài).浮點狀態(tài)和負(fù)數(shù)狀態(tài)回到默認(rèn).
                      isFloat = 0;
                      isNeg 
          = false;
                  }
              }

              
          private void initDisplay() {
                  tftext.setHorizontalAlignment(JTextField.RIGHT);
                  pdisplay.add(tftext);
                  tftext.setText(
          "0.");
                  tfm.setHorizontalAlignment(JTextField.CENTER);
                  tfm.setEditable(
          false);
                  pm.add(tfm);
              }

              
          private void initPbcm() {
                  
          // 生成按鈕
                  for (int i = 0; i < 27; i++) {
                      jb[i] 
          = new JButton(strB[i]);

                  }

                  
          for (int i = 0; i < 4; i++) {
                      jb[i].addActionListener(
          this);
                      pm.add(jb[i]);
                  }
                  
          for (int i = 4; i < 7; i++) {
                      jb[i].addActionListener(
          this);
                      pc.add(jb[i]);
                  }

                  
          for (int i = 7; i < 27; i++) {
                      jb[i].addActionListener(
          this);
                      pb.add(jb[i]);
                  }
                  pbc.add(pc, BorderLayout.NORTH);
                  pbc.add(pb, BorderLayout.CENTER);
                  pbcm.add(pm);
                  pbcm.add(pbc);
              }

              
          private void addMenu() {
                  
          this.setMenuBar(myMenuBar);
                  
          // 以下是編輯菜單項
                  Menu editMenu = new Menu("編輯");
                  myMenuBar.add(editMenu);

                  MenuItem menuitemcopy 
          = new MenuItem("復(fù)制");
                  MenuItem menuitemplaste 
          = new MenuItem("粘貼");
                  MenuItem menuitemload 
          = new MenuItem("用戶登錄");
                  editMenu.add(menuitemload);
                  editMenu.add(menuitemcopy);
                  editMenu.add(menuitemplaste);

                  menuitemload.addActionListener(
          this);
                  menuitemcopy.addActionListener(
          this);
                  menuitemplaste.addActionListener(
          this);

                  
          // 以下是編輯菜單項
                  Menu watchMenu = new Menu("查看");
                  myMenuBar.add(watchMenu);

                  MenuItem menuitemstandard 
          = new MenuItem("標(biāo)準(zhǔn)型");
                  MenuItem menuitemsencien 
          = new MenuItem("科學(xué)型");

                  watchMenu.add(menuitemstandard);
                  watchMenu.add(menuitemsencien);
                  watchMenu.addSeparator();
                  watchMenu.add(
          new MenuItem("數(shù)字分組"));

                  menuitemstandard.addActionListener(
          this);
                  menuitemsencien.addActionListener(
          this);

                  
          // 以下是幫助菜單項
                  Menu helpMenu = new Menu("幫助");
                  myMenuBar.add(helpMenu);

                  CheckboxMenuItem menuitemhelp 
          = new CheckboxMenuItem("幫助主題"false);
                  MenuItem menuitemaboutcal 
          = new MenuItem("關(guān)于計算器");

                  helpMenu.add(menuitemhelp);
                  helpMenu.addSeparator();
                  helpMenu.add(menuitemaboutcal);

                  menuitemhelp.addActionListener(
          this);
                  menuitemaboutcal.addActionListener(
          this);

              }

              
          public static void main(String[] args) {
                  
          new Cal();
              }

          }


          Util.java輔助類
          package wang.window.impl;

          public class Util {
              
          /** DoubleString格式化顯示.如果有小數(shù)點,只對小數(shù)點前面進(jìn)行格式化. */
              
          private String DoubleFormat(String str) {
                  StringBuilder sb 
          = new StringBuilder();

                  
          int length = str.length();
                  
          int left = length % 3;
                  
          int count = 0;
                  
          if (left == 0)
                      left 
          = 3;
                  String tail 
          = "";
                  
          if (str.contains(".")) {
                      
          int index = str.indexOf('.');
                      tail 
          = str.substring(index);
                      str 
          = str.substring(0, index);
                  }

                  
          for (int i = 0; i < str.length(); i++) {

                      
          if (i == left)
                          sb.append(
          ",");
                      
          else if (i > left) {
                          count
          ++;
                          
          if (count % 3 == 0)
                              sb.append(
          ",");

                      }

                      sb.append(str.charAt(i));

                  }
                  sb.append(tail);
                  
          return sb.toString();
              }

              
          private void display() {
              }

              
          /** 根據(jù)兩double類型的操作數(shù),和操作符,計算后返回double類型結(jié)果 */
              
          public static double calculate(double leftOper, double rightOper,
                      
          int operator) {
                  
          double result = 0;
                  
          switch (operator) {
                  
          case 1:
                      result 
          = leftOper + rightOper;
                      
          break;
                  
          case 2:
                      result 
          = leftOper - rightOper;
                      
          break;
                  
          case 3:
                      result 
          = leftOper * rightOper;
                      
          break;
                  
          case 4:
                      
          if (leftOper == 0)
                          
          throw new ArithmeticException();
                      result 
          = leftOper / rightOper;

                      
          break;
                  
          default:
                      System.out.println(
          "歡迎來到地獄!");
                      
          break;
                  }
                  
          return result;

              }

              
          public String format(int isfloat, boolean isNeg, StringBuilder text) {
                  
          int start = 0;//.前一個位置
                  int end;//-后一個位置
                  int count = 0;//計數(shù)
                  if (isfloat != 2)
                      start 
          = text.length() - 1;//java里數(shù)組的長度不用掃描?
                  if (isNeg)
                      end 
          = 1;
                  
          else
                      end 
          = 0;
                  StringBuilder sb 
          = new StringBuilder();
                  
          for (int i = text.length() - 1; i >= 0; i++) {
                      
          char temp = text.charAt(i);
                      
          if (isfloat == 2) {
                          
          if (temp == '.')
                              start 
          = i - 1;
                      }
                      
          if (i == start && i <= end) {
                          
          if (count == 2)
                              sb.append(
          ",");//插入,的條件
                          count = (count + 1% 3;
                      }
                      sb.append(temp);
                  }
                  
          return sb.reverse().toString();//逆序
              }
          }

          運行界面:

          有些地方還沒有完善。高手飄過,探討改進(jìn)啊。
          posted on 2010-11-13 08:03 wangflood 閱讀(945) 評論(0)  編輯  收藏 所屬分類: java
          主站蜘蛛池模板: 黄大仙区| 荔波县| 隆回县| 六枝特区| 红安县| 宜阳县| 利川市| 新余市| 托克逊县| 镇雄县| 长兴县| 抚顺县| 筠连县| 平舆县| 兴业县| 玉门市| 邓州市| 黄冈市| 砚山县| 阿克苏市| 柳林县| 黄浦区| 望奎县| 普兰店市| 阿拉善右旗| 榆社县| 容城县| 塔城市| 油尖旺区| 合阳县| 紫金县| 涿州市| 南皮县| 江口县| 金坛市| 九龙坡区| 乌审旗| 祥云县| 永和县| 大余县| 玉门市|