2015-07-09 146 views
0

我使用Java swing庫構建計算器。除了actionEvent循環中的乘法和除法運算符外,其他所有工作都是有效的。所有其他操作員完全工作。Java計算器運算符錯誤

這是發生錯誤: 我曾嘗試在代碼

計算器的這一部分try語句:

enter image description here

計算器乘法錯誤:

  1. 首先你輸入號碼

  2. 然後按該假設以清除文本框操作員 - 錯誤發生在此步驟

  3. 然後就進入第二數目

  4. 然後按=按鈕輸出答案

Enter Number enter image description here enter image description here enter image description here

圖片錯誤的:

if(e.equals("*")) 
{ 
     fnum = txt.getText(); 
     logic.setTotal(fnum); 
     op = "*"; 
     txt.setText(""); // error occurs here, textfield isn't cleared 
     JOptionPane.showMessageDialog(null, fnum); //messagebox to see if fnum contains the string from the textfield 
} 
if(e.equals("/")) 
{ 
     fnum = txt.getText(); 
     op = "/"; 
     txt.setText(""); 
} 

動作事件循環/功能:

public void actionPerformed(ActionEvent ea) 
{ 
    else if(op.equals("*")) 
    { 
     logic.setTotal(fnum); 
     logic.multiplication(snum); 
     total1 = logic.total; 
    } 
    else if(op.equals("/")) 
    { 
     logic.setTotal(fnum); 
     logic.divide(snum); 
     total1 = logic.total; 
    } 
    txt.setText(""+total1); 
} 

邏輯是內部類

內部類:

public class Inner extends Calculators{ 
    public double total; 
    public Inner() 
    { 
     total = 0; 
    } 
    public void setTotal(String n) 
    { 
     total = convertToNumber(n); 
    } 
    public void divide(String n) 
    { 
     total /= convertToNumber(n); 
    } 
    public void multiplication(String n) 
    { 
     total *=convertToNumber(n); 
    } 
} 

如果你感到困惑,請索要更多的代碼,因爲我不能包含所有的代碼。

Code if you want to try it out yourself

+2

這讓我很擔心:公共類Inner擴展計算器{'。爲什麼內在擴展計算器?這表明濫用繼承權。否則,如果沒有[最小示例程序](http://stackoverflow.com/help/mcve),就很難回答你的問題。 –

+0

內部類使用Calculator方法和變量,因爲它是Calculator的「子類」。我無法添加所有的代碼,因爲它非常廣泛。 –

+0

你看到什麼特別的錯誤?發生錯誤時該類的代碼將會很有幫助。 – MaxZoom

回答

3

您是在首先創建你這樣的按鈕:

... 
    JButton plus = new JButton("+"); 
    JButton multiplication = new JButton("*"); 
    JButton divide = new JButton("/"); 
    JButton minus = new JButton("-"); 
    ... 

,然後加入this爲動作偵聽器。但是一些線條缺失:

... 
    plus.addActionListener(this); 
    // missing: multiplication.addActionListener(this); 
    // missing: divide.addActionListener(this); 
    minus.addActionListener(this); 
    ... 

我怎麼發現的bug:

  1. 下載的代碼,編譯等
  2. 然的代碼,試圖加法,乘法等(檢查應用程序的行爲)。這是一種黑盒測試
  3. 查找區別之間的加法和乘法通過分析代碼。這與白盒測試有關。
  4. 我看到了,應該調用JOptionPane.showMessageDialog(null, fnum); - 但還沒有被調用。所以我坐着中斷點(在eclipse中)調試
  5. 當我意識到,actionPerformed方法尚未在I處被調用時,我搜索了註冊ActionListeners的代碼行。

除此之外:我強烈推薦重構你的代碼。您可以從重新思考代碼結構中受益。您將獲得更好的可讀性,代碼將更易於維護,新功能可以更快地實現。

我會建議:

  • 降低您的領域的知名度。讓你的領域private,這樣你可以很容易地找到所有對他們的引用。
  • 避免重複(稱爲不要重複自己技術)。例如:與其說addActionListener每個按鈕的製作按鈕(即ArrayList<JButton>的收集和使用for循環調用addActionListener爲他們中的每一個
  • 也避免重複的代碼片段,通過定義更多,但更短的方法
  • 考慮刪除您Calculators類,並直接把這些代碼進入Inner的方法。
  • Inner找到一個更有意義的名稱,也許IntermediateResult或相似。
  • 創建一個單獨ActionListener每個按鈕的實例。這將花費的性能(不是由人類noticable)一點點,但會避免長時間if -chains
  • 發佈您的代碼上代碼審查(在StackExchange網絡)爲獲得更多的幫助和新思路
+0

非常感謝您對此的幫助。非常好的答案! –

3

只是一個側面推薦,其中一個與您的主要問題無關,這就是爲什麼我將此發佈爲社區維基,而不是作爲答案:避免不惜一切代價使用空佈局。當然,null佈局和setBounds(...)對於Swing新手來說似乎是創建複雜GUI的最簡單和最好的方法,但更多Swing GUI的創建使用它們時會遇到更嚴重的困難。它們不會在GUI大小調整時調整組件的大小,它們是增強或維護的皇室女巫,當它們放在滾動窗格中時它們會完全失敗,在所有平臺或屏幕分辨率與原始視圖不同時,它們看起來會非常糟糕。例如,如果您使用佈局的智能組合,則您的GUI將能夠自行組裝,更靈活,如果您決定更改按鈕位置或添加新按鈕。例如:

import java.awt.BorderLayout; 
import java.awt.GridLayout; 
import javax.swing.*; 

public class Calc2 extends JPanel { 
    private static final String[][] INITIAL_BTNS = { 
     {"1", "2", "3", "+"}, 
     {"4", "5", "6", "-"}, 
     {"7", "8", "9", "*"}, 
     {"C", "0", ".", "/"}, 
     {"1/x", "\u221A", "Ln", "="} 
    }; 
    private static final String[][] EXTRA_BTNS = { 
     {"sin", "cos", "tan"}, 
     {"csc", "sec", "cot"} 
    }; 
    private static final int GAP = 5; 

    private JTextField displayField = new JTextField(10); 

    public Calc2() { 
     int rows = INITIAL_BTNS.length; 
     int cols = INITIAL_BTNS[0].length; 
     JPanel initialBtnPanel = new JPanel(new GridLayout(rows, cols, GAP, GAP)); 
     rows = EXTRA_BTNS.length; 
     cols = EXTRA_BTNS[0].length; 
     JPanel extraBtnPanel = new JPanel(new GridLayout(rows, cols, GAP, GAP)); 

     JPanel combinedBtnPanel = new JPanel(); 
     combinedBtnPanel.setLayout(new BoxLayout(combinedBtnPanel, BoxLayout.PAGE_AXIS)); 
     combinedBtnPanel.add(initialBtnPanel); 
     combinedBtnPanel.add(Box.createVerticalStrut(GAP)); 
     combinedBtnPanel.add(extraBtnPanel); 

     for (int r = 0; r < INITIAL_BTNS.length; r++) { 
     for (int c = 0; c < INITIAL_BTNS[r].length; c++) { 
      JButton button = new JButton(INITIAL_BTNS[r][c]); 
      initialBtnPanel.add(button); 
      // add action here 
     } 
     } 

     for (int r = 0; r < EXTRA_BTNS.length; r++) { 
     for (int c = 0; c < EXTRA_BTNS[r].length; c++) { 
      JButton button = new JButton(EXTRA_BTNS[r][c]); 
      extraBtnPanel.add(button); 
      // add action here 
     } 
     } 

     setLayout(new BorderLayout(GAP, GAP)); 
     setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP)); 

     add(displayField, BorderLayout.PAGE_START); 
     add(combinedBtnPanel, BorderLayout.CENTER); 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("Calculator"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new Calc2()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

其中顯示爲:

enter image description here

如果以後你決定3個按鍵增加了額外的按鈕部分的頂部,所有你需要我的代碼做是添加一行代碼(不計算所需的邏輯代碼變化,這將是你我相同),並改變此:

private static final String[][] EXTRA_BTNS = { 
     {"sin", "cos", "tan"}, 
     {"csc", "sec", "cot"} 
    }; 

這樣:

private static final String[][] EXTRA_BTNS = { 
     {"foo", "bar", "baz"}, 
     {"sin", "cos", "tan"}, 
     {"csc", "sec", "cot"} 
    }; 

會有無需手動更改所有其他鍵的位置或手動重新大小的JFrame的,因爲佈局管理器將照顧這對你和GUI將顯示爲:

enter image description here

+1

我認爲我們的答案是完美互補的。這是定義和佈置按鈕的好方法! – slartidan

+0

你會如何建議爲示例代碼添加ActionListeners? – slartidan

+1

@slartidan:我可以創建3個或更多的AbstractAction類,一個用於數字和'.'按鈕,一個用於基本操作按鈕,另一個用於複雜操作按鈕。我會使用Map將String與Action關聯起來,然後在for循環中使用Map來爲按鈕獲取適當的Action。 –