8 Replies Latest reply on Jan 30, 2008 11:26 PM by etnot96

    How to add Text to Canvas in Flex/AS3

    etnot96
      I am doing AS3 programactically so I have a one mxml file that calls to my application.

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="Main.main()">
      </mx:Application>

      I am running in to issues when I try to display text inside the Canvas of a view in the ViewStack(The view stack is displaying correctly with links for the navbar). See code below. What am I doing wrong? Any help is welcome!

      BTW, I know I posted a lot of code but I really want some help on this as I am very new to AS3. The real meat of the code is in the AccountView class.

      Thanks in Advance!

      Tonté Pouncil


      package com.pouncilt.chuckspic3.core{
      import mx.containers.Panel;
      import mx.containers.ViewStack;
      import mx.controls.*;
      import mx.core.*;
      import com.pouncilt.chuckspic3.views.ViewFactory;
      import com.pouncilt.chuckspic3.views.View;

      public class Main {
      private static var mainPanel:Panel = null;
      private static var application:Application = null;
      private static var navBar:LinkBar = null;
      private static var views:ViewStack = null;

      public static function main():void{
      init();
      }

      private static function init():void{
      Main.application = Application(Application.application);
      Main.application.styleName = "plain";
      createMainPanel();
      createNavigationBar();
      Main.application.addChild(Main.mainPanel);
      }

      private static function createMainPanel():void{
      Main.mainPanel = new Panel();
      Main.mainPanel.title = "Chuck's Pic 3";
      Main.mainPanel.percentHeight = 95;
      Main.mainPanel.percentWidth = 95;

      Main.mainPanel.setStyle("paddingTop", 10);
      Main.mainPanel.setStyle("paddingLeft", 10);
      Main.mainPanel.setStyle("paddingRight",10);
      Main.mainPanel.setStyle("paddingBottom", 10);
      }

      private static function createNavigationBar():void{
      Main.navBar = new LinkBar();
      Main.views = new ViewStack();
      Main.views.setStyle("borderStyle","solid");
      Main.views.percentHeight = 100;
      Main.views.percentWidth = 100;
      Main.views.visible = true;

      Main.views.addChild(ViewFactory.createView(ViewFactory.HOME));
      Main.views.addChild(ViewFactory.createView(ViewFactory.LOGIN));
      Main.views.addChild(ViewFactory.createView(ViewFactory.REGISTRATION));
      Main.views.addChild(ViewFactory.createView(ViewFactory.ACCOUNT));
      Main.views.addChild(ViewFactory.createView(ViewFactory.APPLICATION));

      Main.navBar.dataProvider = views;
      Main.mainPanel.addChild(Main.navBar);
      }
      }
      }


      package com.pouncilt.chuckspic3.views{
      import flash.utils.getDefinitionByName;
      import flash.utils.getQualifiedClassName;

      public class ViewFactory{
      public static const HOME:String = "com.pouncilt.chuckspic3.views.HomeViewFactory";
      private static const homeViewFactoryRef:HomeViewFactory = null;

      public static const REGISTRATION:String = "com.pouncilt.chuckspic3.views.RegistrationViewFactory";
      private static const registrationViewFactoryRef:RegistrationViewFactory = null;

      public static const LOGIN:String = "com.pouncilt.chuckspic3.views.LoginViewFactory";
      private static const loginViewFactoryRef:LoginViewFactory = null;

      public static const ACCOUNT:String = "com.pouncilt.chuckspic3.views.AccountViewFactory";
      private static const accountViewFactoryRef:AccountViewFactory = null;

      public static const APPLICATION:String = "com.pouncilt.chuckspic3.views.ApplicationViewFactory";
      private static const applicationViewFactoryRef:ApplicationViewFactory = null;


      public static function createView(className:String):View{
      var classReference:Class = getDefinitionByName(className) as Class;
      var factory:IViewFactory = new classReference();
      return factory.createView(null);
      }
      }
      }


      package com.pouncilt.chuckspic3.views{

      public class AccountViewFactory implements IViewFactory{

      /*public function createView():View{
      return new AccountView(null);
      }*/

      public function createView(label:String):View{
      return new AccountView(label);
      }
      }
      }


      package com.pouncilt.chuckspic3.views{
      import mx.controls.Text;

      internal class AccountView extends View{

      public function AccountView(label:String){
      super(label) ;
      var welcomeText:Text = new Text();
      welcomeText.text = "Account Page";
      addChild(welcomeText);
      }
      }
      }

      package com.pouncilt.chuckspic3.views{
      import mx.containers.Canvas;

      internal class View extends Canvas{
      public static var COUNT:int = 0;


      function View(newLabel:String){
      super();
      if(newLabel == "" || newLabel == null){
      label = "View " + View.COUNT;
      } else {
      label = newLabel;
      }

      View.COUNT++;
      }
      /*function View(){
      //View("View " + View.COUNT);
      super();
      label = "View " + ++View.COUNT;
      }*/
      }
      }
        • 1. How to add Text to Canvas in Flex/AS3
          AS3dev
          The problem is that you are adding the Text component in the constructor. When extending classes that extend UIComponent, as Canvas does, you need to override the protected method createChildren() to add your children.

          Change your AccountView class to:

          package com.pouncilt.chuckspic3.views{
          import mx.controls.Text;

          internal class AccountView extends View{

          public function AccountView(label:String){
          super(label) ;
          }
          override protected function createChildren():void {
          super.createChildren();
          var welcomeText:Text = new Text();
          welcomeText.text = "Account Page";
          addChild(welcomeText);
          }
          }
          }

          See the following adobe livedocs for more info:
          Class UIComponent
          About overriding protected UIComponent methods
          Implementing the createChildren() method

          Now, I didn't recreate your project on my computer. So I can't test it. But if everything else is right, it should work. Let me know either way. Thanks!
          • 2. Re: How to add Text to Canvas in Flex/AS3
            etnot96 Level 1
            Okay, Phillip. Thanks for the reply. I made the changes you suggest and it does not work. hm this seems to be a tough one. Any suggestions. BTW, what you suggestioned and the documentation you gave did make sense.

            Thants for that!
            • 3. Re: How to add Text to Canvas in Flex/AS3
              etnot96 Level 1
              I recently changed my Main.as file in an attemp to debug my code after reading a blog on flashmonkey. My new Main.as looks like the following:

              package com.pouncilt.chuckspic3.core{
              import mx.containers.Panel;
              import mx.containers.ViewStack;
              import mx.controls.*;
              import mx.core.*;
              import com.pouncilt.chuckspic3.views.ViewFactory;
              import com.pouncilt.chuckspic3.views.View;

              public class Main {
              private static var mainPanel:Panel = null;
              private static var application:Application = null;
              private static var navBar:LinkBar = null;
              private static var views:ViewStack = null;


              public static function main():void{
              init();
              }

              private static function init():void{
              Main.application = Application(Application.application);
              Main.application.styleName = "plain";
              createMainPanel();
              createNavigationBar();
              Main.application.addChild(Main.mainPanel);
              }

              private static function createMainPanel():void{
              Main.mainPanel = new Panel();
              Main.mainPanel.title = "Chuck's Pic 3";
              Main.mainPanel.percentHeight = 95;
              Main.mainPanel.percentWidth = 95;

              Main.mainPanel.setStyle("paddingTop", 10);
              Main.mainPanel.setStyle("paddingLeft", 10);
              Main.mainPanel.setStyle("paddingRight",10);
              Main.mainPanel.setStyle("paddingBottom", 10);
              }

              private static function createNavigationBar():void{
              Main.navBar = new LinkBar();
              Main.views = new ViewStack();
              Main.views.setStyle("borderStyle","solid");
              Main.views.percentHeight = 100;
              Main.views.percentWidth = 100;
              Main.views.visible = true;

              //Main.views.addChild(ViewFactory.createView(ViewFactory.HOME));
              //Main.views.addChild(ViewFactory.createView(ViewFactory.LOGIN));
              //Main.views.addChild(ViewFactory.createView(ViewFactory.REGISTRATION));
              var someView:View = ViewFactory.createView(ViewFactory.ACCOUNT);
              Main.views.addChild(someView);
              //Main.views.addChild(ViewFactory.createView(ViewFactory.APPLICATION));

              Main.navBar.dataProvider = views;
              Main.mainPanel.addChild(Main.navBar);
              }
              }
              }

              I get the following error:

              [INFO] C:\dev\projects2\chucks-pic3\src\main\flex\com\pouncilt\chuckspic3\core\Main.as(51): col: 17 Error: Type was not found or was not a compile-time constant: View.
              [INFO]
              [INFO] var someView:View = ViewFactory.createView(ViewFactory.ACCOUNT);

              Does anyone know why I am getting this build error when I import the import com.pouncilt.chuckspic3.views.View class?
              • 4. Re: How to add Text to Canvas in Flex/AS3
                etnot96 Level 1
                I believe I was getting this build error because the View class is internal and not public. I have since change the code to look like this in the Main.as
                ...
                private static function createNavigationBar():void{
                Main.navBar = new LinkBar();
                Main.views = new ViewStack();
                Main.views.setStyle("borderStyle","solid");
                Main.views.percentHeight = 100;
                Main.views.percentWidth = 100;
                Main.views.visible = true;

                ViewFactory.createView(ViewFactory.HOME, Main.views);
                ViewFactory.createView(ViewFactory.LOGIN, Main.views);
                ViewFactory.createView(ViewFactory.REGISTRATION, Main.views);
                ViewFactory.createView(ViewFactory.ACCOUNT, Main.views);
                ViewFactory.createView(ViewFactory.APPLICATION, Main.views);

                Main.navBar.dataProvider = views;
                Main.mainPanel.addChild(Main.navBar);
                }
                ...

                My ViewFactory.as looks like this.
                package com.pouncilt.chuckspic3.views{
                import flash.utils.getDefinitionByName;
                import flash.utils.getQualifiedClassName;
                import mx.containers.ViewStack;

                public class ViewFactory{
                public static const HOME:String = "com.pouncilt.chuckspic3.views.HomeViewFactory";
                private static const homeViewFactoryRef:HomeViewFactory = null;

                public static const REGISTRATION:String = "com.pouncilt.chuckspic3.views.RegistrationViewFactory";
                private static const registrationViewFactoryRef:RegistrationViewFactory = null;

                public static const LOGIN:String = "com.pouncilt.chuckspic3.views.LoginViewFactory";
                private static const loginViewFactoryRef:LoginViewFactory = null;

                public static const ACCOUNT:String = "com.pouncilt.chuckspic3.views.AccountViewFactory";
                private static const accountViewFactoryRef:AccountViewFactory = null;

                public static const APPLICATION:String = "com.pouncilt.chuckspic3.views.ApplicationViewFactory";
                private static const applicationViewFactoryRef:ApplicationViewFactory = null;


                public static function createView(className:String, views:ViewStack):void{
                var classReference:Class = getDefinitionByName(className) as Class;
                var factory:IViewFactory = new classReference();
                views.addChild(views);
                }
                }
                }
                • 5. Re: How to add Text to Canvas in Flex/AS3
                  etnot96 Level 1
                  I believe I was getting this build error because the View class is internal and not public. I have since change the code to look like this in the Main.as
                  ...
                  private static function createNavigationBar():void{
                  Main.navBar = new LinkBar();
                  Main.views = new ViewStack();
                  Main.views.setStyle("borderStyle","solid");
                  Main.views.percentHeight = 100;
                  Main.views.percentWidth = 100;
                  Main.views.visible = true;

                  ViewFactory.createView(ViewFactory.HOME, Main.views);
                  ViewFactory.createView(ViewFactory.LOGIN, Main.views);
                  ViewFactory.createView(ViewFactory.REGISTRATION, Main.views);
                  ViewFactory.createView(ViewFactory.ACCOUNT, Main.views);
                  ViewFactory.createView(ViewFactory.APPLICATION, Main.views);

                  Main.navBar.dataProvider = views;
                  Main.mainPanel.addChild(Main.navBar);
                  }
                  ...

                  My ViewFactory.as looks like this.
                  package com.pouncilt.chuckspic3.views{
                  import flash.utils.getDefinitionByName;
                  import flash.utils.getQualifiedClassName;
                  import mx.containers.ViewStack;

                  public class ViewFactory{
                  public static const HOME:String = "com.pouncilt.chuckspic3.views.HomeViewFactory";
                  private static const homeViewFactoryRef:HomeViewFactory = null;

                  public static const REGISTRATION:String = "com.pouncilt.chuckspic3.views.RegistrationViewFactory";
                  private static const registrationViewFactoryRef:RegistrationViewFactory = null;

                  public static const LOGIN:String = "com.pouncilt.chuckspic3.views.LoginViewFactory";
                  private static const loginViewFactoryRef:LoginViewFactory = null;

                  public static const ACCOUNT:String = "com.pouncilt.chuckspic3.views.AccountViewFactory";
                  private static const accountViewFactoryRef:AccountViewFactory = null;

                  public static const APPLICATION:String = "com.pouncilt.chuckspic3.views.ApplicationViewFactory";
                  private static const applicationViewFactoryRef:ApplicationViewFactory = null;


                  public static function createView(className:String, views:ViewStack):void{
                  var classReference:Class = getDefinitionByName(className) as Class;
                  var factory:IViewFactory = new classReference();
                  views.addChild(views);
                  }
                  }
                  }

                  but I still don't see any text in the main panel. Any suggestion from anybody?

                  Thanks!
                  • 6. Re: How to add Text to Canvas in Flex/AS3
                    etnot96 Level 1
                    I get the following error with the new code I added above.

                    ArgumentError: Error #2024: An object cannot be added as a child of itself.
                    at flash.display::DisplayObjectContainer/addChildAt()
                    at mx.core::UIComponent/ http://www.adobe.com/2006/flex/mx/internal::$addChildAt()[C:\dev\flex_201_ja\sdk\framework s\mx\core\UIComponent.as:4677
                    at mx.core::Container/addChildAt()[C:\dev\flex_201_ja\sdk\frameworks\mx\core\Container.as:22 78]
                    at mx.core::Container/addChild()[C:\dev\flex_201_ja\sdk\frameworks\mx\core\Container.as:2214 ]
                    at com.pouncilt.chuckspic3.views::ViewFactory$/createView()[C:\dev\projects2\chucks-pic3\src \main\flex\com\pouncilt\chuckspic3\views\ViewFactory.as:26]
                    at com.pouncilt.chuckspic3.core::Main$/createNavigationBar()[C:\dev\projects2\chucks-pic3\sr c\main\flex\com\pouncilt\chuckspic3\core\Main.as:47]
                    at com.pouncilt.chuckspic3.core::Main$/init()[C:\dev\projects2\chucks-pic3\src\main\flex\com \pouncilt\chuckspic3\core\Main.as:23]
                    at com.pouncilt.chuckspic3.core::Main$/main()[C:\dev\projects2\chucks-pic3\src\main\flex\com \pouncilt\chuckspic3\core\Main.as:16]
                    at com.pouncilt.chuckspic3.core::chuckspic3/___Application1_applicationComplete()[C:\dev\pro jects2\chucks-pic3\src\main\flex\com\pouncilt\chuckspic3\core\chuckspic3.mxml:2]
                    at flash.events::EventDispatcher/dispatchEventFunction()
                    • 7. Re: How to add Text to Canvas in Flex/AS3
                      etnot96 Level 1
                      Ok sorry, I fixed the error msg above but still no luck with displaying the text in the main view. My ViewFactory.createView() looks like this.

                      public static function createView(className:String, views:ViewStack):void{
                      var classReference:Class = getDefinitionByName(className) as Class;
                      var factory:IViewFactory = new classReference();
                      views.addChild(factory.createView(null));
                      }

                      Any suggestion?

                      Thanks!
                      • 8. Re: How to add Text to Canvas in Flex/AS3
                        etnot96 Level 1
                        OK folks I figured out what I was doing wrong. In my Main.as class I have a method called createNavigationBar() and in this method is where I add the Linkbar (I refer to LinkBar as NavBar in my code) to the Panel. Because I am a newbie and tbecause of the lack of documentation of working with Flex programmatically, I didn't know I had to also added the ViewStack to the Panel. This was not so clear to me because I had already added the ViewStack to the LinkBar as my DataProvider. So I thought since I already connected my ViewStack to the LinkBar via DataProvider and then adding the LinkBar to the Panel I should see both aspects of the ViewStack (the navbar and the main view). But this is where I was wrong. See Code snippet below:

                        private static function createNavigationBar():void{
                        Main.navBar = new LinkBar();
                        Main.views = new ViewStack();
                        Main.views.setStyle("borderStyle","solid");
                        Main.views.percentHeight = 100;
                        Main.views.percentWidth = 100;
                        Main.views.visible = true;
                        Main.views.creationPolicy = "all";

                        ViewFactory.createView(ViewFactory.HOME, Main.views);
                        ViewFactory.createView(ViewFactory.LOGIN, Main.views);
                        ViewFactory.createView(ViewFactory.REGISTRATION, Main.views);
                        ViewFactory.createView(ViewFactory.ACCOUNT, Main.views);
                        ViewFactory.createView(ViewFactory.APPLICATION, Main.views);

                        Main.navBar.dataProvider = Main.views;
                        Main.mainPanel.addChild(Main.navBar);
                        Main.mainPanel.addChild(Main.views);



                        }

                        Its funny that no body spotted this. But many thanks to all who took the time to help with suggestion and links. I learn a lot about Flex/ActionScript3 while debugging this issue.

                        Thanks!

                        Tonte