3 Replies Latest reply: Nov 30, 2012 9:54 AM by Gaius Coffey RSS

    Printing from a component

    Chris Pamplin

      In the Flash user guide there is an example of how to print using a custom control to deal with the layout for printing. In the code example it has the following code snippet:


      public function doPrint():void {

           // Create a FlexPrintJob instance.

           var printJob:FlexPrintJob = new FlexPrintJob();

           // Start the print job.

           if(printJob.start()) {

                // Create a MyPrintView control as a child

                // of the current view.

                var formPrintView:MyPrintView = new MyPrintView();




      The problem I have is that the call to addElement is flagged as a problem (may be undefined) in the code editor and fails with an error (ArgumentError: espMain18.WindowedApplicationSkin19.Group20.contentGroup.PrintRendered1039 is not found in this Group) when I run the application and try to print.


      I can get around this by adding FlexGlobals.TopLevelApplication. before the call to addElement, but that results in all print out having a gray tint across the whole page.


      If, instead, I add a try catch block around the addElement call and simply ignore the error, the print comes out as intended without the gray tint overlaying everything.


      What am I doing wrong? How am I suppsoed to use the addElement call?



        • 1. Re: Printing from a component
          Gaius Coffey Community Member

          Well, nothing much can go wrong with a call to addElement, provided:

          a) You make the call on a class that _has_ the addElement method

          b) You call it with something that is a valid IVisualElement


          For b), you say that the call works when you use FlexGlobals.topLevelApplication.addElement(); so (although you haven't provided source) I can be confident that MyPrintView is a valid IVisualElement. So b) is not the problem. Calling FlexGlobals.topLevelApplication.addElement(); works because the application is an IVisualElementContainer and so has the addElement method defined.


          Therefore, I conclude that you have defined this method on something other than the display class that you are printing.


          You have either defined the method on a class that is not an IVisualElementContainer (for example, did you build this as an extension of Sprite, outside of Flex? or did you create a separate print manager class?) or created an anonymous function within the display class that cannot resolve "this" to the container.




          Check where and what you have set your print job method up on. If you are using Flex, then it can just be a method of the containing s:Group or s:View or whatever. If it is a Sprite in a pure Flash app, then you can replace addElement with addChild instead.



          • 2. Re: Printing from a component
            Chris Pamplin Community Member



            Many thanks for your insights. What 'this' means is always something that seems to fool me. Because of my programming background I tend to split code from UI by putting code into a separate .as file that I then include, using <fx:Script source="xyz.as"/>, into the mxml file. So, my public function doPrint()  is declared inside the .as file rather than inside an fx:Script block in the mxml file.


            I understand that if I declared doPrint() in a script block in the mxml file then 'this' would refer to the containing s:window (in my case). But, moving the code out into the .as file, despite it being included back into the mxml file with <fs:Script source="xyz.as">, clearly leaves 'this' refering to something else, something else that isn't based on IVisualElementContainer.


            So, using your insight, I simply created a new function, print2(), inside the mxml file (and that has no problem with addElement) then just called print2 from the original doPrint() function in the .as file, passing in the necessary data to output. No errors and no gray overlay!


            Thank you for helping me to understand the issue better and thereby come up with a solution. Maybe I shouldn't be so keen to move code out of the mxml file.



            • 3. Re: Printing from a component
              Gaius Coffey Community Member

              Separating out logical code from display code is nothing to be ashamed of, but there are better ways of doing it... Remember, you are in an OOP environment, so you can organise things to share functionality across a wide range of things without getting tied up in global function hell.


              For example, I could do this:


              package com.whatever


                import spark.components.Group;



              public class PGroupBase extends Group



              I can then add custom properties to that class, or create subclasses of that class, or quite a lot of other things. I can implement interfaces and I can use static properties to provide global links between every instance and so on and so forth.


              And, from a design perspective, in my display code, I still end up with the very simple and familiar:



              <whatever:PGroupBase width="100%" height="100%"





              That doesn't stop you from separating out purely abstract code into purely abstract classes - for example, I have a singleton pattern OrientationManager class that provides me with full control over stage rotation etc for anything that cares to use it in just a couple of lines - but it does mean that you can leverage the full might of Flex IVisualElement and IUIComponent power without tieing yourself up in knots.