7 Replies Latest reply on Oct 2, 2011 11:58 PM by pauland

    Calculator

    newbie-fl3x

      Hi Everyone

       

      I am trying to make simple calc on flex mobile,

      It doesn`t work it doesn`t display anything on text area

      and i got no error message, just warning message abou Data Binding

       

      This is the code

       

      <?xml version="1.0" encoding="utf-8"?>
      <s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">
      <fx:Declarations>
        <!-- 非ビジュアルエレメント (サービス、値オブジェクトなど) をここに配置 -->
      </fx:Declarations>

       


      <fx:Script>
        <![CDATA[
        
         public var numbers:Array = [num0_btn,num1_btn,num2_btn,num3_btn,num4_btn,num5_btn,num6_btn,num7_btn,num8_btn,num9_bt n];
        
         public var operators:Array = [equal_btn,divide_btn,subtract_btn,add_btn];
        
         public var op:String;
        
         public var num1:Number;
        
         public var num2:Number;
        
         [Bindable]
         public var txt:TextField = new TextField();
        
         public function addListeners():void
         {
         
          for(var i:uint = 0; i < numbers.length; i++)
          {
           numbers[i].addEventListener(MouseEvent.CLICK, pressNumber);
          }
          for(i = 0; i < operators.length; i++)
          {
           operators[i].addEventListener(MouseEvent.CLICK, pressOperator);
          }
          clear_btn.addEventListener(MouseEvent.CLICK, clearAll);
          dot_btn.addEventListener(MouseEvent.CLICK, addDot);
         }
        
         public function pressNumber(event:MouseEvent):void
         {
          var instanceName:String = event.target.name;
          var numPushed:String = instanceName.charAt(3);
          if(txt.text == "0" || num1 == Number(txt.text))
          {
           txt.text = "";
          }
          txt.appendText(numPushed);
         }
        
         public function pressOperator(event:MouseEvent):void
         {
          var instanceName:String = event.target.name;
          var currentOp:String = instanceName.slice(0, instanceName.indexOf("_"));
          if(!num1)
          {
           num1 = Number(txt.text);
           txt.text="";
           op = currentOp;
          }
          else if(!num2)
          {
           num2 = Number(txt.text);
           showCalculation();
           op = currentOp;
          }
         }
        
         public function clearAll(event:MouseEvent):void
         {
          txt.text = "0";
          num1 = NaN;
          num2 = NaN;
         }
        
         public function addDot(event:MouseEvent):void
         {
          if(num1 == Number(txt.text))
          {
           txt.text = "0";
          }
          if(txt.text.indexOf(".")==-1)
          {
           txt.appendText(".");
          }
         }
        
         public function showCalculation():void
         {
          switch(op)
          {
           case"multiply":
            num1 *= num2;
            break;
           case"divide":
            num1 /= num2;
            break;
           case"add":
            num1 += num2;
            break;
           case"subtract":
            num1 -= num2;
            break;
           default:
            break;
          
          }
          txt.text = String(num1);
          num2 = NaN;
         }
        
        
        
        
        
        ]]>
      </fx:Script>

       


      <s:TextArea id="window_txt" x="20" y="44" text="{txt.text}"/>
      <s:Button id="num1_btn" x="46" y="399" label="1" />
      <s:Button id="num2_btn" x="128" y="399" label="2" />
      <s:Button id="num3_btn" x="216" y="399" label="3" />
      <s:Button id="num0_btn" x="50" y="494" label="0" />
      <s:Button id="add_btn" x="294" y="308" label="+" />
      <s:Button id="equal_btn" x="294" y="493" label="=" />


      <s:Button id="dot_btn" x="128" y="493" label="."/>
      <s:Button id="clear_btn" x="216" y="493" label="C"/>
      <s:Button id="subtract_btn" x="294" y="399" label="-"/>
      <s:Button id="num4_btn" x="46" y="308" label="4"/>
      <s:Button id="num5_btn" x="128" y="308" label="5"/>
      <s:Button id="num6_btn" x="216" y="308" label="6"/>
      <s:Button id="divide_btn" x="294" y="131" label="÷"/>
      <s:Button id="num7_btn" x="46" y="219" label="7"/>
      <s:Button id="num8_btn" x="128" y="219" label="8"/>
      <s:Button id="num9_btn" x="216" y="219" label="9"/>
      <s:Button x="46" y="131" width="48" label="M+" fontSize="12"/>
      <s:Button x="128" y="131" label="M-" fontSize="12"/>
      <s:Button x="216" y="131" label="mr" fontSize="12"/>
      <s:Button id="multiply_btn" x="294" y="219" label="x"/>

       


      </s:View>

        • 1. Re: Calculator
          kraikit

          I haven't looked too closely, but at a quick glance it looks like you have an addListeners() function to attach the click listeners. Where does addListeners() get called?

           

          -- Tom Kraikit

          Flex SDK engineer

          1 person found this helpful
          • 2. Re: Calculator
            newbie-fl3x Level 1

            Hi Tom,

            Thanks for Reply

             

            I try to call my addListener() to my buttons, but got this error messages.

             

            ############

            TypeError: Error #1009: Cannot access a property or method of a null object reference.

            at Calculator/addListeners()[C:\Users\ut\Adobe Flash Builder 4.5\Calculator\src\Calculator.mxml:27]

            at Calculator/__num1_btn_click()[C:\Users\ut\Adobe Flash Builder 4.5\Calculator\src\Calculator.mxml:120]

            ############

             

            and then try to trace it with

             

            trace("mytrace:" + numbers[i]); -->  //mytrace: null           

            trace("mytrace:" + numbers.length); --> //mytrace: 10

            trace("mytrace:" + i); --> //mytrace: 1

            #####################

            <?xml version="1.0" encoding="utf-8"?>
            <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                    xmlns:s="library://ns.adobe.com/flex/spark"
                    xmlns:mx="library://ns.adobe.com/flex/mx">

            <fx:Script>
              <![CDATA[
              
               import flash.events.MouseEvent;
              
               public var numbers:Array = [num0_btn,num1_btn,num2_btn,num3_btn,num4_btn,num5_btn,num6_btn,num7_btn,num8_btn,num9_bt n];
              
               public var operators:Array = [equal_btn,divide_btn,subtract_btn,add_btn];
              
               public var op:String;
              
               public var num1:Number;
              
               public var num2:Number;
              
                 
               public function addListeners():void
               {
               
                for(var i:uint = 0; i < numbers.length; i++)
                {
                 numbers[i].addEventListener(MouseEvent.CLICK, pressNumber);
                
                }
                for(i = 0; i < operators.length; i++)
                {
                 operators[i].addEventListener(MouseEvent.CLICK, pressOperator);
                }
                clear_btn.addEventListener(MouseEvent.CLICK, clearAll);
                dot_btn.addEventListener(MouseEvent.CLICK, addDot);
               
               }
              
               public function pressNumber(event:MouseEvent):void
               {
                var instanceName:String = event.target.name;
                var numPushed:String = instanceName.charAt(3);
                if(window_txt.text == "0" || num1 == Number(window_txt.text))
                {
                 window_txt.text = "";
                }
                window_txt.appendText(numPushed);
               }
              
               public function pressOperator(event:MouseEvent):void
               {
                var instanceName:String = event.target.name;
                var currentOp:String = instanceName.slice(0, instanceName.indexOf("_"));
                if(!num1)
                {
                 num1 = Number(window_txt.text);
                 window_txt.text="";
                 op = currentOp;
                }
                else if(!num2)
                {
                 num2 = Number(window_txt.text);
                 showCalculation();
                 op = currentOp;
                }
               }
              
               public function clearAll(event:MouseEvent):void
               {
                window_txt.text = "0";
                num1 = NaN;
                num2 = NaN;
               }
              
               public function addDot(event:MouseEvent):void
               {
                if(num1 == Number(window_txt.text))
                {
                 window_txt.text = "0";
                }
                if(window_txt.text.indexOf(".") == -1)
                {
                 window_txt.appendText(".");
                }
               }
              
               public function showCalculation():void
               {
                switch(op)
                {
                 case"multiply":
                  num1 *= num2;
                  break;
                 case"divide":
                  num1 /= num2;
                  break;
                 case"add":
                  num1 += num2;
                  break;
                 case"subtract":
                  num1 -= num2;
                  break;
                 default:
                  break;
                
                }
                window_txt.text = String(num1);
                num2 = NaN;
               }
              
                    
              ]]>
            </fx:Script>

            <fx:Declarations>
              <!-- Place non-visual elements (e.g., services, value objects) here -->
            </fx:Declarations>

            <s:TextArea id="window_txt" x="20" y="44" height="42" text="0"/>
            <s:Button id="num1_btn" x="23" y="182" label="1" click="addListeners()"/>
            <s:Button id="num2_btn" x="105" y="182" label="2" click="addListeners()"/>
            <s:Button id="num3_btn" x="193" y="182" label="3" click="addListeners()"/>
            <s:Button id="num0_btn" x="27" y="212" label="0" click="addListeners()"/>
            <s:Button id="add_btn" x="271" y="153" label="+" click="addListeners()"/>
            <s:Button id="equal_btn" x="271" y="211" label="=" click="addListeners()"/>


            <s:Button id="dot_btn" x="105" y="211" label="." click="addListeners()"/>
            <s:Button id="clear_btn" x="193" y="211" label="C" click="addListeners()"/>
            <s:Button id="subtract_btn" x="271" y="182" label="-" click="addListeners()"/>
            <s:Button id="num4_btn" x="23" y="153" label="4" click="addListeners()"/>
            <s:Button id="num5_btn" x="105" y="153" label="5" click="addListeners()"/>
            <s:Button id="num6_btn" x="193" y="153" label="6" click="addListeners()"/>
            <s:Button id="divide_btn" x="271" y="97" label="÷" click="addListeners()"/>
            <s:Button id="num7_btn" x="23" y="125" label="7" click="addListeners()"/>
            <s:Button id="num8_btn" x="105" y="125" label="8" click="addListeners()"/>
            <s:Button id="num9_btn" x="193" y="125" label="9" click="addListeners()"/>
            <s:Button x="23" y="97" width="48" label="M+" fontSize="12" click="addListeners()"/>
            <s:Button x="105" y="97" label="M-" fontSize="12" click="addListeners()"/>
            <s:Button x="193" y="97" label="mr" fontSize="12" click="addListeners()"/>
            <s:Button id="multiply_btn" x="271" y="125" label="x" click="addListeners()"/>


            </s:WindowedApplication>

            • 3. Re: Calculator
              pauland Level 4

              Your array initialisation for numbers is done before the buttons are created, so it's full of nulls.

               

              public var numbers:Array = [num0_btn,num1_btn,num2_btn,num3_btn,num4_btn,num5_btn,num6_btn,num7_ btn,num8_btn,num9_btn];

               

              Check out creation complete. You must wait for the interface to be built before referring to the buttons.

               

              You have supplied "addListeners()" as the handler for a click for all your UI elements. It should be called only once, preferably after creation complete, and certainly not as part of a click handler.

               

              You are clearly confused as to the differrence between creating a click event handler in MXML and actionscript.

               

              click="addListeners()" in MXML is saying that "my handler for the click event is what's between the quotes".

               

              When you write in AS3

               

              addEventListener(MouseEvent.CLICK, pressNumber);  you are saying "this is my click handler for the click event, for this UI element".

               

              So, use one or the other, either

               

              click="pressNumber(event)" in MXML, or addEventListener(MouseEvent.CLICK, pressNumber); in AS3, but not both.

               

              That should give you some movement towards the solution.

               

              I would also say, that before bad habits get entrenched, the old flash naming convention "subtract_btn" is not so good in Flex or indeed Flash these days. Use camel case to name your variables rather than underscores, so subtract_btn becomes subtractBtn. Better to start with that right now than later!

               

              Good luck.

               

              Paul

              1 person found this helpful
              • 4. Re: Calculator
                newbie-fl3x Level 1

                Hi Paul

                thanks for quick response

                 

                I follow your advice and fix the code. creationComplete="addListeners()"

                Now i got displayed numbers on calc screen every time i push the button ,

                i forgot to include instanceName in Flex, got confused between "id" and "name" (instanceName in AS3)

                 

                But the operators doesn't work well , any suggestion ???

                 

                THis is the code

                 

                <?xml version="1.0" encoding="utf-8"?>
                <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                        xmlns:s="library://ns.adobe.com/flex/spark"
                        xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="addListeners()" >

                <fx:Script>
                  <![CDATA[
                  
                   import flash.events.MouseEvent;
                      
                   public var op:String;
                  
                   public var num1:Number;
                  
                   public var num2:Number;
                  
                       
                   public function addListeners():void
                   {
                   
                    var numbers:Array = [num0Btn,num1Btn,num2Btn,num3Btn,num4Btn,num5Btn,num6Btn,num7Btn,num8Btn,num9Btn];
                    var operators:Array = [divideBtn,addBtn,subtractBtn,multiplyBtn,equalBtn];
                   
                    for(var i:uint = 0; i < numbers.length; i++)
                    {
                     numbers[i].addEventListener(MouseEvent.CLICK, pressNumber);
                     trace("mytrace:" + i);
                    }
                    for(i = 0; i < operators.length; i++)
                    {
                     operators[i].addEventListener(MouseEvent.CLICK, pressOperator);
                    }
                    clearBtn.addEventListener(MouseEvent.CLICK, clearAll);
                    dotBtn.addEventListener(MouseEvent.CLICK, addDot);
                   
                   
                   
                   }
                  
                   public function pressNumber(event:MouseEvent):void
                   {
                    var instanceName:String = event.target.name;
                    var numPushed:String = instanceName.charAt(3);
                    if(window_txt.text == "0" || num1 == Number(window_txt.text))
                    {
                     window_txt.text = "";
                    
                    }
                    window_txt.appendText(numPushed);
                   
                   }
                  
                   public function pressOperator(event:MouseEvent):void
                   {
                    var instanceName:String = event.target.name;
                    var currentOp:String = instanceName.slice(0, instanceName.indexOf("_"));
                    if(!num1)
                    {
                     num1 = Number(window_txt.text);
                     window_txt.text="";
                     op = currentOp;
                    }
                    else if(!num2)
                    {
                     num2 = Number(window_txt.text);
                     showCalculation();
                     op = currentOp;
                    }
                   }
                  
                   public function clearAll(event:MouseEvent):void
                   {
                    window_txt.text = "0";
                    num1 = NaN;
                    num2 = NaN;
                   }
                  
                   public function addDot(event:MouseEvent):void
                   {
                    if(num1 == Number(window_txt.text))
                    {
                     window_txt.text = "0";
                    }
                    if(window_txt.text.indexOf(".") == -1)
                    {
                     window_txt.appendText(".");
                    }
                   }
                  
                   public function showCalculation():void
                   {
                    switch(op)
                    {
                     case"multiply":
                      num1 *= num2;
                      break;
                     case"divide":
                      num1 /= num2;
                      break;
                     case"add":
                      num1 += num2;
                      break;
                     case"subtract":
                      num1 -= num2;
                      break;
                     default:
                      break;
                    
                    }
                    window_txt.text = String(num1);
                    num2 = NaN;
                   }
                  
                        
                  ]]>
                </fx:Script>

                <fx:Declarations>
                  <!-- Place non-visual elements (e.g., services, value objects) here -->
                </fx:Declarations>

                <s:TextArea id="window_txt" x="20" y="44" height="42" text="0"/>
                <s:Button id="num1Btn" x="23" y="182" label="1" name="num1Btn" />
                <s:Button id="num2Btn" x="105" y="182" label="2" name="num2Btn"/>
                <s:Button id="num3Btn" x="193" y="182" label="3" name="num3Btn"/>
                <s:Button id="num0Btn" x="27" y="212" label="0" name="num0Btn"/>
                <s:Button id="addBtn" x="271" y="153" label="+" name="addBtn"/>
                <s:Button id="equalBtn" x="271" y="211" label="=" name="equalBtn"/>


                <s:Button id="dotBtn" x="105" y="211" label="." name="dotBtn"/>
                <s:Button id="clearBtn" x="193" y="211" label="C" name="clearBtn"/>
                <s:Button id="subtractBtn" x="271" y="182" label="-" name="subtractBtn"/>
                <s:Button id="num4Btn" x="23" y="153" label="4" name="num4Btn"/>
                <s:Button id="num5Btn" x="105" y="153" label="5" name="num5Btn"/>
                <s:Button id="num6Btn" x="193" y="153" label="6" name="num6Btn"/>
                <s:Button id="divideBtn" x="271" y="97" label="÷" name="divideBtn"/>
                <s:Button id="num7Btn" x="23" y="125" label="7" name="num7Btn"/>
                <s:Button id="num8Btn" x="105" y="125" label="8" name="num8Btn"/>
                <s:Button id="num9Btn" x="193" y="125" label="9" name="num9Btn"/>
                <s:Button x="23" y="97" width="48" label="M+" fontSize="12" />
                <s:Button x="105" y="97" label="M-" fontSize="12" />
                <s:Button x="193" y="97" label="mr" fontSize="12" />
                <s:Button id="multiplyBtn" x="271" y="125" label="x" name="multplyBtn"/>



                </s:WindowedApplication>

                • 5. Re: Calculator
                  pauland Level 4

                  "But the operators doesn't work well"

                   

                  Well that could mean anything! Put in some trace statements and/or have a go with the debugger. Start debugging by trying to add 1 to 1 and then gradually move on from there.

                   

                  Paul

                  • 6. Re: Calculator
                    newbie-fl3x Level 1

                    I solve the problem,

                     

                    @Paul, i follow your advice ("the old flash naming convention "subtract_btn" is not so good in Flex or indeed Flash these days") .so i change subtract_btn -> subtractBtn.
                    But then i realize that i am using "_" for my operators naming.
                    This was the problem and then i change my button id again
                    subtractBtn -> subtract_btn and it works.

                    anyway thanks.

                     

                    I also learn how to combining vertical and horizontal group, playing with color picker.

                    It was fun.

                     

                    ###########################

                     

                    <?xml version="1.0" encoding="utf-8"?>

                    <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"

                            xmlns:s="library://ns.adobe.com/flex/spark"

                            xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="addListeners()" >

                     

                    <fx:Script>

                      <![CDATA[

                      

                       import flash.events.MouseEvent;

                          

                       public var op:String;

                      

                       public var num1:Number;

                      

                       public var num2:Number;

                      

                           

                       public function addListeners():void

                       {

                       

                        var numbers:Array = [num0Btn,num1Btn,num2Btn,num3Btn,num4Btn,num5Btn,num6Btn,num7Btn,num8Btn,num9Btn];

                        var operators:Array = [divide_btn,add_btn,subtract_btn,multiply_btn,equal_btn];

                       

                        for(var i:uint = 0; i < numbers.length; i++)

                        {

                         numbers[i].addEventListener(MouseEvent.CLICK, pressNumber);

                         //trace("mytrace:" + i);

                        }

                        for(i = 0; i < operators.length; i++)

                        {

                         operators[i].addEventListener(MouseEvent.CLICK, pressOperator);

                        }

                        clearBtn.addEventListener(MouseEvent.CLICK, clearAll);

                        dotBtn.addEventListener(MouseEvent.CLICK, addDot);

                       

                       

                       

                       }

                      

                       public function pressNumber(event:MouseEvent):void

                       {

                        var instanceName:String = event.target.name;

                        var numPushed:String = instanceName.charAt(3);

                        if(window_txt.text == "0" || num1 == Number(window_txt.text))

                        {

                         window_txt.text = "";

                        

                        }

                        window_txt.appendText(numPushed);

                        //trace("instanceName:" + instanceName);

                        trace("numPushed:" + numPushed);

                       }

                      

                       public function pressOperator(event:MouseEvent):void

                       {

                        var instanceName:String = event.target.name;

                        var currentOp:String = instanceName.slice(0, instanceName.indexOf("_"));

                        if(!num1)

                        {

                         num1 = Number(window_txt.text);

                         window_txt.text="";

                         op = currentOp;

                        }

                        else if(!num2)

                        {

                         num2 = Number(window_txt.text);

                         showCalculation();

                         op = currentOp;

                        }

                        trace("currentOp:" + currentOp);

                       }

                      

                       public function clearAll(event:MouseEvent):void

                       {

                        window_txt.text = "0";

                        num1 = NaN;

                        num2 = NaN;

                       }

                      

                       public function addDot(event:MouseEvent):void

                       {

                        if(num1 == Number(window_txt.text))

                        {

                         window_txt.text = "0";

                        }

                        if(window_txt.text.indexOf(".") == -1)

                        {

                         window_txt.appendText(".");

                        }

                       }

                      

                       public function showCalculation():void

                       {

                        switch(op)

                        {

                         case"multiply":

                          num1 *= num2;

                          break;

                         case"divide":

                          num1 /= num2;

                          break;

                         case"add":

                          num1 += num2;

                          break;

                         case"subtract":

                          num1 -= num2;

                          break;

                         default:

                          break;

                        

                        }

                        window_txt.text = String(num1);

                        num2 = NaN;

                       }

                      

                            

                      ]]>

                    </fx:Script>

                     

                    <fx:Declarations>

                      <!-- Place non-visual elements (e.g., services, value objects) here -->

                    </fx:Declarations>

                     

                    <s:layout>

                      <s:HorizontalLayout gap="15" paddingLeft="10" paddingTop="10"/>

                    </s:layout>

                     

                    <mx:VDividedBox backgroundColor="{colorPicker.selectedItem.toString()}">

                      <s:Panel width="100%" height="74">

                       <s:TextArea id="window_txt" x="0" y="0" width="308" height="42" fontSize="20" text="0"

                          textAlign="right"/>

                      </s:Panel>

                     

                    <mx:HDividedBox height="136">

                       

                      <s:VGroup horizontalAlign="left" verticalAlign="top">

                       <s:Button label="M+" fontSize="12" />

                       <s:Button id="num7Btn" label="7" name="num7Btn"/>

                       <s:Button id="num4Btn" label="4" name="num4Btn"/>

                       <s:Button id="num1Btn" label="1" name="num1Btn" />

                       <s:Button id="num0Btn" label="0" name="num0Btn"/>

                      </s:VGroup>

                     

                      <s:VGroup horizontalAlign="left" verticalAlign="top">

                       <s:Button label="M-" fontSize="12" />

                       <s:Button id="num8Btn" label="8" name="num8Btn"/>

                       <s:Button id="num5Btn" label="5" name="num5Btn"/>

                       <s:Button id="num2Btn" label="2" name="num2Btn"/>

                       <s:Button id="dotBtn" label="." name="dotBtn"/>

                      </s:VGroup>

                     

                      <s:VGroup horizontalAlign="left" verticalAlign="top">

                       <s:Button label="mr" fontSize="12" />

                       <s:Button id="num9Btn" label="9" name="num9Btn"/>

                       <s:Button id="num6Btn" label="6" name="num6Btn"/>

                       <s:Button id="num3Btn" label="3" name="num3Btn"/>

                       <s:Button id="clearBtn" label="C" name="clearBtn"/>

                      </s:VGroup>

                     

                      <s:VGroup horizontalAlign="left" verticalAlign="top">

                       <s:Button id="add_btn" label="+" name="add_btn"/>

                       <s:Button id="subtract_btn" label="-" name="subtract_btn"/>

                       <s:Button id="divide_btn" label="÷" name="divide_btn"/>

                       <s:Button id="multiply_btn" label="x" name="multiply_btn"/>

                       <s:Button id="equal_btn" label="=" name="equal_btn"/>

                      </s:VGroup>

                    </mx:HDividedBox>

                     

                    </mx:VDividedBox>

                     

                    <mx:ColorPicker id="colorPicker" />

                     

                    </s:WindowedApplication>

                    • 7. Re: Calculator
                      pauland Level 4

                      Glad it worked out, and still the question is "not answered"!