4 Replies Latest reply on Jul 18, 2010 1:44 PM by Kyle-Said

    Resize Image with Scroller causing 1502 exception

    Kyle-Said

      Description:

      I'm loading an image inside of a border container and when i zoom out, the scroll bars disappear as expected. Now when I resize the image to exceed the boundaries of the boarder container I receive the exception below. I believe the exception is thrown when the scroll bars are reactivating but i could be wrong. Has anyone seen this before

       

      Exception:

       

      Error: Error #1502: A script has executed for longer than the default timeout period of 15 seconds.
      at spark.components.supportClasses::ScrollBarBase/get viewport()
      at spark.components::VScrollBar/updateMaximumAndPageSize()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\components\VScrollBar.as:123]
      at spark.components::VScrollBar/http://www.adobe.com/2006/flex/mx/internal::viewportResizeHandler()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\components\VScrollBar.as:390]
      at flash.events::EventDispatcher/dispatchEventFunction()
      at flash.events::EventDispatcher/dispatchEvent()
      at mx.core::UIComponent/dispatchEvent()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:12266]
      at mx.core::UIComponent/dispatchResizeEvent()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:9641]
      at mx.core::UIComponent/setActualSize()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:9172]
      at spark.components::Group/setActualSize()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\components\Group.as:891]
      at mx.core::LayoutElementUIComponentUtils$/setLayoutBoundsSize()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\LayoutElementUIComponentUtils.as:497]
      at mx.core::UIComponent/setLayoutBoundsSize()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:13069]
      at spark.components.supportClasses::ScrollerLayout/updateDisplayList()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\components\supportClasses\ScrollerLayout.as:546]
      at spark.components.supportClasses::GroupBase/updateDisplayList()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\components\supportClasses\GroupBase.as:1224]
      at spark.components::Group/updateDisplayList()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\components\Group.as:899]
      at spark.skins::SparkSkin/updateDisplayList()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\skins\SparkSkin.as:191]
      at mx.core::UIComponent/validateDisplayList()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:8531]
      at mx.managers::LayoutManager/validateDisplayList()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:663]
      at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:736]
      at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1072]
      at flash.utils::Timer/_timerDispatch()
      at flash.utils::Timer/tick()
      
      

       

       

      MXML Code:

       

       

      <?xml version="1.0" encoding="utf-8"?>
      <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"
                        xmlns:ns1="com.adobe.wheelerstreet.fig.panzoom.*"
                        pageTitle="FileNet Flex Viewer"
                        minWidth="955" 
                        minHeight="600" 
                        creationComplete="init()">
           <fx:Style>
                @namespace s "library://ns.adobe.com/flex/spark";
                @namespace mx "library://ns.adobe.com/flex/mx";
                /*
                s|Application {
                backgroundGradientColors: #000000, #222222;
                }          
                */
                s|Button#zoomInButton {          
                     skinClass: ClassReference("skins.ZoomIn");
                }
                
                s|Button#zoomOutButton {          
                     skinClass: ClassReference("skins.ZoomOut");
                }
                
                s|Button#fitToWindowButton {          
                     skinClass: ClassReference("skins.FitToWindow");
                }
                
                s|Button#fitToWidthButton {          
                     skinClass: ClassReference("skins.FitToWidth");
                }
                
                s|Button#fitToHeightButton {          
                     skinClass: ClassReference("skins.FitToHeight");
                }
                
                s|Button#rotateRightButton {          
                     skinClass: ClassReference("skins.RotateRight");
                }
                
                s|Button#rotateLeftButton {          
                     skinClass: ClassReference("skins.RotateLeft");
                }
                
                s|ToggleButton#rubberBandZoomButton {          
                     skinClass: ClassReference("skins.RubberBand");
                }
                
                
                
           </fx:Style>
           
           <fx:Declarations>
                <!-- Place non-visual elements (e.g., services, value objects) here 
                <s:Rotate id="rotator" angleFrom="{angle-90}" angleTo="{angle}" target="{img}"/>
                -->
                <s:Resize id="resize" target="{img}"/>
                <s:Rotate id="rotate" target="{img}"/>
                <!--<s:Resize id="contract" target="{img}"/> -->
           </fx:Declarations>
           
           
           <fx:Script>
                <![CDATA[
                     
                     import flash.net.navigateToURL;
                     
                     import mx.controls.Alert;
                     
                     [Bindable]
                     private var _imageURL:String = "images/earth-map_small.jpg";
                     
                     [Bindable]
                     public var angle:Number = 0;
                          
                     [Bindable]
                     private var borderHeight:Number;
                     
                     [Bindable]
                     private var borderWidth:Number;
                     
                     private var effectDuration:Number = 250;
                     private var defaultRotation:Number = 90;
                     
                     private var profits:Array;
                     private var dragStart:Point;
                     private var dragEnd:Point;
                     private var zoomingEnabled:Boolean;
                     
                     public var originalHeight:Number;
                     public var originalWidth:Number;
                     
                     public function init():void{
                          originalHeight = img.height;
                          originalWidth = img.width;
                          borderHeight = borderContainer.height - 5;
                          borderWidth = borderContainer.width - 5;
                     }
                     
                     
                     public function fitToWindow():void{
                          resize.end();
                          resize.duration = effectDuration;
                          
                          if(img.rotation == defaultRotation || img.rotation == -defaultRotation){     
                               resize.heightTo = borderWidth;
                               resize.widthTo = borderHeight;
                          }
                          else{
                               resize.heightTo = borderHeight;
                               resize.widthTo = borderWidth;
                          }
                          
                          resize.play();
                     }
                     
                     public function fitToWidth():void{
                          resize.end();
                          resize.duration = effectDuration;
                          
                          if(img.rotation == defaultRotation || img.rotation == -defaultRotation){
                               resize.heightTo = borderWidth;
                          }
                          else{
                               resize.widthTo = borderWidth;
                          }
                          
                          resize.play();
                     }
                     
                     public function fitToHeight():void{
                          resize.end();
                          resize.duration = effectDuration;
                          
                          if(img.rotation == defaultRotation || img.rotation == -defaultRotation){
                               resize.widthTo = borderHeight;
                          }
                          else{
                               resize.heightTo = borderHeight;
                          }
                          
                          resize.play();
                     }
                     
                     public function zoomIn():void{
                          resize.end();
                          resize.duration = effectDuration;
                          resize.heightTo = img.height*2;
                          resize.widthTo = img.width*2;
                          resize.play();
                          
                     }
                     
                     public function zoomOut():void{
                          resize.end();
                          resize.duration = effectDuration;
                          resize.heightTo = img.height/2;
                          resize.widthTo = img.width/2;
                          resize.play();
                     }
                     
                     public function rotateRight():void{
                          rotate.end();
                          rotate.duration = effectDuration-200;
                          rotate.angleFrom = angle;
                          rotate.angleTo = (angle += defaultRotation);
                          rotate.play();
                     }
                     
                     public function rotateLeft():void{                    
                          rotate.end();
                          rotate.duration = effectDuration-200;
                          rotate.angleFrom = angle;
                          rotate.angleTo = (angle -= defaultRotation);
                          rotate.play();
                     }
                     
      
                     private function initRectangle(e:MouseEvent):void{
                          
                     }
                     
                     private function showShowRectangle(e:MouseEvent):void{
      
                     }
                     
                     private function clearRectangle(e:MouseEvent):void{
      
                     }
                     
                     
                ]]>
           </fx:Script>
           
           <s:Panel
                id="mainPanel"
                left="5" 
                right="5" 
                top="5" 
                bottom="5" 
                title="FileNet Flex Viewer" 
                fontWeight="bold">
                
                
                <mx:ApplicationControlBar dock="true" top="0" left="0" right="0">
                     <s:Button 
                          id="zoomInButton"
                          toolTip="Zoom In"
                          click="{zoomIn();}"
                          />
                     <s:Button 
                          id="zoomOutButton"
                          toolTip="Zoom Out"
                          click="{zoomOut();}"
                          />
                     <s:Button 
                          id="fitToWindowButton"
                          toolTip="Fit To Window"
                          click="{fitToWindow();}"
                          />
                     <s:Button 
                          id="fitToWidthButton"
                          toolTip="Fit To Width"
                          click="{fitToWidth();}"
                          />
                     <s:Button 
                          id="fitToHeightButton"
                          toolTip="Fit To Height"
                          click="{fitToHeight();}"
                          />
                     <s:Button 
                          id="rotateRightButton"
                          toolTip="Rotate Right"
                          click="{rotateRight();}"
                          />
                     <s:Button 
                          id="rotateLeftButton"
                          toolTip="Rotate Left"
                          click="{rotateLeft();}"
                          />
                     <!--<s:ToggleButton 
                          id="rubberBandZoomButton"
                          toolTip="Rubber Band Zoom"
                          click="{}"
                          />
                     -->
                </mx:ApplicationControlBar>
                
                <s:BorderContainer 
                     id="borderContainer"
                     right="5" 
                     left="5" 
                     top="40" 
                     bottom="5">
                     
                     <s:Scroller
                          width="100%"
                          height="100%">
                          <s:Group>
                               <mx:Image 
                                    id="img"
                                    maintainAspectRatio="false"
                                    maintainProjectionCenter="true"
                                    source="@Embed('images/earth-map_small.jpg')"
                                    verticalCenter="0"
                                    horizontalCenter="0" 
                                    horizontalAlign="center" 
                                    verticalAlign="middle"/>
                          </s:Group>
                     </s:Scroller>
                </s:BorderContainer>
           </s:Panel>
           
      </s:Application>
      
       
      
        • 1. Re: Resize Image with Scroller causing 1502 exception
          Shongrunden Adobe Employee

          It looks like you're running into a Scroller looping bug.  I was unable to reproduce this consistently with your current code sample.  Can you please try to simplify your code sample to consistently demonstrate the issue so we can investigate further?

          • 2. Re: Resize Image with Scroller causing 1502 exception
            Kyle-Said Level 1

            I'm not sure that i can simplify this code any more than it already is. I'm able to reproduce this issue 90% of the time with the following test script....

             

            1) The source image should be a high resolution image.

            2) Invoke the zoomOut() function until the scroll bars disappear.

            3) Invoke the zoomIn() button until the scroller SHOULD appear. This is where i'm hitting an infinite loop with the scrollers.

             

            - I'll also investigate whether i'm hitting the maximum resolution of 2880x2880 pixels.

            • 3. Re: Resize Image with Scroller causing 1502 exception
              Shongrunden Adobe Employee

              I believe this reduced version demonstrates the issue consisently (JPG attached):

              <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">
                 
                  <fx:Script>
                      <![CDATA[
                          public function fitToWindow():void{
                              img.height = borderContainer.height;
                              img.width = borderContainer.width;
                          }
                      ]]>
                  </fx:Script>
                 
                  <s:controlBarContent>
                      <s:Button label="fit to window" click="{fitToWindow()}" />
                  </s:controlBarContent>
                 
                  <s:BorderContainer id="borderContainer" width="955" height="600">
                      <s:Scroller width="100%" height="100%">
                          <s:Group>
                              <mx:Image id="img" source="@Embed('DSC00074.jpg')"
                                   horizontalCenter="0" verticalCenter="0" />
                          </s:Group>
                      </s:Scroller>
                  </s:BorderContainer>
                 
              </s:Application>

               

              Looks like the interaction of verticalCenter/horizontalCenter with the adding/removing of scrollbars is causing looping.  Can you please file a bug and post the link here?  (Or let me know if you would rather that I file it).

               

              The workarounds are:

               

              1. In the fitToWindow() method subtract enough pixels to account for both border sides, for example:

                          public function fitToWindow():void{
                              img.height = borderContainer.height - 2;
                              img.width = borderContainer.width - 2;
                          }

              2. Always keep the scrollbars shown, for example:

              <s:Scroller width="100%" height="100%" verticalScrollPolicy="on" horizontalScrollPolicy="on">

              3. Instead of using BorderContainer use a SkinnableContainer/Group and draw the border outside of that container, for example:

                  <s:Group  width="955" height="600">
                      <s:Rect width="100%" height="100%">
                          <s:fill>
                              <s:SolidColor color="black" />
                          </s:fill>
                      </s:Rect>
                
                      <s:SkinnableContainer id="borderContainer" backgroundColor="white" top="1" left="1" right="1" bottom="1">
                          <s:Scroller width="100%" height="100%">
                              <s:Group>
                                  <mx:Image id="img" source="@Embed('DSC00074.jpg')"
                                       horizontalCenter="0" verticalCenter="0" />
                              </s:Group>
                          </s:Scroller>
                      </s:SkinnableContainer>
                  </s:Group>

               

              Let me know if these workarounds for the reduced case also work for your application.

              • 4. Re: Resize Image with Scroller causing 1502 exception
                Kyle-Said Level 1

                Thanks for the help. I filed the following defect....

                 

                http://bugs.adobe.com/jira/browse/SDK-26993