6 Replies Latest reply: Apr 11, 2011 3:20 PM by Flex harUI RSS

    Is this a PrintDataGrid bug / restriction / my lack of understanding?

    DilipShah Community Member
      Hi!

      I'm trying to implement PrintDataGrid in my application  and I'm encountering a peculiar problem. The printout is skipping last several  rows in the printout of each page.
      I have narrowed down to what's causing this issue. My  application-level custom skin provides Flex scrolling capability to the entire  application. Presence of this scrollbar in the custom skin is causing  PrintDataGrid to skip last rows. In fact, number of rows skipped depends on the  height of the browser. If you reduce the browser height, you skip more  rows!
      Is this a bug PrintDataGrid or a restriction (cannot  have PrintDataGrid within Scroller) or I'm missing something?
      Please help as I'm struggling with this for several  days!
      Here is simple code to reproduce the issue:
      Main Application:
      ============
      <?xml version="1.0"?>
      <!-- printing\MultiPagePrint.mxml -->
      <s:Application
          xmlns:fx="http://ns.adobe.com/mxml/2009"
          xmlns:s="library://ns.adobe.com/flex/spark"
          xmlns:mx="library://ns.adobe.com/flex/mx"
          initialize="initData();"
          skinClass="ApplicationSkinCustom"
          >
          <s:states>
              <s:State name="displayState" />
              <s:State name="printState" />
          </s:states>
         
          <fx:Script>
              <![CDATA[
                  import mx.collections.ArrayCollection;
                  import mx.printing.*;
                 
                  [Bindable]
                  public var dgProvider:ArrayCollection;
                 
                  public var prodIndex:Number;
                 
                  // Data initialization, called when the application initializes.
                  public function initData():void {
                      // Create the data provider for the DataGrid control.
                      dgProvider = new ArrayCollection;
                  }
                 
                  // Fill the dgProvider ArrayCollection with the specified items.
                  public function setdgProvider(items:int):void {
                      // First initialize the index and clear any existing data.
                      prodIndex=1;
                      dgProvider.removeAll();
                     
                      // Fill the ArrayCollection, and calculate a product total.
                      // For simplicity, it increases the Index field value by
                      // 1, and the Qty field by 7 for each item.
                      for (var z:int=0; z<items; z++) {
                          var prod1:Object = {};
                          prod1.Qty = prodIndex * 7;
                          prod1.Index = prodIndex++;
                          dgProvider.addItem(prod1);
                      }
                  }
                 
                  // The function to print the output.
                  public function doPrint():void {
                      currentState = "printState";
                     
                      // Create a FlexPrintJob instance.
                      var printJob:FlexPrintJob = new FlexPrintJob();
                     
                      // Start the print job.
                      if (printJob.start()) {
                          // Set the print view properties.
                          vGroup.width=printJob.pageWidth;
                          vGroup.height=printJob.pageHeight;
                         
                          // Set the data provider of the FormPrintView
                          // component's DataGrid to be the data provider of
                          // the displayed DataGrid.
                          printDataGrid.dataProvider = dgProvider;
                         
                          printJob.addObject(vGroup);
                      }
                      // Send the job to the printer.
                      printJob.send();
                  }
              ]]>
          </fx:Script>
         
          <s:VGroup
              excludeFrom="printState"
              width="100%"
              horizontalAlign="center"
              paddingTop="10"
              paddingBottom="10"
              paddingLeft="10"
              paddingRight="10"
              gap="10"
              >
              <!-- The form that appears on the user's system.-->
              <mx:Form id="myForm" width="80%">
                  <mx:FormHeading label="Product Information"/>
                  <mx:DataGrid id="myDataGrid" dataProvider="{dgProvider}">
                      <mx:columns>
                          <mx:DataGridColumn dataField="Index"/>
                          <mx:DataGridColumn dataField="Qty"/>
                      </mx:columns>
                  </mx:DataGrid>
                  <mx:Text width="100%"
                           text="Specify the number of lines and click Fill Grid first.
                           Then you can click Print."/>
                  <mx:TextInput id="dataItems" text="35"/>
                  <mx:HBox>
                      <mx:Button id="setDP"
                                 label="Fill Grid"
                                 click="setdgProvider(int(dataItems.text));"/>
                      <mx:Button id="printDG"
                                 label="Print"
                                 click="doPrint();"/>
                  </mx:HBox>
              </mx:Form>
          </s:VGroup>
         
          <s:VGroup
              id="vGroup"
              includeIn="printState"
              width="100%"
              horizontalAlign="center"
              paddingTop="10"
              paddingBottom="10"
              paddingLeft="10"
              paddingRight="10"
              gap="10"
              >
              <mx:PrintDataGrid id="printDataGrid" width="60%" height="100%">
                  <!-- Specify the columns to ensure that their order is correct. -->
                  <mx:columns>
                      <mx:DataGridColumn dataField="Index" />
                      <mx:DataGridColumn dataField="Qty" />
                  </mx:columns>
              </mx:PrintDataGrid>
          </s:VGroup>
      </s:Application>

      Application custom skin class:ApplicationSkinCustom.mxml
      ============================================
      <?xml version="1.0" encoding="utf-8"?>
      <!--
      ADOBE SYSTEMS INCORPORATED
      Copyright 2008 Adobe Systems Incorporated
      All Rights Reserved.

       

      NOTICE: Adobe permits you to use, modify, and distribute this file
      in accordance with the terms of the license agreement accompanying it.
      -->

       

      <!--- The default skin class for the Spark Application component.

       

      @see spark.components.Application

       

      @langversion 3.0
      @playerversion Flash 10
      @playerversion AIR 1.5
      @productversion Flex 4
      -->
      <s:Skin
          xmlns:fx="http://ns.adobe.com/mxml/2009"
          xmlns:s="library://ns.adobe.com/flex/spark"
          xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
          alpha.disabled="0.5" alpha.disabledWithControlBar="0.5"
          >
         
          <fx:Metadata>
              <![CDATA[
              /**
              * A strongly typed property that references the component to which this skin is applied.
              */
              [HostComponent("spark.components.Application")]
              ]]>
          </fx:Metadata>
         
          <fx:Script fb:purpose="styling">
              <![CDATA[
                  /**
                   *  @private
                   */
                  override protected function updateDisplayList(unscaledWidth:Number,
                                                                unscaledHeight:Number) : void
                  {
                      bgRectFill.color = getStyle('backgroundColor');
                      super.updateDisplayList(unscaledWidth, unscaledHeight);
                  }
              ]]>
          </fx:Script>
         
          <s:states>
              <s:State name="normal" />
              <s:State name="disabled" />
              <s:State name="normalWithControlBar" />
              <s:State name="disabledWithControlBar" />
          </s:states>
         
          <!-- fill -->
          <!---
          A rectangle with a solid color fill that forms the background of the application.
          The color of the fill is set to the Application's backgroundColor property.
          -->
          <s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0"  >
              <s:fill>
                  <s:SolidColor id="bgRectFill" color="#FFFFFF"/>
              </s:fill>
          </s:Rect>
         
          <s:Scroller left="1" top="1" right="1" bottom="1" id="scroller">
              <s:Group left="0" right="0" top="0" bottom="0">
                  <s:layout>
                      <s:VerticalLayout gap="0" horizontalAlign="justify" />
                  </s:layout>
                 
                  <!---
                  @private
                  Application Control Bar
                  -->
                  <s:Group
                      id="topGroup"
                      minWidth="0"
                      minHeight="0"
                      includeIn="normalWithControlBar, disabledWithControlBar"
                      >
                     
                      <!-- layer 0: control bar highlight -->
                      <s:Rect left="0" right="0" top="0" bottom="1" >
                          <s:stroke>
                              <s:LinearGradientStroke rotation="90" weight="1">
                                  <s:GradientEntry color="0xFFFFFF" />
                                  <s:GradientEntry color="0xD8D8D8" />
                              </s:LinearGradientStroke>
                          </s:stroke>
                      </s:Rect>
                     
                      <!-- layer 1: control bar fill -->
                      <s:Rect left="1" right="1" top="1" bottom="2" >
                          <s:fill>
                              <s:LinearGradient rotation="90">
                                  <s:GradientEntry color="0xEDEDED" />
                                  <s:GradientEntry color="0xCDCDCD" />
                              </s:LinearGradient>
                          </s:fill>
                      </s:Rect>
                     
                      <!-- layer 2: control bar divider line -->
                      <s:Rect left="0" right="0" bottom="0" height="1" alpha="0.55">
                          <s:fill>
                              <s:SolidColor color="0x000000" />
                          </s:fill>
                      </s:Rect>
                     
                      <!-- layer 3: control bar -->
                      <!--- @copy spark.components.Application#controlBarGroup -->
                      <s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
                          <s:layout>
                              <s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="7" paddingBottom="7" gap="10" />
                          </s:layout>
                      </s:Group>
                  </s:Group>
                 
                  <!--- @copy spark.components.SkinnableContainer#contentGroup -->
                  <!--<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" />-->
                  <s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" />
              </s:Group>
          </s:Scroller>
      </s:Skin>

       


        • 1. Re: Is this a PrintDataGrid bug / restriction / my lack of understanding?
          Flex harUI Adobe Employee

          I think you may want to put the PrintDataGrid in a Canvas so you can give it

          any height you want.  Size it so it is tall enough (and maybe call

          validateNow) before submitting the page.

          • 2. Re: Is this a PrintDataGrid bug / restriction / my lack of understanding?
            DilipShah Community Member

            That approach doesn't work. To me it looks like... since this Canvas (I used

            Group since it's a Flex 4 application) is also 'constrained' by the scroller

            in the application screen, the printout is incomplete at the bottom.

             

            Could someone from Adobe respond to this thread? Should I file this as a

            bug?

             

            Dilip

            • 3. Re: Is this a PrintDataGrid bug / restriction / my lack of understanding?
              Flex harUI Adobe Employee

              Last time I checked, I am from adobe.  Post a 20-line test case.

              • 4. Re: Is this a PrintDataGrid bug / restriction / my lack of understanding?
                DilipShah Community Member

                So sorry... didn't mean to offend. Just that I didn't notice 'employee' below your user profile thumbnail.

                 

                I'll make the earlier example even shorter and post it here. That will allow you to recreate the issue.

                 

                Thanks!

                • 5. Re: Is this a PrintDataGrid bug / restriction / my lack of understanding?
                  DilipShah Community Member

                  Steps to reproduce the issue:

                  1. create a new Flex application with the code provided after the last step

                  (PrintTest.mxml is the test application's main file and

                  ApplicationSkinCustom.mxml is the application's custom skin class). Both the

                  files go in the default package

                  2. run the application

                  3. click on 'Fill Grid' button

                  4. click on 'Print' button

                  5. depending on your browser height, it'll print up to 25 rows in a table

                  6. reduce the height of the browser to about 400 pixels

                  7. run the application

                  8. click on 'Fill Grid' button

                  9. click on 'Print' button

                  10. Depending on your browser height, it'll print a few rows but will skip

                  last 10-12 rows from the table

                   

                  PrintTest.mxml

                  ============

                  <?xml version="1.0"?>

                  <s:Application

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

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

                  xmlns:mx="library://ns.adobe.com/flex/mx"

                  initialize="initData();"

                  skinClass="ApplicationSkinCustom"

                  >

                  <s:states>

                    <s:State name="displayState" />

                    <s:State name="printState" />

                  </s:states>

                   

                  <s:VGroup

                    excludeFrom="printState"

                    width="100%"

                    horizontalAlign="center"

                    paddingTop="10"

                    paddingBottom="10"

                    paddingLeft="10"

                    paddingRight="10"

                    gap="10"

                    >

                    <!-- The form that appears on the user's system.-->

                    <mx:Form id="myForm" width="80%">

                     <mx:FormHeading label="Product Information"/>

                     <mx:DataGrid id="myDataGrid" dataProvider="">

                      <mx:columns>

                       <mx:DataGridColumn dataField="Index"/>

                       <mx:DataGridColumn dataField="Qty"/>

                      </mx:columns>

                     </mx:DataGrid>

                     <mx:Text width="100%"

                        text="Specify the number of lines and click Fill Grid first.

                        Then you can click Print."/>

                     <mx:TextInput id="dataItems" text="25"/>

                     <mx:HBox>

                      <mx:Button id="setDP"

                           label="Fill Grid"

                           click="setdgProvider(int(dataItems.text));"/>

                      <mx:Button id="printDG"

                           label="Print"

                           click="doPrint();"/>

                     </mx:HBox>

                    </mx:Form>

                  </s:VGroup>

                   

                  <s:VGroup

                    id="vGroup"

                    includeIn="printState"

                    width="100%"

                    horizontalAlign="center"

                    paddingTop="10"

                    paddingBottom="10"

                    paddingLeft="10"

                    paddingRight="10"

                    gap="10"

                    >

                    <mx:PrintDataGrid id="printDataGrid" width="60%" height="100%">

                     <!-- Specify the columns to ensure that their order is correct. -->

                     <mx:columns>

                      <mx:DataGridColumn dataField="Index" />

                      <mx:DataGridColumn dataField="Qty" />

                     </mx:columns>

                    </mx:PrintDataGrid>

                  </s:VGroup>

                   

                  <fx:Script>

                    <![CDATA[

                     import mx.collections.ArrayCollection;

                     import mx.printing.*;

                   

                    

                     public var dgProvider:ArrayCollection;

                   

                     public var prodIndex:Number;

                   

                     // Data initialization, called when the application initializes.

                     public function initData():void {

                      // Create the data provider for the DataGrid control.

                      dgProvider = new ArrayCollection;

                     }

                   

                     // Fill the dgProvider ArrayCollection with the specified items.

                     public function setdgProvider(items:int):void {

                      // First initialize the index and clear any existing data.

                      prodIndex=1;

                      dgProvider.removeAll();

                   

                      // Fill the ArrayCollection, and calculate a product total.

                      // For simplicity, it increases the Index field value by

                      // 1, and the Qty field by 7 for each item.

                      for (var z:int=0; z<items; z++) {

                       var prod1:Object = {};

                       prod1.Qty = prodIndex * 7;

                       prod1.Index = prodIndex++;

                       dgProvider.addItem(prod1);

                      }

                     }

                   

                     // The function to print the output.

                     public function doPrint():void {

                      currentState = "printState";

                   

                      // Create a FlexPrintJob instance.

                      var printJob:FlexPrintJob = new FlexPrintJob();

                   

                      // Start the print job.

                      if (printJob.start()) {

                       // Set the print view properties.

                       vGroup.width=printJob.pageWidth;

                       vGroup.height=printJob.pageHeight;

                   

                       // Set the data provider of the FormPrintView

                       // component's DataGrid to be the data provider of

                       // the displayed DataGrid.

                       printDataGrid.dataProvider = dgProvider;

                   

                       printJob.addObject(vGroup);

                      }

                      // Send the job to the printer.

                      printJob.send();

                     }

                    ]]>

                  </fx:Script>

                  </s:Application>

                   

                   

                   

                   

                   

                  ApplicationSkinCustom.mxml

                  =======================

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

                  <!--

                  ADOBE SYSTEMS INCORPORATED

                  Copyright 2008 Adobe Systems Incorporated

                  All Rights Reserved.

                   

                  NOTICE: Adobe permits you to use, modify, and distribute this file

                  in accordance with the terms of the license agreement accompanying it.

                  -->

                   

                  <!--- The default skin class for the Spark Application component.

                   

                  @see spark.components.Application

                   

                  @langversion 3.0

                  @playerversion Flash 10

                  @playerversion AIR 1.5

                  @productversion Flex 4

                  -->

                  <s:Skin

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

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

                  xmlns:fb="http://ns.adobe.com/flashbuilder/2009"

                  alpha.disabled="0.5" alpha.disabledWithControlBar="0.5"

                  >

                   

                  <fx:Metadata>

                    <![CDATA[

                    /**

                     

                  • A strongly typed property that references the component to which this

                  skin is applied.

                    */

                    [HostComponent("spark.components.Application")]

                    ]]>

                  </fx:Metadata>

                   

                  <fx:Script fb:purpose="styling">

                    <![CDATA[

                     /**

                       

                  • @private

                      */

                     override protected function updateDisplayList(unscaledWidth:Number,

                                  unscaledHeight:Number) : void

                     {

                      bgRectFill.color = getStyle('backgroundColor');

                      super.updateDisplayList(unscaledWidth, unscaledHeight);

                     }

                    ]]>

                  </fx:Script>

                   

                  <s:states>

                    <s:State name="normal" />

                    <s:State name="disabled" />

                    <s:State name="normalWithControlBar" />

                    <s:State name="disabledWithControlBar" />

                  </s:states>

                   

                  <!-- fill -->

                  <!---

                  A rectangle with a solid color fill that forms the background of the

                  application.

                  The color of the fill is set to the Application's backgroundColor property.

                  -->

                  <s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0"  >

                    <s:fill>

                     <s:SolidColor id="bgRectFill" color="#FFFFFF"/>

                    </s:fill>

                  </s:Rect>

                   

                  <s:Scroller left="1" top="1" right="1" bottom="1" id="scroller">

                    <s:Group left="0" right="0" top="0" bottom="0">

                     <s:layout>

                      <s:VerticalLayout gap="0" horizontalAlign="justify" />

                     </s:layout>

                   

                     <!---

                     @private

                     Application Control Bar

                     -->

                     <s:Group

                      id="topGroup"

                      minWidth="0"

                      minHeight="0"

                      includeIn="normalWithControlBar, disabledWithControlBar"

                      >

                   

                      <!-- layer 0: control bar highlight -->

                      <s:Rect left="0" right="0" top="0" bottom="1" >

                       <s:stroke>

                        <s:LinearGradientStroke rotation="90" weight="1">

                         <s:GradientEntry color="0xFFFFFF" />

                         <s:GradientEntry color="0xD8D8D8" />

                        </s:LinearGradientStroke>

                       </s:stroke>

                      </s:Rect>

                   

                      <!-- layer 1: control bar fill -->

                      <s:Rect left="1" right="1" top="1" bottom="2" >

                       <s:fill>

                        <s:LinearGradient rotation="90">

                         <s:GradientEntry color="0xEDEDED" />

                         <s:GradientEntry color="0xCDCDCD" />

                        </s:LinearGradient>

                       </s:fill>

                      </s:Rect>

                   

                      <!-- layer 2: control bar divider line -->

                      <s:Rect left="0" right="0" bottom="0" height="1" alpha="0.55">

                       <s:fill>

                        <s:SolidColor color="0x000000" />

                       </s:fill>

                      </s:Rect>

                   

                      <!-- layer 3: control bar -->

                      <!--- @copy spark.components.Application#controlBarGroup -->

                      <s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1"

                  minWidth="0" minHeight="0">

                       <s:layout>

                        <s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="7"

                  paddingBottom="7" gap="10" />

                       </s:layout>

                      </s:Group>

                     </s:Group>

                   

                     <!--- @copy spark.components.SkinnableContainer#contentGroup -->

                     <!--<s:Group id="contentGroup" width="100%" height="100%" minWidth="0"

                  minHeight="0" />-->

                     <s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" />

                    </s:Group>

                  </s:Scroller>

                   

                  </s:Skin

                  • 6. Re: Is this a PrintDataGrid bug / restriction / my lack of understanding?
                    Flex harUI Adobe Employee

                    It is a bug in the Flash Player.  I will bring it to their attention.  You

                    will have to parent your print view outside of the scroller.