PDA

View Full Version : Scrollbars & Code structure - Actionscript 3.0



MichaelxxOA
December 31st, 2006, 04:21 PM
So this thread actually began from another thread, I am just moving it over here... I got asked to write a tutorial about this, is anyone else interested?

The purpose of this thread is more about the code design then it is about the functionality although this is a very practical and very usable solution.

Scrooooooooooollbars

A scrollbar isn't nearly as much as people assume it to be. In fact a scrollbar can be broken down into a composite of a few simpler components.

The approach here is to make this as abstract as possible. First thoughts should be focusing on what a scrollbar is and what a scrollbar isn't. This is important because it relates directly to the complexity of our design. If we couple together a scrollbar with content we have to design specifically for that. Instead we need to assume less.


Scrollbars and Sliders

At the core of just about every scrollbar is the slider. A slider can be described as a track and a marker. The marker can be dragged along the length of the track where it's position along the track is the visual representation of some percentage that we can read and write.

To promote a more flexible design we will be decoupling the way in which anything becomes aware of the scrollbar. Instead of the scrollbar modifying an object based on it's percentage we will instead notify objects that the scrollbar has changed, providing them with the new percentage.

At this point we are discussing two agents in the design, a slider (which is itself a component that can be used 100% independently of the scrollbar ), and the event which our slider will broadcast.

These can be defined programatically as Slider and SliderEvent with the following classes:

Slider


package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Rectangle;

/**
* Represents the base functionality for Sliders.
*
* Broadcasts 1 event:
* -SliderEvent.CHANGE
*/
public class Slider extends Sprite
{
// elements
protected var track:Sprite;
protected var marker:Sprite;

// percentage
protected var percentage:Number = 0;
/**
* The percent is represented as a value between 0 and 1.
*/
public function get percent():Number { return percentage; }
/**
* The percent is represented as a value between 0 and 1.
*/
public function set percent( p:Number ):void
{
percentage = Math.min( 1, Math.max( 0, p ) );
marker.y = percentage * (track.height - marker.height);

dispatchEvent( new SliderEvent( SliderEvent.CHANGE, percentage ) );
}

/**
* Constructor
*/
public function Slider()
{
createElements();
}

// ends the sliding session
protected function stopSliding( e:MouseEvent ):void
{
marker.stopDrag();
stage.removeEventListener( MouseEvent.MOUSE_MOVE, updatePercent );
stage.removeEventListener( MouseEvent.MOUSE_UP, stopSliding );
}
// updates the data to reflect the visuals
protected function updatePercent( e:MouseEvent ):void
{
e.updateAfterEvent();
percentage = marker.y / (track.height - marker.height);

dispatchEvent( new SliderEvent( SliderEvent.CHANGE, percentage ) );
}

// Executed when the marker is pressed by the user.
protected function markerPress( e:MouseEvent ):void
{
marker.startDrag( false, new Rectangle( 0, 0, 0, track.height - marker.height ) );
stage.addEventListener( MouseEvent.MOUSE_MOVE, updatePercent );
stage.addEventListener( MouseEvent.MOUSE_UP, stopSliding );
}

/**
* Creates and initializes the marker/track elements.
*/
protected function createElements():void
{
track = new Sprite();
marker = new Sprite();

track.graphics.beginFill( 0xCCCCCC, 1 );
track.graphics.drawRect(0, 0, 10, 100);
track.graphics.endFill();

marker.graphics.beginFill( 0x333333, 1 );
marker.graphics.drawRect(0, 0, 10, 15);
marker.graphics.endFill();

marker.addEventListener( MouseEvent.MOUSE_DOWN, markerPress );

addChild( track );
addChild( marker );
}
}
}


SliderEvent


package
{
import flash.events.Event;

public class SliderEvent extends Event
{
// events
public static const CHANGE:String = "change";

protected var percentage:Number;
/**
* Read-Only
*/
public function get percent():Number
{
return percentage;
}

/**
* Constructor
*/
public function SliderEvent( type:String, percent:Number )
{
super( type );
percentage = percent;
}
}
}


This code should be failry intuitive and require very little explanation if at all, so if there is something that is not understood, please ask and I will explain it.

Scrollbars

Since scrollbars are a composite of simpler components, the definition of a scrollbar is going to simply manage these components. We will talk about this design before showing the code.

Think about what differentiates a scrollbar and a slider (minus the context within which they operate). In data scrollbars and sliders represent the same thing, some percentage. The difference is the means in which the percentage can be modified.

A slider has a marker and a track, where the marker's position is the 'visual' representation of the slider's percentage. This marker can be dragged, allowing the user to modify the percentage.

A scrollbar is everything that a slider is in addition to allowing the user to press 'arrows' that increment/decrement the percentage by some predefined or calculated amount. You can remember in the design of the slider we allowed ourselves a means of modifying a sliders percentage programatically. This flexibility is what will allow us to implement the scrollbar.

Since what the scrollbar and slider represent in data are the same thing, we can use the same means of notifying a listener about changes in data. So our scrollbar class will be used merely to encapsulate the composition of the arrows and track. Remember that the way in which we notify the objects is the same, as a note instead of re-broadcasting the events we will simply register listeners for the Slider directly.

A simple implementation of the Scrollbar follows.

Scrollbar


package
{
import flash.display.Sprite;
import flash.events.MouseEvent;

public class Scrollbar extends Sprite
{
// elements
protected var slider:Slider;
protected var up_arrow:Sprite;
protected var down_arrow:Sprite;

protected var scrollSpeed:Number = .1;

// read/write percentage value relates directly to the slider
public function get percent():Number { return slider.percent; }
public function set percent( p:Number ):void { slider.percent = p; }

/**
* Constructor
*/
public function Scrollbar()
{
createElements();
}

// executes when the up arrow is pressed
protected function arrowPressed( e:MouseEvent ):void
{
var dir:int = (e.target == up_arrow) ? -1 : 1;
slider.percent += dir * scrollSpeed;
}

/**
* Create and initialize the slider and arrow elements.
*/
protected function createElements():void
{
slider = new Slider();

up_arrow = new Sprite();
up_arrow.graphics.beginFill( 0x666666, 1 );
up_arrow.graphics.drawRect( 0, 0, 10, 10 );
up_arrow.graphics.endFill();

down_arrow = new Sprite();
down_arrow.graphics.beginFill( 0x666666, 1 );
down_arrow.graphics.drawRect( 0, 0, 10, 10 );
down_arrow.graphics.endFill();

slider.y = up_arrow.height;
down_arrow.y = slider.y + slider.height;

up_arrow.addEventListener( MouseEvent.MOUSE_DOWN, arrowPressed );
down_arrow.addEventListener( MouseEvent.MOUSE_DOWN, arrowPressed );

addChild( slider );
addChild( up_arrow );
addChild( down_arrow );
}

/**
* Override the add and remove event listeners, so that SliderEvent.CHANGE events will be
* subscribed to the Slider directly.
*
* There is issues with this however, Event.CHANGE events will get subscribed directly too Slider as well.
*/
public override function addEventListener( type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false ):void
{
if ( type === SliderEvent.CHANGE )
{
slider.addEventListener( SliderEvent.CHANGE, listener, useCapture, priority, useWeakReference );
return;
}
super.addEventListener( type, listener, useCapture, priority, useWeakReference );
}
public override function removeEventListener( type:String, listener:Function, useCapture:Boolean=false ):void
{
if ( type === SliderEvent.CHANGE )
{
slider.removeEventListener( SliderEvent.CHANGE, listener, useCapture );
return;
}
super.removeEventListener( type, listener, useCapture );
}
}
}


Once again this code should be failry intuitive, but I will actually go over this one.

Pretty much all we are doing here is creating the slider and the arrows and assigning their functionality. When either of the arrows are pressed the arrowPressed method gets invoked, we see which arrow was pressed, then we update the slider accordingly. The slider retains all of it's previous functionality... because we haven't touched it.

So now we have all of this... but still, it's really not a scrollbar.

Content?

This part is by far the easiest, and can be thought of as yet another abstraction. We can build a ScrollContent class that is a composition of a scrollbar and some content.

We will assume that all content wishing to be scrolled is a Sprite. We will utilize various properties of the sprite to set up the scroll. The method in which we will scroll the content is simple and is explained in this post: http://www.createage.com/blog/?p=105.

Here is a simple implementation of the ScrollContent class.

ScrollContent


package
{
import flash.display.Sprite;
import flash.geom.Rectangle;

public class ScrollContent extends Sprite
{
// elements
protected var content:Sprite;
protected var scrollbar:Scrollbar;
protected var contentHeight:Number;

/**
* Constructor
*/
public function ScrollContent( clip:Sprite, scroller:Scrollbar, scrollRect:Rectangle )
{
content = clip;
contentHeight = clip.height;
content.scrollRect = scrollRect;

scrollbar = scroller;

scrollbar.addEventListener( SliderEvent.CHANGE, updateContent );
}

public function updateContent( e:SliderEvent ):void
{
var scrollable:Number = contentHeight - content.scrollRect.height;
var sr:Rectangle = content.scrollRect.clone();

sr.y = scrollable * e.percent;

content.scrollRect = sr;
}
}
}


You can see that this is yet again another simple abstraction. It was a little more of a process to get started, but once complete you have a very flexible, very reusable base from which you can implement many different kinds of scrolling components.

The main class that was used to test this follows (it's simple, you shouldn't have an issue understanding it).

ScrollbarExample


package {
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;

public class ScrollbarExample extends Sprite
{
public function ScrollbarExample()
{
var content:Sprite = new Sprite();
var scrollbar:Scrollbar = new Scrollbar();
var scroll_rect:Rectangle = new Rectangle( 0, 0, 100, 50 );

content.graphics.beginFill( 0xFF0000, 1 );
content.graphics.drawRect( 0, 0, 100, 50 );
content.graphics.beginFill( 0x00FF00, 1 );
content.graphics.drawRect( 0, 50, 100, 50 );
content.graphics.beginFill( 0x0000FF, 1 );
content.graphics.drawRect( 0, 100, 100, 50 );
content.graphics.endFill();

var rect:Rectangle = new Rectangle( 0, 0, 100, 50 );
var sc:ScrollContent = new ScrollContent( content, scrollbar, rect );

scrollbar.x = content.width;

addChild( content );
addChild( scrollbar );
}
}
}


Take care, if anyone has any questions I will do my best to answer as quickly as I can.

Michael

devonair
January 1st, 2007, 05:37 AM
Playing around with this now.. Cool stuff..


(you should post this over at SP as well...)

stringy
January 1st, 2007, 08:23 AM
great stuff. Thanks for sharing :)

mprzybylski
January 1st, 2007, 02:13 PM
i wouldnt mind reading a tutorial about it.

devonair, whats SP?

sepu
January 1st, 2007, 05:13 PM
thanks for sharing ! very nice stuff! :crazy:

MichaelxxOA
January 1st, 2007, 08:38 PM
From talking to a couple people now it seems that you guys would prefer me talking about design then the actual scrollbars. So I'm thinking that instead of re-writing this all fancy (as it's pretty clear and to the point right now), I will put together an Introduction to Software Design write up, and maybe an advanced one if I ever find the time.

Is this preferred? If so I would like to talk to you guys about what you'd really like to hear about.

Looking forward to hearing from you guys.
Michael

devonair
January 3rd, 2007, 12:06 PM
I don't think the two things are mutually exclusive. I definitely think the Flash community needs more tutorials on general design over specific effects, etc. It's always easier to make sense of theory with concrete examples though, so putting the two together I think would make for a very good read. But that's just me.. :)




devonair, whats SP?

SP = ShavedPlatypus - a much smaller forum than Kirupa, but fairly tight knit and friendly. MichaelxxOA is a member over there...

MichaelxxOA
January 3rd, 2007, 03:02 PM
I don't think the two things are mutually exclusive. I definitely think the Flash community needs more tutorials on general design over specific effects, etc. It's always easier to make sense of theory with concrete examples though, so putting the two together I think would make for a very good read. But that's just me.. :)





SP = ShavedPlatypus - a much smaller forum than Kirupa, but fairly tight knit and friendly. MichaelxxOA is a member over there...

I haven't been to SP in a while, I will be sure to start making my way over there soon. I'm just so darn cut for time right now it's rediculous.

And I also agree with what you are saying. I have every intent on using an example project to work through, I just don't want to use something like this which already has a fairly decent explanation.

Make sense? What kind of simple framework do you guys want to see?

Michael

Michael

agilius
January 4th, 2007, 03:43 AM
Nice and usefull. Thx for sharing. I'll play with this asap! :D

herk
May 5th, 2007, 04:58 PM
hi, thanks for sharing the code :)

i wanted to have the slider.marker and slider.track auto adjustable to the content, so i have added the following code on the ScrollbarExample Class.



//change track and marker acording to content
scrollbar.slider.track.height = rect.height - 20;
scrollbar.slider.marker.height = Math.round( ( rect.height / content.height ) * 100 ) ;
i also had to change the corresponding properties and methods in the Slider and Scrollbar Classes to public, so i can access them from the ScrollbarExample Class.

dail
June 21st, 2007, 05:16 PM
Pretty interesting code example.

I understand how the AS is working, but I'm totally new to AS3 and more so to classes. So, where to I place each of the AS samples you have provided to get this to work?

toniabc
July 23rd, 2007, 01:32 PM
Hi!

I have textField that I scroll with your class but when I change text in the textField the scroller object needs to be updated with new data.

Can aynone help me please!

Thx, Toni

tomfrederick
October 30th, 2007, 06:26 AM
Thanx for this code I m searching this code for more time

livingegg
October 30th, 2007, 07:26 PM
A scrollbar isn't nearly as much as people assume it to be. In fact a scrollbar can be broken down into a composite of a few simpler components.

Thanks a ton Michael. I found your post very useful to help me understand the bigger picture with how scrollbars work. The way you write your code looks just like mine - so i'm assuming your also a thinker who values clarity and grokking the bigger concepts before bothering with the details. Right on! :pope: Personally I would like to see a lot more material exactly as you have presented it - just the overview with a few code examples and not wasting too much time in the realm of details and functionality because that can always be worked on once you understand the bigger concepts.

As this was articulated very well and on simple terms I grasp everything except for the use of the Rectangle. Is it somehow acting as a mask? I have reviewed this a few times and played with the code a bit and I still don't understand whats going on here with the Rectangle at all.

I also have a bit of a repost from another thread that I was wondering if you have any insight on? :

I am writing a display engine that uses sprites nested recursively in order to position and display content. I tried to integrate a custom scrollbar into this by creating a mask of the desired size of my sprite containing content, and then using a scrollbar similar to yours to scroll the content sprite underneath the mask. That works fine, however when the content sprite takes on a larger height than its parent (even though it is masked) then its parent stretches, in turn stretching its parent, all the way up the tree breaking my relative positioning! Is there some way to prevent this from happening? Is there a way to prevent a parent Sprite from stretching when its child Sprite becomes larger than it is?

I do not want to have to resort to using the ScrollPane component but i'm afraid I might have to, because this seems to circumvent this problem. When I add a sprite as the .source property of the ScrollPane, that sprite is removed from its parent's display list and so it doesn't break the layout. However -- where does it go? I can not find what new display list it has been added to. Does anyone understand how the ScrollPane works in terms of the display list?

Thanks---

-egg

Graymalkin
October 31st, 2007, 06:36 AM
Very nice. Thanks a lot.

daidai
November 22nd, 2007, 10:14 PM
this is great, thanks
i was wondering if anyone knows how to add a bit of friction to the content scrolling, to give a smoother ride?

daidai
November 27th, 2007, 05:39 PM
also how would I implement a method to move the marker via the SliderEvent ?

g_wulfwud
December 18th, 2007, 12:25 AM
can you use this on a movie clip instead of a sprite?

overbyte
March 20th, 2008, 11:34 AM
this is great, thanks
i was wondering if anyone knows how to add a bit of friction to the content scrolling, to give a smoother ride?


i used Tweener to do this as you can tween variables using it
here's my amended code (Note i also change the direction from vertical to horizontal but i've marked out bits that are relevant for you:

package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import com.caurina.transitions.*; // <------you need this - note i added com but you'll have to use your path to the classes

public class Scrollbar extends Sprite
{
// elements
protected var slider:Slider;
protected var left_arrow:Sprite;
protected var right_arrow:Sprite;

protected var scrollSpeed:Number = .1;

// read/write percentage value relates directly to the slider
public function get percent():Number { return slider.percent; }
public function set percent( p:Number ):void { slider.percent = p; }

/**
* Constructor
*/
public function Scrollbar()
{
createElements();
}

// executes when the up arrow is pressed
protected function arrowPressed( e:MouseEvent ):void
{
var dir:int = (e.target == left_arrow) ? -1 : 1;
var total:Number = slider.percent + (dir * scrollSpeed);
Tweener.addTween(slider,{percent:total, time:0.5}); // Tweener tween added to make arrow presses a little smoother - God bless Zeh and chums!
//slider.percent = total; // <------delete or comment this out
}

/**
* Create and initialize the slider and arrow elements.
*/
protected function createElements():void
{
slider = new Slider();

left_arrow = new Sprite();
left_arrow.graphics.beginFill( 0x999999, 1 );
left_arrow.graphics.moveTo(20,0);
left_arrow.graphics.lineTo(20,40);
left_arrow.graphics.lineTo(10,40);
left_arrow.graphics.curveTo(0,40,0,30);
left_arrow.graphics.lineTo(0,10);
left_arrow.graphics.curveTo(0,0,10,0);
left_arrow.graphics.lineTo(20,0);
left_arrow.graphics.endFill();

right_arrow = new Sprite();
right_arrow.graphics.beginFill( 0x999999, 1 );
right_arrow.graphics.lineTo(10,0);
right_arrow.graphics.curveTo(20,0,20,10);
right_arrow.graphics.lineTo(20,30);
right_arrow.graphics.curveTo(20,40,10,40);
right_arrow.graphics.lineTo(0,40);
right_arrow.graphics.lineTo(0,0);
right_arrow.graphics.endFill();

slider.x = left_arrow.width;
right_arrow.x = slider.x + slider.width;

left_arrow.addEventListener( MouseEvent.MOUSE_DOWN, arrowPressed );
right_arrow.addEventListener( MouseEvent.MOUSE_DOWN, arrowPressed );

addChild( slider );
addChild( left_arrow );
addChild( right_arrow );
}

/**
* Override the add and remove event listeners, so that SliderEvent.CHANGE events will be
* subscribed to the Slider directly.
*
* There is issues with this however, Event.CHANGE events will get subscribed directly too Slider as well.
*/
public override function addEventListener( type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false ):void
{
if ( type === SliderEvent.CHANGE )
{
slider.addEventListener( SliderEvent.CHANGE, listener, useCapture, priority, useWeakReference );
return;
}
super.addEventListener( type, listener, useCapture, priority, useWeakReference );
}
public override function removeEventListener( type:String, listener:Function, useCapture:Boolean=false ):void
{
if ( type === SliderEvent.CHANGE )
{
slider.removeEventListener( SliderEvent.CHANGE, listener, useCapture );
return;
}
super.removeEventListener( type, listener, useCapture );
}
}
}you can get Tweener (http://code.google.com/p/tweener/) here. You just need to add it to your classpath (http://gotoandlearn.com/player.php?id=45)


can you use this on a movie clip instead of a sprite?
I would think so - movieclip is a descendant of sprite so it will have all of the same attributes and methods

best
obie

overbyte
March 20th, 2008, 12:34 PM
does anyone know how i would go about reparenting something in a sprite that was being scrolled using a SliderEvent? i'll post my code if you'd like

thanks
obie

overbyte
March 20th, 2008, 02:05 PM
also how would I implement a method to move the marker via the SliderEvent ?

you could probably set up a couple of invisible sprites over the scrolling movie and set them to be the same as the arrow presses

rdj
March 21st, 2008, 06:16 AM
is there any chance you could provide the fla's? I'm wouldn't have a clue on how to make any of these scripts work.

overbyte
March 21st, 2008, 04:17 PM
you need at least a cursory understanding of some flash actionscript 3 basics, like custom classes, the display list etc. to understand this thread

I would recommend essential actionscript 3 by colin moock - it will give you really good fundamentals as well as an in-depth understanding of the as3 works

overbyte
March 25th, 2008, 12:29 PM
i've made some additions to this class to let users click on the track to jump to a certain point (uses the Tweener (http://code.google.com/p/tweener/) class for friction)

enjoy



// new method
protected function trackPress( e:MouseEvent ):void
{
var msx:Number = e.target.mouseX;
var total:Number = msx / (track.width - marker.width/2);

Tweener.addTween(this,{percent:total, time: .5, transition:"easeInOutQuad"});
// Tweener friction - Note: event dispatched by the set() method so commented out here

//dispatchEvent( new SliderEvent( SliderEvent.CHANGE, percentage ) );
}

/**
* Creates and initializes the marker/track elements.
Amended method
*/
protected function createElements():void
{
track = new Sprite();
marker = new Sprite();

track.graphics.beginFill( 0xCCCCCC, 1 );
track.graphics.drawRect(0, 0, 10, 100);
track.graphics.endFill();

track.addEventListener( MouseEvent.MOUSE_DOWN, trackPress ); // new addition

marker.graphics.beginFill( 0x333333, 1 );
marker.graphics.drawRect(0, 0, 10, 15);
marker.graphics.endFill();

marker.addEventListener( MouseEvent.MOUSE_DOWN, markerPress );

addChild( track );
addChild( marker );
}

winterain
September 15th, 2008, 02:02 AM
hi,
Anyone experiencing immediate slowdown the moment you click/scroll on the scrollbar ?
I'm using the scrollbar class that MichaelxxOA wrote a while back.
The moment I click on the scrollbar or scroll with it, the frame rates of all the other animations running come to a crawl, and general response of the flash project comes to a crawl.

schedal
October 17th, 2008, 01:50 AM
Nice code, busy trying to integrate it all together, would have been nice if there was all the files, with adjustments, in one place, but oh well, thus is the copy-paste-amend life!

Overbyte: nice addition, I was wondering though if there would be an easy way to integrate into this code a way to have the scroll bar only move up and down one "page" when you click on the gap between the bar or when you click on the arrows. By a "page" I mean the size of the mask? Or in terms of this code: one unit of: content.scrollRect.height in the ScrollContent event/class.

schedal
October 17th, 2008, 02:01 AM
BTW, for this code to be truly modular and reusable, one should not be defining graphics inside of the slider and scrollbar... that should be passed to it from the respective constructor(s). If I can get a more generic version together, i will post it.

tspider
November 10th, 2008, 01:36 PM
Hello to all AS coders.. I have read all your posts, cause Im looking for some scrollbar that works with the keyboard too, with the up and down arrows, do anyone has something to do this..? im trying to modify the script but are not working for me.. please could you help me?
thank you for all!!

Tsp

skyblu263
November 20th, 2008, 04:13 PM
There is one tutorial on Kirupa and, though it technically works, the slider starts at the center of the track instead of the top. I also have another problem with it. Here is the ActionScript code I used. Can someone help me with why the sliders starts in the center of the track and why it skips parts of the list? Thanks

Sky

vols4ever
March 7th, 2009, 09:50 PM
Michael,

Thank you very much for the explanation and the code. This was exactly what I was looking for and your explanations helped me to understand the code so I could manipulate it. Keep up the good work.

Carvecy09
December 30th, 2009, 02:27 PM
Im currently using this code:HTMLEverbane (http://www.kirupa.com/forum/login.php)/HTMLBut on some pages I need users to be able to scroll down, and they cant. How do I go about making it so you can use scrollbars, or even better, scrollbars on specific pages only, without using iFrames. If its possible.Thank you

Urguzi
January 5th, 2010, 03:53 PM
I have some experience with classes, but I've lost my confidence right now.

"The main class that was used to test this follows (it's simple, you shouldn't have an issue understanding it)."

I just want to create a dynamic textfield with a slider, can someone please help me with that?

gertjanmeire
May 29th, 2011, 10:50 AM
I'm currently trying out this example and it works fine with movieclips or something.
But I have a class that loads in items from a DB with AMFPHP and when I try to put this content into this scrollbar it doesn't work like it's supposed to.

After experimenting with this a bit I realized that the scrollbar needs a height to scroll correctly. Problem is that my height isn't a constant... it changes according to the amount of items I get back from the DB.

Any way to solve this so it works with my project too?

My code so far:
Main class


package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.geom.Rectangle;

public class Main extends Sprite
{
private var data:Data;

public function Main()
{
//Maak de inhoud aan wat gescrolled moet worden
data = new Data();
//Voeg de scrollbar toe
var scrollbar:Scrollbar = new Scrollbar();

//Bepaal hoe groot het te scrollen gebied moet zijn
var rect:Rectangle = new Rectangle( 0, 0, data.width, 250 );
//Voeg de scrollcontent toe met de scrollbar
var sc:ScrollContent = new ScrollContent( data, scrollbar, rect );

//Bepaal de positie
scrollbar.x = data.width;

//Voeg de foto toe
addChild( data );
//voeg de scrollbar toe
addChild( scrollbar );

}
}
}


Data.as


package
{
import flash.display.Sprite;
import flash.net.NetConnection;
import flash.net.Responder;

public class Data extends Sprite
{
private var netConnection:NetConnection;
private var responder:Responder;
private var newsItem:NewsItem;
public function Data()
{
netConnection = new NetConnection();
netConnection.connect("http://localhost/amfphp/gateway.php");

responder = new Responder(resultHandler, faultHandler);

showNews();
}

/************************************************** ********************
resultHandler
* Vangt het result op dat PHP terug geeft
/************************************************** *******************/
private function resultHandler(e:Array):void{
trace("news result:");
trace(e);

var offsetY:Number = 30;
for each(var item:Object in e){
newsItem = new NewsItem(item.title, item.content, item.category);
newsItem.x = 0;
newsItem.y = offsetY;
addChild(newsItem);
offsetY += newsItem.height + 10;
}
}

/************************************************** ********************
faultHandler
* Vangt eventuele fouten op die PHP terug geeft
/************************************************** *******************/
private function faultHandler(e:Object):void{
trace(e.description);
}

/************************************************** ********************
showNews
* Roep de PHP functie getNewsContent op om het nieuws uit de DB te halen
/************************************************** *******************/
private function showNews():void{
trace("Showing the news");
netConnection.call("CasinoService.getNewsContent", responder);
}
}
}