I was asked this morning about the Button component in MX2004 / F8 as a friend of mine wanted to do some tooltip popups on rolling over the component – Unfortunately the Button component only dispatches a few events by default – I’m excluding all the UIObject class ones like load, hide, draw etc from this train of thought.
So for interacting with the Button component we have these:
- click – the commonest of the events
- focusIn – pretty much th same as click
- focusOut – if you click outside the component
- keyDown – Well, click, but with the keyboard :S
- keyUp – similar to focusOut, as it triggers when the button loses state
So back to this issue of rollOver events. There is a class in the mx.events called LowLevelEvents, but this doesn’t really apply in this instance as that is more ‘useable’ when actually applied inside a component / presentation orientated class – So that leaves extending the Button class…Or does it.
Now extending it is an obvious process to take, but seems a bit overkill for the sake of a few low level events to be broadcast, let me explain why – In SimpleButton.as, from which the Button component is extended, are all the onPress, onRelease etc handlers that we are all aware of from Flash of old. However through oversight these have been commented up as private methods, but are in actual fact public. So if I or any other developer wished to short cut the Button component to add a rollOver to the actual Button component instance they could, see below.
// myBtn being a Button component. myBtn.onRollOver = function() { dispatchEvent({type:'rollOver'}); } |
OK so it’s not elegant, but the real issue here is that it breaks the Button component as this method is ‘defined’ as a private method in the Simple Button class from which it inherits – by defined I mean there is a comment that says it’s private :P. So how does it break the Button component? Well the onXXX methods are used to update the skins and refresh the component so it changes visually for the user. If you use the above code it will dispatch a ‘rollOver’ event but it’s overridden the SimpleButton method so the skin isn’t updated nor refreshed.
If the method was ACTUALLY private then you wouldn’t be able to access it as is illustrated by the above example because it would throw a compile time error, let alone override it to boot.
Now if you REALLY REALLY have to do it like the above example you can fix it by adding the super() to the method like this:
// myBtn being a Button component. myBtn.onRollOver = function() { super.onRollOver(); dispatchEvent({type:'rollOver'}); } |
But if you came across that in an FLA I’m sure you’d have to ask yourself why – let alone developers that may not be upto speed and think there is nothing wrong doing it this way.
Far simpler would be to extend the Button component and be done with it (see below) – but it can appear as overkill for just a few extra lines for functionality that in my mind should have been there to begin with in – though not necessarily via the methods that are in place currently.
import mx.controls.Button; class com.flashgen.components.FGButton extends Button { private static var symbolName:String = "FGButton"; private static var symbolOwner = FGButton; private var className:String = "FGButton"; public function FGButton() { super(); } function onRollOver() { super.onRollOver(); disptachEvent({type:'rollOver'}); } } |
Obviously this is cleaner, but still doesn’t fix the fact that this should be private, but as the parents method isn’t then neither can this – unless you want the compiler to squeak and grunt as you try and export it :P
As a side note both the SimpleButton class in AS3 and the Button component in Flex2 both support all the mouse based events so it wouldn’t require any extension / hacking to get the same results. Flex 1.5 had it also, as well as a built in tooltip property…but thats a different topic :P
Note this was first posted to the FlashComponent-L mailing list 11/26/2005
Great – thanks very much for this. Was fiddling around for ages trying to get a hover-over effect from a standard Flash button. Really annoying that they’d missed out the rollover function. Great to see that they didn’t really miss it out. Thanks!
nice nice nice. That helped me out loads, I have blogged this entry to spread the word! Thanks a million.
Sorry, but I need some implementation details. creating a FGButton instance with:
import mypackage.components.FGButton;
myButton = paneContent.createClassObject(FGButton, “myButton”, paneContent.getNextHighestDepth());
doesn’t show a button on the stage whereas createClassObject(Button, .. runs fine
Do I have to create a FGButton component?
Stefan, not sure if you’re subscribed to this post. However I have sent you an MXP with the component, class file and a simple sample file. Hope that helps
regs
FG
Hi – i found this a very useful post – thank you.
I was trying to apply this technique to the ComboBox, but I don’t seem to be able to get it to work. Whatever I do to enable the onRollOver event dispatch seems to disable the ComboBox functionality. Any ideas? Thanks!
Chad
Appreciated because you share your ideas. But, you have mistaken in your article when you said, “If the method was ACTUALLY private then you wouldn’t be able to access it as is illustrated by the above example because it would throw a compile time error, let alone override it to boot.” You are not overriding onRollOver at all by using dispatch method within the body of the onRollOver callback function. All you did was implementing the callback function.
Ozgur Uksal