5 Replies Latest reply on Aug 23, 2009 11:11 PM by emansouri

    Obscure but highly annoying iconFunction problem

    emansouri Level 1

      I have an AdvancedDataGrid that implements a custom iconFunction.

       

      When I style my AdvancedDataGrid via an externally loaded SWF-compiled CSS via the StyleManager, what happens is when a node is opened in the AdvancedDataGrid, all of the icons disappear.  They reappear when the row is moused over but calls to invalidateList(), updateList(), etc. do not return the icons.

       

      When I set the styles via AdvancedDataGrid.setStyle(), this same situation occurs.

       

      This problem effectively shuts down my ability to style my Advanced Data Grid and use the iconFunction method simultaneously which is a major problem for me.

       

      Does this sound like a bug?  Or are there adjustments to my methodology I should be employing here?

        • 1. Re: Obscure but highly annoying iconFunction problem
          Flex harUI Adobe Employee

          Is this happening independently of the unsupported cross-version configuration?  What is in the renderer?  What do the icons consist of?  What does your icon function return?

           

          Alex Harui

          Flex SDK Developer

          Adobe Systems Inc.

          Blog: http://blogs.adobe.com/aharui

          • 2. Re: Obscure but highly annoying iconFunction problem
            emansouri Level 1

            Hello,

             

            Yes I have isolated this behavior in a Flex 4 app and observed it without it being loaded into the Flex 3 container.  By the way a note about my efforts to move my container from Flex 3 to Flex 4 - my container app is quite large and I am using a number of open source and commercial SWCs that I am finding are not necessarily readily working automatically in Flex 4 so I do face a real challenge here.

             

            My dataProvider for my ADG has an icon property which is a ByteArray (which is actually local file system icons transcoded from BitMaps to ByteArray via PNGEncoder returned from AIR via a LocalConnection).  In my iconFunction I take the ByteArray and pass it to a static method in a class that extends BitmapAsset.  I am attaching the class here for reference.

             

            I was able to "solve" my problem in a manner that may not be in the best interest of performance or best practice.  In the class there is a displayLoader method that references the parent UIComponent that the icon ends up being attached to.  I add an event listener listening for the Event.RENDER event and upon encountering it, call invalidateDisplayList() on said UIComponent.  This seems to work and I haven't noticed any performance issues yet even with very large data sets being fed to the ADG.

            • 3. Re: Obscure but highly annoying iconFunction problem
              emansouri Level 1

              Hello,

               

              I was able to isolate this behavior in a Flex 4 app running independently not loaded into the Flex 3 container.  A quick side note about my efforts to evolve my main container from Flex 3 to Flex 4 - the app is very extensive, and it makes use of a number of open source and commercial SWCs and I am finding they do not necessarily readily work in Flex 4 - so I am facing a real dilemma there.  Your unilateral position to classify this scenario as unsupported is very understandable, yet unfortunate and in my humble opinion, worthy of reconsideration in certain circumstances such as mine where I am using the latest Flex 3 SDK and targeting Flash Player 10.

               

              In the iconFunction matter at hand, the dataProvider for my ADG has an icon property and the icon property is a ByteArray (which is actually local file system icons returned from AIR transcoded from BitMaps to ByteArrays via PNGEncoder).

               

              I was able to "solve" the problem though it may not address the best interest of performance or be a best practice solution.

               

              The iconFunction passes the ByteArray to a static method on a class that extends BitmapAsset.  I have tried to attach the class here but the board wouldn't let me.  I'll try again and if I still can't attach I'll copy and paste the code in a follow-up reply.  In the code you'll see a displayLoader() method.  It references the parent UI Component that the icon actually gets attached to.  I attach an event listener to the Event.RENDER events on the UIComponent and upon encountering them, call invalidateDisplayList() on the UIComponent.

               

              This seems to work OK and I haven't seen any breakdown in performance even with a very large dataProvider on the ADG but I am a bit weary here.

              • 4. Re: Obscure but highly annoying iconFunction problem
                emansouri Level 1

                Sorry for the double - (triple) reply here.  In my first reply I tried to attach an AS class file and was rejected but apparently the post still posted.  Below is the text of the referenced class:

                 

                package com.ucompass.educator2.filemanagerwindow.utils
                {
                    import flash.display.BitmapData;
                    import flash.display.Loader;
                    import flash.events.Event;
                    import flash.geom.Matrix;
                    import flash.system.LoaderContext;
                    import flash.utils.ByteArray;
                    import flash.utils.Dictionary;
                   
                    import mx.controls.advancedDataGridClasses.AdvancedDataGridGroupItemRenderer;
                    import mx.core.BitmapAsset;
                    import mx.core.UIComponent;

                 

                    /**
                     * <code>IconUtility</code> is a very useful class that enables an image as a <code>ByteArray</code>
                     * instance to serve as an icon where a <code>Class</code> instance is normally expected.
                     */
                    public class IconUtility extends BitmapAsset
                    {

                 

                        private static var dictionary:Dictionary;
                       
                        public function IconUtility()
                        {
                            addEventListener(Event.ADDED,addedHandler);
                        }
                       
                        public static function getClass(source:ByteArray):Class
                        {
                           
                            if(!dictionary)
                            {
                                dictionary = new Dictionary(false);
                            }
                           
                            var loader:Loader = new Loader();
                            loader.loadBytes(source,new LoaderContext(false));
                            dictionary[source] = loader;
                            return IconUtility;
                        }
                       
                        private function addedHandler(event:Event):void
                        {
                            var dataField:AdvancedDataGridGroupItemRenderer = parent as AdvancedDataGridGroupItemRenderer;
                            getData(dataField);
                        }
                       
                        private function getData(dataField:AdvancedDataGridGroupItemRenderer):void
                        {
                            var ba:ByteArray = dataField.data.icon;
                            var loader:Loader = dictionary[ba];
                            loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler,false,0,true);
                        }
                       
                        private function completeHandler(event:Event):void
                        {
                            displayLoader(event.target.loader as Loader);
                        }
                       
                        private function displayLoader(loader:Loader):void
                        {
                            if(!bitmapData) {
                                // bitmapData = new BitmapData(loader.content.width, loader.content.height, true, 0x00FFFFFF);
                                bitmapData = new BitmapData(18,18, true, 0x00FFFFFF);
                            }
                            bitmapData.draw(loader, new Matrix(bitmapData.width/loader.width, 0, 0, bitmapData.height/loader.height, 0, 0));
                            if(parent is UIComponent) {
                                var component:UIComponent = parent as UIComponent;
                                component.invalidateSize();
                                // flash.utils.setInterval(component.invalidateDisplayList,100);
                                component.addEventListener(Event.RENDER,renderEvent);
                               
                                // this is required for the icon to be able to be clicked on
                                parent.mouseEnabled = true;

                 

                            }

                 

                        }
                       
                        private function renderEvent(event:Event):void
                        {
                            event.target.invalidateDisplayList();
                        }

                 

                    }
                }

                • 5. Re: Obscure but highly annoying iconFunction problem
                  Flex harUI Adobe Employee

                  Hard to say without digging through a full test case, but one common problem when loading external icons is that they are not fully baked until a frame after the Complete event and thus won't have valid measurements until then.

                   

                  Alex Harui

                  Flex SDK Developer

                  Adobe Systems Inc.

                  Blog: http://blogs.adobe.com/aharui