2015-07-09 167 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。 –