next up previous contents index
Next: Limitations and Conclusion Up: Examples Previous: Stable pair-matching

Building a Calculator

Now, let us consider how to build the calculator depicted in Figure [*]. This example illustrates how to use the grid constraint.


  
Figure: A Calculator.
\begin{figure}
\begin{center}
\epsfile{file=calculator.ps,width=5cm}\end{center}\end{figure}

The calculator is composed of a display and a board with many buttons. The display is simply a text field which is already available as a base class. Therefore, we only need to get the Board class ready to build a calculator.

The following shows the class for building the board:

       Class Board {
             dj Button b[9]; // Buttons "0",...,"9"
             dj    Button bc {text == "C"};
             ... // Buttons "+","-","*","/",".","="

             for (i in 0..9) b[i].text == String(i);
             grid({{bc,bdiv,bmul,bsub},
                  {b[7],b[8],  b[9],  badd},
                  {b[4],b[5],  b[6],  badd},
                  {b[1],b[2],  b[3],  beq },
                  {b[0],b[0],  bpoint,beq}});
       }
The for statement constrains the values for the text attributes of the digit buttons. The expression String(i) translates an integer i into a string. The grid constraint constrains the positions for the buttons. Notice that a component may spread over several grids.

To have a working caculator, we need to associate actions with the buttons. The following class Calculator class has a board and a text field that serves as the display of the calculator.

class Calculator {
        double acc = 0;
        char op = ' ';
        boolean firstDigit = true;
    
    dj TextField tf{text=="0";columns==20};
    dj Board bd;

// constraints 
    above(tf,bd);
    sameCenterX(tf,bd);

// actions
    for (i in 0..9) command(bd.b[i],inputDigit(char(i)));
    command(bd.bc,clear());
    command(bd.badd,inputOp('+'));
    command(bd.bsub,inputOp('-'));
    command(bd.bmul,inputOp('*'));
    command(bd.bdiv,inputOp('/'));
    command(bd.beq,inputOp('='));
    command(bd.bpoint,inputPoint());

    void inputZero(){
    if ((tf.getText()).compareTo("0")!=0)
        inputDigit('0');
    }

    void inputDigit(char d){
    if (firstDigit){
        tf.setText(String.valueOf(d));
        if (d!='0') firstDigit = false;
    } else {
        tf.setText(tf.getText()+d);
    }
    }

    void clear(){
    tf.setText("0");
    firstDigit=true;
    acc = 0.0;
    op = ' ';
    }

    void inputOp(char operator){
    compute(op);
    op = operator;
    }

   void inputPoint(){
    if (!hasPoint(tf.getText())){
        tf.setText(tf.getText()+".");
        }
    }

    void compute(char operator){
    double newValue;
    newValue = (Double.valueOf(tf.getText())).doubleValue();
    switch (operator){
       case '+' : acc += newValue;break;
       case '-' : acc -= newValue;break;
       case '*' : acc *= newValue;break;
       case '/' : acc /= newValue;break;
        default : acc = newValue;
    }
        tf.setText(Double.toString(acc));
    firstDigit = true;
   }
   boolean hasPoint(String s){
    for (int i=0;i<s.length();i++){
            if ((s.charAt(i))=='.') return true;
    }
    return false;
   }
}



Neng-Fa Zhou
1999-02-16