'Progressbar in Datagrid Example'에 해당되는 글 1건

  1. 2013.07.24 [펌] Progressbar in Datagrid Example
반응형

Progressbar in Datagrid Example

Line Break

Author: Roelof (13 Articles) - Author Website

Roelof is a SAP Consultant specialized in Front-End development. In his spare free time he is either developing on the web, playing basketball, watching soccer or traveling. He is also the co-owner of Flex-Blog.com.


In the comments of our previous post about using the ProgressBar, one of our readers asked if a ProgressBar could be used inside a DataGrid.

This is, ofcourse, possible. So we decided to write an example about this.

There are a couple of things you need to know before we start:

  1. Use an ItemRenderer to show the ProgressBar inside the DataGrid instead of text.
  2. Create a DataProvider for the DataGrid (in our case we use an ArrayCollection).
  3. Create an action to start the ProgressBar (in our case we simulate a download).
  4. Make sure the ArrayCollection is updated on every progress of the ProgressBar.

First we create an ItemRenderer in a seperate ActionScript file (myProgressBar.as):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package
{
    import mx.containers.HBox;
    import mx.controls.ProgressBar;
    import mx.controls.dataGridClasses.*;

    public class myProgressBar extends HBox
    //This should normally be extends ProgressBar, we are using HBox to have more control over the layout.
    {
        private var pb:ProgressBar;
       
        public function myProgressBar():void {
            //Create new ProgressBar Instance
            pb = new ProgressBar();
            //Set some layout things
            pb.mode = "manual";
            pb.percentWidth = 100;         
            pb.labelPlacement = "center";
            this.setStyle("verticalAlign","middle");
            //Add ProgressBar as child
            addChild(pb);
        }
       
        override public function set data(value:Object):void
        {
            super.data = value;
        }  
       
        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void{
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            pb.setProgress(data.loaded, data.total);
        }
    }
}

Then we will use this ItemRenderer inside the DataGrid column.

1
<mx:DataGridColumn itemRenderer="myProgressBar" dataField="progress" headerText="Progress" width="180" paddingLeft="5"/>

To start the ‘fake’ ProgressBar download progress, we are using an Image as a Button inside the DataGrid.

1
2
3
4
5
6
7
8
9
10
            <mx:DataGridColumn width="112" headerText="Download">
                <mx:itemRenderer>
                    <fx:Component>
                        <mx:HBox horizontalAlign="center" verticalAlign="middle">    
                            <s:Label text="{data.file}"/>
                            <mx:Image buttonMode="true" toolTip="'Download'" click="outerDocument.downloadFile()" source="@Embed(source='images/down_alt.png')"/>
                        </mx:HBox>
                    </fx:Component>
                </mx:itemRenderer>             
            </mx:DataGridColumn>

Why use outerDocument?
Since the itemRenderer is within another Component, we need to use outerDocument to call a method inside your ‘main’ Component.

Next step was to implement the method downloadFile():

1
2
3
4
5
6
7
            public function downloadFile():void{
                //start timer
                var timer:Timer = new Timer(500);
                // add event listener
                timer.addEventListener(TimerEvent.TIMER, updateProgressBar);
                timer.start();             
            }

Next, implement the eventListener. Inside the eventListener we need to make sure the DataGrid / ArrayCollection gets updated.

1
2
3
4
5
6
7
            private function updateProgressBar(event:TimerEvent):void{
                var myItem:Object
                // Add a 'random' number to loaded. To fake the progress..
                myDataGrid.selectedItem.loaded += Math.ceil(Math.random() * 5);
                //refesh arraycollection to refresh the datagrid
                myArrayCollection.refresh();               
            }

Then you are done. Below you will find a working example. For the full source code either use Right Mouse Click -> View Source or scroll down.

Full Source Code:
ProgressBarInsideDatagridExample.mxml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?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/halo" width="500"  height="200" initialize="init();" viewSourceURL="srcview/index.html">

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
           
            [Bindable]private var myArrayCollection:ArrayCollection;
           
            private function init():void {
                // Create instance of myArrayCollection
                myArrayCollection = new ArrayCollection;
                // Create new Object
                var obj:Object = new Object;
               
                obj.file = "File 1";
                obj.total = 100;
                obj.loaded = 0;
                // Add object to myArrayCollection
                myArrayCollection.addItem(obj);
                obj = new Object;
                obj.file = "File 2";
                obj.total = 100;
                obj.loaded = 0;
                // Add object to myArrayCollection
                myArrayCollection.addItem(obj);
            }

            public function downloadFile():void{
                //start timer
                var timer:Timer = new Timer(500);
                // add event listener
                timer.addEventListener(TimerEvent.TIMER, updateProgressBar);
                timer.start();             
            }

            private function updateProgressBar(event:TimerEvent):void{
                var myItem:Object
                // Add a 'random' number to loaded. To fake the progress..
                myDataGrid.selectedItem.loaded += Math.ceil(Math.random() * 5);
                //refesh arraycollection to refresh the datagrid
                myArrayCollection.refresh();               
            }
           
           
        ]]>
    </fx:Script>
   
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->    
    </fx:Declarations>
   
    <mx:DataGrid id="myDataGrid" height="200" width="500" dataProvider="{myArrayCollection}">
        <mx:columns>
            <mx:DataGridColumn width="112" headerText="Download">
                <mx:itemRenderer>
                    <fx:Component>
                        <mx:HBox horizontalAlign="center" verticalAlign="middle">    
                            <s:Label text="{data.file}"/>
                            <mx:Image buttonMode="true" toolTip="'Download'" click="outerDocument.downloadFile()" source="@Embed(source='images/down_alt.png')"/>
                        </mx:HBox>
                    </fx:Component>
                </mx:itemRenderer>             
            </mx:DataGridColumn>
           
            <mx:DataGridColumn itemRenderer="myProgressBar" dataField="progress" headerText="Progress" width="180" paddingLeft="5"/>
        </mx:columns>          
    </mx:DataGrid>
   
</s:Application>

myProgressBar.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package
{
    import mx.containers.HBox;
    import mx.controls.ProgressBar;
    import mx.controls.dataGridClasses.*;

    public class myProgressBar extends HBox
    //This should normally be extends ProgressBar, we are using HBox to have more control over the layout.
    {
        private var pb:ProgressBar;
       
        public function myProgressBar():void {
            //Create new ProgressBar Instance
            pb = new ProgressBar();
            //Set some layout things
            pb.mode = "manual";
            pb.percentWidth = 100;         
            pb.labelPlacement = "center";
            this.setStyle("verticalAlign","middle");
            //Add ProgressBar as child
            addChild(pb);
        }
       
        override public function set data(value:Object):void
        {
            super.data = value;
        }  
       
        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void{
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            pb.setProgress(data.loaded, data.total);
        }
    }
}

 

Posted by 1010