2015-07-12 18 views
3

这是一个简单的计算器,用户可以输入计算结果并点击输入,计算器将确定它是否是有效计算。如果它是有效的计算,则执行计算。如果不是,则将错误消息写入屏幕。如何解决简单计算器的字符串版本计算?

calculation is carried out部分尚未完成。

有人可以建议解决方案的getAnswer()方法。

这将非常感激。

import java.awt.ComponentOrientation; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.BoxLayout; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.border.EmptyBorder; 


@SuppressWarnings("serial") 
public class Calculator extends JFrame{ 

    private interface CalculatorInterface { 
     public void writeToScreen(String text); 
     public void clearScreen(); 
     public String getScreenText(); 
    } 

    private class CalculatorPanel extends JPanel implements CalculatorInterface { 

     private class NumberPanel extends JPanel implements CalculatorInterface { 

      private static final int NUMTOTAL = 10; 

      private CalculatorPanel calcPanel; 
      private JButton[] numButtons; 

      public NumberPanel(CalculatorPanel calcPanel) { 
       this.calcPanel = calcPanel; 
       buildLayout(); 
       addButtons(); 
      } 
      private void buildLayout() { 
       this.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); 

       GridLayout layout = new GridLayout(4,3); 
       layout.setHgap(1); 
       layout.setVgap(1); 

       this.setLayout(new GridLayout(4,3)); 

      } 
      private void addButtons() { 
       numButtons = new JButton[NUMTOTAL]; 

       for(int i = numButtons.length -1; i >= 0 ; i--) { 
        numButtons[i] = new JButton("" + i); 
        numButtons[i].setPreferredSize(new Dimension(60,40)); 
        numButtons[i].setFont(new Font("Sans serif", Font.PLAIN, 18)); 
        numButtons[i].addActionListener(
          new ActionListener() { 
           @Override 
           public void actionPerformed(ActionEvent e) { 
            String text = ((JButton)e.getSource()).getText().trim(); 
            if(getScreenText().equals("Invalid Calc")) { 
             clearScreen(); 
             writeToScreen(text); 
            }else { 
             writeToScreen(text); 
            }  
           } 
          }); 
        this.add(numButtons[i]); 
       } 
      } 
      @Override 
      public void writeToScreen(String text) { 
       calcPanel.writeToScreen(text); 
      } 
      @Override 
      public void clearScreen() { 
       calcPanel.clearScreen(); 

      } 
      @Override 
      public String getScreenText() { 
       return calcPanel.getScreenText(); 
      } 

     } 

     private class OperPanel extends JPanel implements CalculatorInterface { 

      private static final int ADD = 0; 
      private static final int SUB = 1; 
      private static final int MULT = 2; 
      private static final int DIV = 3; 
      private static final int OPENB = 4; 
      private static final int CLOSEB = 5; 
      private static final int CLEAR = 6; 
      private static final int EQL = 7; 


      private static final int OPERTOTAL = 8; 

      private CalculatorPanel calcPanel; 
      private JButton[] operButtons; 

      public OperPanel(CalculatorPanel calcPanel) { 
       this.calcPanel = calcPanel; 
       buildLayout(); 
       addButtons(); 
      } 

      private void buildLayout() { 
       GridLayout layout = new GridLayout(4,1); 
       layout.setHgap(1); 
       layout.setVgap(1); 

       this.setLayout(new GridLayout(4,1)); 
      } 

      private void addButtons() { 
       operButtons = new JButton[OPERTOTAL]; 

       operButtons[ADD] = makeButton(ADD, "+"); 
       operButtons[SUB] = makeButton(SUB, "-"); 
       operButtons[MULT] = makeButton(MULT, "*"); 
       operButtons[DIV] = makeButton(DIV, "/"); 
       operButtons[CLEAR] = makeButton(CLEAR, "CL"); 
       operButtons[EQL] = makeButton(EQL, "="); 
       operButtons[OPENB] = makeButton(OPENB, "("); 
       operButtons[CLOSEB] = makeButton(CLOSEB, ")"); 

       for(JButton button: operButtons) { 
        this.add(button); 
       } 
      } 

      private JButton makeButton(int index, String label) { 

       operButtons[index] = new JButton(label); 
       operButtons[index].addActionListener(
         new ActionListener() { 
          @Override 
          public void actionPerformed(ActionEvent e) { 
           String text = ((JButton)e.getSource()).getText(); 
           if(text.equals("=")) { 
            String screenText = getScreenText(); 
            clearScreen(); 
            try { 
             writeToScreen(getAnswer(screenText)); 
            }catch(Exception excep) { 
             writeToScreen("Invalid Calc"); 
            } 
           }else if(text.equals("CL")) { 
            clearScreen(); 
           }else { 
            writeToScreen(text); 
           } 
          }  
         }); 

       return operButtons[index];  
      } 


      private String getAnswer(String text) throws Exception { 
       /*I'm trying to solve for any input by the user e.g 
       *(the stuff in square brackets represents what is displayed 
       * on the screen:. 
       *[1+1] (hits equals) [2] 
       *[1+2-3] (hits equals) [0] 
       *[1+2*3] (hits equals) [7] 
       *[10*(14+1/2)] (hits equals) [145] 
       */ 
       throw new Exception(); 
      } 
      @Override 
      public String getScreenText() { 
       return calcPanel.getScreenText(); 
      } 

      @Override 
      public void clearScreen() { 
       calcPanel.clearScreen(); 

      } 

      @Override 
      public void writeToScreen(String text) { 
       calcPanel.writeToScreen(text); 

      } 

     } 


     private NumberPanel numPanel; 

     private OperPanel operPanel; 
     private JTextField calcScreen; 

     public CalculatorPanel(JTextField calcScreen) { 
      this.calcScreen = calcScreen; 

      buildNumPanel(); 
      buildOperPanel(); 

      buildCalcPanel(); 


     } 
     private void buildNumPanel() { 
      this.numPanel = new NumberPanel(this); 
     } 

     private void buildOperPanel() { 
      this.operPanel = new OperPanel(this); 
     } 

     private void buildCalcPanel() { 
      this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); 
      this.add(numPanel); 
      this.add(operPanel); 
     } 


     @Override 
     public void writeToScreen(String text) { 
      calcScreen.setText(getScreenText() + text);  
     } 

     @Override 
     public String getScreenText() { 
      return calcScreen.getText(); 
     } 

     @Override 
     public void clearScreen() { 
      calcScreen.setText(""); 
     } 
    } 

    private JPanel mainPanel; 
    private JTextField calcScreen; 

    private CalculatorPanel calcPanel; 
    public Calculator() { 
     buildScreen(); 

     buildCalcPanel(); 

     buildMainPanel(); 

     buildCalculator(); 
    } 

    private void buildScreen() { 
     this.calcScreen = new JTextField(); 
     this.calcScreen.setPreferredSize(new Dimension(150,50)); 
     this.calcScreen.setHorizontalAlignment(JTextField.CENTER); 
     this.calcScreen.setFont(new Font("Sans serif", Font.PLAIN, 30)); 

    } 

    private void buildCalcPanel() { 
     this.calcPanel = new CalculatorPanel(this.calcScreen); 
    } 

    private void buildMainPanel() { 
     this.mainPanel = new JPanel(); 
     this.mainPanel.setBorder(new EmptyBorder(10,10,10,10)); 
     this.mainPanel.setLayout(new BoxLayout(this.mainPanel, BoxLayout.Y_AXIS)); 

     this.mainPanel.add(calcScreen); 
     this.mainPanel.add(calcPanel); 
    } 

    private void buildCalculator() { 

     this.add(mainPanel); 
     this.setTitle("Calculator"); 
     this.pack();   
     this.setLocationRelativeTo(null); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setVisible(true); 
    } 

    public static void main(String[] args) { 
     @SuppressWarnings("unused") 
     Calculator calc = new Calculator(); 
    } 

} 

如何检查,看是否有字符串是一个简单的计算器一个有效的计算?

编辑1:修正了makeButton()方法中的一个愚蠢错误,我传入了要验证的按钮文本而不是屏幕上的文本。 (我是个笨蛋)

编辑2:从代码中删除了isValid(String text),并使其成为getAnswer()方法,如果输入不是有效的计算,就会引发异常。

+1

验证会很棘手,但我建议你首先解决最简单的情况:'1 + 1','5 + 4 + 21','5 * 1.2'。然后转向更复杂的方程,随时重构代码。我的早期解决方案首先是为操作员寻找,然后是操作数(数字)。根据我的理解,我最终开发了计算器,它将字符串输入转换成语法树,用于验证和计算;但是语法树对于这个问题可能是过度的。 – kevin628

+1

对于基本的算术运算符,您可以使用堆栈(如果有效,同时计算结果)执行此操作。 – celticminstrel

回答

3

除了在以前StackOverflow答案(Evaluating a math expression given in string form),你可以使用Javascript'sScriptEngine基于您将检索从文本字段的字符串来计算表达式提及。首先将它放在try-catch block中,查看表达式中是否有错误。在catch块中,设置变量是否存储有效表达式或不为false。

boolean validExpression = true; 

ScriptEngineManager mgr = new ScriptEngineManager(); 
ScriptEngine engine = mgr.getEngineByName("JavaScript"); 
String input = textField.getText() // Modify this to whatever variable you have assigned to your text field 

try { 
    System.out.println(engine.eval(foo)); 
} 
catch (ScriptException e) { 
    validExpression = false; 
    System.out.println("Invalid Expression"); 
} 

请确保您有以下进口:

import javax.script.ScriptEngineManager; 
import javax.script.ScriptEngine; 
import javax.script.ScriptException; 

虽然你可以尝试实施调度场算法或其他算法解析器,这是一个简单的方式更务实的解决方案。

+0

虽然这很好理解,但它是a)对用例的矫枉过正和b)没有帮助某人学习如何解析表达式。 – celticminstrel