import java.lang.*; import java.util.*; import java.awt.event.*; public class CalculatorController implements ActionListener { private Calculator calculator; private CalculatorModel model; private final int CLEARED = 0; private final int INTEGER_V = 1; private final int FLOAT_V = 2; private final int ERROR = 3; private StringBuffer acc; private int state = CLEARED; private boolean neg = false; CalculatorController( Calculator c, CalculatorModel m ) { calculator = c; model = m; clearEntry(); } public void actionPerformed( ActionEvent e ) { String eStr = e.getActionCommand(); int eType = Integer.parseInt( eStr ); if ( state == ERROR ) { // El único modo de salvar el error es un CLEAR general if ( eType == Calculator.I_C ) { reset(); } else return; } if ( eType == Calculator.I_CE ) clearEntry(); else if ( eType == Calculator.I_C ) reset(); else { switch ( state ) { case CLEARED: if ( Calculator.isDigit( eType ) ) { state = INTEGER_V; acc.append( eStr ); } else if ( Calculator.isOp( eType )) doOp( eType ); else if ( eType == Calculator.I_POINT ) { state = FLOAT_V; acc.append ( "0." ); } else error(); break; case INTEGER_V: if ( Calculator.isDigit( eType ) ) { acc.append( eStr ); } else if ( Calculator.isOp( eType )) doOp( eType ); else { switch ( eType ) { case Calculator.I_SIGN: neg = !neg; break; case Calculator.I_POINT: state = FLOAT_V; acc.append( "." ); break; default: state = ERROR; break; } } break; case FLOAT_V: if ( Calculator.isDigit( eType )) { acc.append( eStr ); } else if ( Calculator.isOp( eType )) doOp( eType ); else { switch ( eType ) { case Calculator.I_SIGN: neg = !neg; break; default: error(); break; } } break; } } if (acc.length() == 0) { calculator.setDisplay(Calculator.EMPTYSTR); } else if (neg) calculator.setDisplay("-" + acc.toString()); else calculator.setDisplay(acc.toString()); } private void doOp( int eT ) { if ( eT == Calculator.I_POP ) { try { setAcc( model.pop() ); } catch ( EmptyStackException e ) { error(); } } else if ( eT == Calculator.I_PUSH ) { if ( state == CLEARED ) error(); else doPush(); } else { try { if ( state != CLEARED ) doPush(); switch( eT ) { case Calculator.I_DIV: setAcc( model.div() ); break; case Calculator.I_MUL: setAcc( model.mul() ); break; case Calculator.I_SUB: setAcc( model.sub() ); break; case Calculator.I_ADD: setAcc( model.add() ); break; } } catch ( EmptyStackException e ) { error(); } } } private void doPush() { double d = 0.0; try{ d = Double.parseDouble(acc.toString()); } catch ( NumberFormatException e ) { error(); } if ( neg ) d = -d; model.push( d ); clearEntry(); } private void setAcc( double d ) { state = FLOAT_V; acc = new StringBuffer(); acc.append( Math.abs( d ) ); neg = ( d >= 0.0 ) ? false : true; } private void clearEntry() { state = CLEARED; acc = new StringBuffer(); calculator.clearDisplay(); neg = false; } private void reset() { model.clear(); clearEntry(); } private void error() { state = ERROR; neg = false; acc = new StringBuffer( "ERROR" ); } }