Why does the click produce a 0 every time?

edited November 2013 in JavaScript Mode
/*************************************************************************
*  Basic Calculator: By Ken Kapptie | Copyright 2013                     *
*  Goal: to teach OOP to high school students while creating something   *
*        useful and highly customizable that runs on any OS.             *
*  TODO: 1. Employ response to keyboard digit entry that corresponds to  *
*           keypad or keyboard numeric data.                             *
*        2. Small graphing feature                                       *
*        3. Color themes with the click of a button                      *
**************************************************************************/

// Instantiate each of the classification of buttons
CalcButton[] numButtons = new CalcButton[10];
CalcButton[] opButtons = new CalcButton[6];
CalcButton[] spButtons = new CalcButton[1];

String displayValue;
String valueToCompute;  // string value left of operator 
String valueToCompute2; // string value right of operator 
float valueToComputeI;   // float value left of operator 
float valueToComputeI2;  // float value right of operator 
float result;
char opValue;
boolean firstNum;

void setup() {
  size(230,330);
  background(150);
  frameRate(10);

  // Populate number buttons
  numButtons[0] = new CalcButton(true, 0, 65, 275);
  numButtons[1] = new CalcButton(true, 1, 10, 220);
  numButtons[2] = new CalcButton(true, 2, 65, 220);
  numButtons[3] = new CalcButton(true, 3, 120, 220);
  numButtons[4] = new CalcButton(true, 4, 10, 165);
  numButtons[5] = new CalcButton(true, 5, 65, 165);
  numButtons[6] = new CalcButton(true, 6, 120, 165);
  numButtons[7] = new CalcButton(true, 7, 10, 110);
  numButtons[8] = new CalcButton(true, 8, 65, 110);
  numButtons[9] = new CalcButton(true, 9, 120, 110);


  // Populate operators
  opButtons[0] = new CalcButton("+", 175, 275);
  opButtons[1] = new CalcButton("-", 175, 220);
  opButtons[2] = new CalcButton("*", 175, 165);
  opButtons[3] = new CalcButton("/", 175, 110);
  opButtons[4] = new CalcButton("=", 120, 275);
  opButtons[5] = new CalcButton("C", 10, 55);

  // Populate special buttons
  spButtons[0] = new CalcButton(true, ".", 10, 275);

  // Set the initial value of first num to true
  firstNum = true;
}

void draw() {
  // Draw number buttons
  for(int i=0; i<numButtons.length; i++) {
    CalcButton inumButton = numButtons[i];
    inumButton.display();
    inumButton.clickButton();
    if(numButtons[i].overBox && mousePressed == true && firstNum == true) { 
        valueToCompute = valueToCompute + str(numButtons[i].numButtonValue);
        displayValue = valueToCompute;
        updateDisplay();
    } else if (numButtons[i].overBox && mousePressed == true && firstNum == false) {
      valueToCompute2 = valueToCompute2 + str(numButtons[i].numButtonValue);
        displayValue = valueToCompute2;
        updateDisplay();
    }
  }

  // Draw operator buttons
  /*for(int i=0; i<opButtons.length; i++){
    CalcButton iOpButton = opButtons[i];
    iOpButton.display();
    iOpButton.clickButton();
    if(opButtons[i].overBox && mousePressed == true) { 
      if(opButtons[i].opButtonValue == "C") {
        displayValue = "0";
        opValue = 'C';
        valueToCompute = "";
        valueToCompute2 = "";
        valueToComputeI = 0;
        valueToComputeI = 0;
        result = 0;
        firstNum = true;
        updateDisplay();
      } else if(opButtons[i].opButtonValue == "=") {
        // Perform calculation
        firstNum = true;
        performCalculation();
      } else if (opButtons[i].opButtonValue == "+"){
        opValue = '+';
        firstNum = false;
        displayValue = "+";
        updateDisplay();
      } else if (opButtons[i].opButtonValue == "-"){
        opValue = '-';
        firstNum = false;
        displayValue = "-";
        updateDisplay();
      } else if (opButtons[i].opButtonValue == "*"){
        opValue = '*';
        firstNum = false;
        displayValue = "*";
        updateDisplay();
      } else if (opButtons[i].opButtonValue == "/"){
        opValue = '/';
        firstNum = false;
        displayValue = "/";
        updateDisplay();
      }
    }
  }*/

  // Draw special buttons
  /*for (int i=0; i<spButtons.length; i++){
    CalcButton iSpButton = spButtons[i];
    iSpButton.display();
    iSpButton.clickButton();
    if(spButtons[i].overBox && mousePressed == true && firstNum == true) {
        valueToCompute = valueToCompute + spButtons[i].spButtonValue;
        displayValue = valueToCompute;
        updateDisplay();
    } else if (spButtons[i].overBox && mousePressed == true && firstNum == false) {
      valueToCompute2 = valueToCompute2 + spButtons[i].spButtonValue;
        displayValue = valueToCompute2;
        updateDisplay();
    }
  }*/
  updateDisplay();
}

void performCalculation() {
  // set string values to integers
  try {
    valueToComputeI = float(valueToCompute);
    valueToComputeI2 = float(valueToCompute2);
  } catch (Exception e) {
    displayValue = str(e);
    //displayValue = "Bad input, try again!";
  } 

  // perform calculation based on the appropriate operator
  try {
    if (opValue == '+') {
      result = valueToComputeI+valueToComputeI2;
    } else if (opValue == '-') {
      result = valueToComputeI-valueToComputeI2;
    } else if (opValue == '*') {
      result = valueToComputeI*valueToComputeI2;
    } else if (opValue == '/') {
      result = valueToComputeI/valueToComputeI2;
    }
    // change result back to string
    displayValue = str(result);
    // let = work multiple times
    valueToCompute = str(displayValue);
  } catch (Exception e) {
    displayValue = str(e);
  }
}

void updateDisplay() {
  fill(200,200,150);
  rect(10,10,210,35,7);
  fill(0);
  text(displayValue,20,37);
}

class CalcButton {
  // Class variables
  boolean isNumber;
  boolean isSpecial;
  float numButtonValue;
  String opButtonValue;
  String spButtonValue;
  float xpos;
  float ypos;
  int boxSize = 45;
  //int buttonW = 45;
  //int buttonH = 45;
  boolean overBox = false;

  // Constructor for number buttons
  CalcButton(boolean tempIsNumber, float tempNumButtonValue, float tempXpos, float tempYpos) {
    isNumber = tempIsNumber;
    numButtonValue = tempNumButtonValue;
    xpos = tempXpos;
    ypos = tempYpos;
  }

  // Constructor for operator buttons
  CalcButton(String tempOpButtonValue, float tempXpos, float tempYpos) {
    opButtonValue = tempOpButtonValue;
    xpos = tempXpos;
    ypos = tempYpos;
  }

  // Constructor for special buttons
  CalcButton(boolean tempIsSpecial, String tempSpButtonValue, float tempXpos, float tempYpos) {
    isSpecial = tempIsSpecial;
    spButtonValue = tempSpButtonValue;
    xpos = tempXpos;
    ypos = tempYpos;
  }

  // Draw the button on the canvas
  void display() {
    // Draw rounded edged button on canvas
    fill(50);
    stroke(0);
    rect(xpos, ypos, boxSize, boxSize, 10);
    fill(150);
    stroke(255);
    rect(xpos+2, ypos+2, boxSize-4, boxSize-4, 10);
    if(isNumber) {
      fill(0);
      textSize(24);
      text(numButtonValue, xpos+15, ypos+30);
    } else if (isSpecial) {
      fill(0);
      textSize(24);
      text(spButtonValue, xpos+15, ypos+30);
    } else {
      fill(0);
      textSize(24);
      text(opButtonValue, xpos+15, ypos+30);
    }
  }

  // Handle mouse actions
  void clickButton() {
    if (mouseX > xpos && mouseX < xpos+boxSize && mouseY > ypos && mouseY < ypos+boxSize) {
      overBox = true;
    } else {
      overBox = false;
    }
  }
}

Answers

  • I had to remove a number of str() and exception handling to run this in Java mode. str() doesn't throw exceptions! I also had to init displayValue to an empty string.

    After that, I could run your code, but with strange display (why numButtonValue is a float? Must be converted to int before display. Idem for digits displayed when I click the buttons. But the digits were corresponding to the buttons I clicked.

    So, perhaps it can be a good idea to be more precise in your question...

  • Here is the code with my fixes to make it work in Java mode:

    // Instantiate each of the classification of buttons
    CalcButton[] numButtons = new CalcButton[10];
    CalcButton[] opButtons = new CalcButton[6];
    CalcButton[] spButtons = new CalcButton[1];
    
    String displayValue = "";
    String valueToCompute = "";  // string value left of operator
    String valueToCompute2 = ""; // string value right of operator
    float valueToComputeI;   // float value left of operator
    float valueToComputeI2;  // float value right of operator
    float result;
    char opValue;
    boolean firstNum;
    
    void setup() {
      size(230,330);
      background(150);
      frameRate(10);
    
      // Populate number buttons
      numButtons[0] = new CalcButton(true, 0, 65, 275);
      numButtons[1] = new CalcButton(true, 1, 10, 220);
      numButtons[2] = new CalcButton(true, 2, 65, 220);
      numButtons[3] = new CalcButton(true, 3, 120, 220);
      numButtons[4] = new CalcButton(true, 4, 10, 165);
      numButtons[5] = new CalcButton(true, 5, 65, 165);
      numButtons[6] = new CalcButton(true, 6, 120, 165);
      numButtons[7] = new CalcButton(true, 7, 10, 110);
      numButtons[8] = new CalcButton(true, 8, 65, 110);
      numButtons[9] = new CalcButton(true, 9, 120, 110);
    
    
      // Populate operators
      opButtons[0] = new CalcButton("+", 175, 275);
      opButtons[1] = new CalcButton("-", 175, 220);
      opButtons[2] = new CalcButton("*", 175, 165);
      opButtons[3] = new CalcButton("/", 175, 110);
      opButtons[4] = new CalcButton("=", 120, 275);
      opButtons[5] = new CalcButton("C", 10, 55);
    
      // Populate special buttons
      spButtons[0] = new CalcButton(true, ".", 10, 275);
    
      // Set the initial value of first num to true
      firstNum = true;
    }
    
    void draw() {
      // Draw number buttons
      for (int i=0; i<numButtons.length; i++) {
        CalcButton inumButton = numButtons[i];
        inumButton.display();
        inumButton.clickButton();
        if (numButtons[i].overBox && mousePressed && firstNum) {
            valueToCompute += int(numButtons[i].numButtonValue);
            displayValue = valueToCompute;
            updateDisplay();
        } else if (numButtons[i].overBox && mousePressed && !firstNum) {
            valueToCompute2 += int(numButtons[i].numButtonValue);
            displayValue = valueToCompute2;
            updateDisplay();
        }
      }
    
      updateDisplay();
    }
    
    void performCalculation() {
      // set string values to integers
      valueToComputeI = float(valueToCompute);
      valueToComputeI2 = float(valueToCompute2);
    
      // perform calculation based on the appropriate operator
      if (opValue == '+') {
        result = valueToComputeI+valueToComputeI2;
      } else if (opValue == '-') {
        result = valueToComputeI-valueToComputeI2;
      } else if (opValue == '*') {
        result = valueToComputeI*valueToComputeI2;
      } else if (opValue == '/') {
        result = valueToComputeI/valueToComputeI2;
      }
      // change result back to string
      displayValue = str(result);
      // let = work multiple times
      valueToCompute = displayValue;
    }
    
    void updateDisplay() {
      fill(200,200,150);
      rect(10,10,210,35,7);
      fill(0);
      text(displayValue,20,37);
    }
    
    class CalcButton {
      // Class variables
      boolean isNumber;
      boolean isSpecial;
      float numButtonValue;
      String opButtonValue;
      String spButtonValue;
      float xpos;
      float ypos;
      int boxSize = 45;
      //int buttonW = 45;
      //int buttonH = 45;
      boolean overBox = false;
    
      // Constructor for number buttons
      CalcButton(boolean tempIsNumber, float tempNumButtonValue, float tempXpos, float tempYpos) {
        isNumber = tempIsNumber;
        numButtonValue = tempNumButtonValue;
        xpos = tempXpos;
        ypos = tempYpos;
      }
    
      // Constructor for operator buttons
      CalcButton(String tempOpButtonValue, float tempXpos, float tempYpos) {
        opButtonValue = tempOpButtonValue;
        xpos = tempXpos;
        ypos = tempYpos;
      }
    
      // Constructor for special buttons
      CalcButton(boolean tempIsSpecial, String tempSpButtonValue, float tempXpos, float tempYpos) {
        isSpecial = tempIsSpecial;
        spButtonValue = tempSpButtonValue;
        xpos = tempXpos;
        ypos = tempYpos;
      }
    
      // Draw the button on the canvas
      void display() {
        // Draw rounded edged button on canvas
        fill(50);
        stroke(0);
        rect(xpos, ypos, boxSize, boxSize, 10);
        fill(150);
        stroke(255);
        rect(xpos+2, ypos+2, boxSize-4, boxSize-4, 10);
        if(isNumber) {
          fill(0);
          textSize(24);
          text(int(numButtonValue), xpos+15, ypos+30);
        } else if (isSpecial) {
          fill(0);
          textSize(24);
          text(spButtonValue, xpos+15, ypos+30);
        } else {
          fill(0);
          textSize(24);
          text(opButtonValue, xpos+15, ypos+30);
        }
      }
    
      // Handle mouse actions
      void clickButton() {
        overBox = mouseX > xpos && mouseX < xpos+boxSize && mouseY > ypos && mouseY < ypos+boxSize;
      }
    }
    
  • Thanks for the conversion tips... the reason I posted in Javascript mode is because the number buttons always render as "0" in the display in this mode. Java mode works fine...

  • Well, the Java version had the problems I mentioned and that I fixed, but perhaps it is because I used v.2.1 while you might be on a lower version.

  • Puzzling...

    Current state of my researches: http://jsfiddle.net/PhiLho/z7GL8/1/ Still getting zeroes for numButtonValue!

    Not sure why.

  • I recall somebody mentioning that JS doesn't like overloaded functions, thus constructors. I suggest to use only one constructor (eg. with the coordinates), then assign the other values).

  • Very strange indeed! I know that JS doesn't have a char data-type. Trying to use 1 there, JS will consider as numerical!

  • I think this is it, the ''Constructor for number buttons'' is never called, only the Constructor for operator buttons is called. here: http://jsfiddle.net/z7GL8/5/

  • _vk_vk
    edited November 2013

    If the constructors have different parameters it works, for an idiot test I made two more ints in number constructor (not used at all, just to change the signature) and it worked. Probably Philho is correct. see

    http://jsfiddle.net/z7GL8/6/

  • Answer ✓

    Actually, there were constructors with different number of parameters, above, and they were not working. I tweaked them, without result. Looks like some cases can work? Even more puzzling.

    I went the safe way, making only one constructor, with modifiers depending on the kind of buttons to make. With the added bonus that is acts like named parameters, ie. it becomes explicit about the kind of button it creates.

    http://jsfiddle.net/PhiLho/z7GL8/7/

  • I think js only sees difference in the number of parameters and not in Types...

  • edited November 2013

    Ah, the first two constructors have different number of parameters (in the original code), but weren't working, and I concentrated on them, overlooking the third one (unused, but same number of parameters than the first one), which might have been the one called instead of the first one!

    JS cannot distinguish functions on their type, because it has no typed variables. Processing.js would need some extra work to detect these overloads and to manage them...

Sign In or Register to comment.