Determining a Flex event's default behavior - apache-flex

How can I tell what the default behavior for a cancelable event is?
For example, I read somewhere that the TextEvent.TEXT_INPUT has a default behavior and that default behavior includes adding a text character associated with the key that was pressed to a TextInput. That makes perfect sense.
But if I hadn't read that, how would I know what the default behavior is? Other than guessing. In this case, it's probably obvious. But in other situations, it might not be.
For example, in the docs, look at DataGridEvent.HEADER_RELEASE's cancelable property. It says:
cancelable: true
so, there appears to be a "default behavior" associated with a DataGridEvent.HEADER_RELEASE event. But what is it? And why would I cancel it if I'm not really sure what it is? :)
thanks.

It's all in the documentation, which says: "The DataGrid control has a default handler for this event that implements a single-column sort."
The live docs a pretty thorough. If you keep following the links you'll usually find what you are looking for.

Here's what I think to be true -
To cancel the default behavior associated with an event, 2 things must be true:
The event must be marked as cancelable (you can check the event's cancelable property to determine this). If you are dispatching the event yourself, set the 3rd parameter to true to mark the event as cancelable. If the event is marked as cancelable, calling event.preventDefault() will set the event to "cancelled" and a query of event.isDefaultPrevented() will return true. If the event is NOT marked as cancelable, calling event.preventDefault() will do nothing at all. A query of event.isDefaultPrevented() will always return false no matter how many times you call event.preventDefault().
The event handler registered for the event must actually have the ability to do nothing (i.e. prevent the default behavior associated with the event). So the handler must have something like this in it:
if (!event.isDefaultPrevented()) { doSomething(); }
So, that still leaves me with the question - "For a cancelable event of type X, what is the default behavior?"
I guess that depends on the target of the event. For example, the target of a DataGridEvent.HEADER_RELEASE event is a DataGrid and inside the DataGrid class you'll find this in the constructor:
addEventListener(DataGridEvent.HEADER_RELEASE,
headerReleaseHandler,
false, EventPriority.DEFAULT_HANDLER);
and the handler looks like this:
private function headerReleaseHandler(event:DataGridEvent):void
{
if (!event.isDefaultPrevented())
{
manualSort = true;
sortByColumn(event.columnIndex);
manualSort = false;
}
}
Or, you can poke around aimlessly in the docs forever and maybe stumble on the answer like this:
http://livedocs.adobe.com/flex/3/langref/mx/controls/DataGrid.html#event%3aheaderRelease
"The DataGrid control has a default handler for this event that implements a single-column sort"
Hopefully, this answer helps reduce the aimlessness of your doc search.
Jeremy

Related

Event propagation in Qt

I've just the documentation on the Qt event system and the QEvent class. I'm interested in the behavior of the QObject::event() method. The documentation states:
This virtual function receives events to an object and should return true if the event e was recognized and processed.
What is the expected behavior when false is returned from the event() method? What else is attempted in order to handle the event? Is the event automatically forwarded to the parent object?
Note: I know the source is available, and I do have a copy. I'm ideally looking for some piece of documentation addressing this behavior.
I believe the best practice is to explicitly forward the events to the base-class event method if you do not wish to filter that event type (e.g. return QObject::event(event);) since the event function delegates events to specific handlers (e.g. QWidget::keyPressEvent).
QCoreApplication::notify propogates events based on the return value. On true, it considers the event as consumed and stops. Otherwise, the event is passed to the object's parent. For more information, see Events and Filters and Another Look at Events.
Some Events can be propagated.Event will be propagated to it's parent and it's parent recursively until it is processed. Take a look at this:https://doc.qt.io/archives/qq/qq11-events.html

AIR Application enabled=false not processed (Busyindicator)

In my AIR application (with mate-Framework) i did follwing things:
click on a button
call a method in my model "onApplicationBusy"
apply some filter in arraycollections.
In my onApplicationBusy there is this code:
FlexGlobals.topLevelApplication.enabled = false;
FlexGlobals.topLevelApplication.
I trace every step and all methods are called in right order.
But my application never becomes disabled.
Why. Is there a method for this purpose.
I try InvalidateDisplayList or ValidateNow or callLater. But all tries won't work. Probably i try it on the wrong place?
I assume, my application is so busy while applying filters (4 values for 10.000 lines) that the disabled property can't processed.
If i call the method without applying the filters all works fine.
If i call just the disbaled property but never enable the app again, the app will shown as disabled after applying the filters. for me too late.
What i origin want is a clear behavior, when the app is busy and when not (ready for clicking on buttons and all this stuff).
If you can help me or know a method, how can i shown a busy application, please help me
Thanks
Frank
All right, the setTimeout Method solve my issue. I assume, I have to wait for the next screen refresh.
Why callLater won't work and when i have to implement those functions, because i have too less ressources while my filterFunction is running?
Frank
I'm using FlexGlobals.topLevelApplication.stage.mouseChildren = false | true;
Worth noting that I first tried setting the mouseEnabled flag but found various visual elements would not update at all while mouseEnabled = false.

What can cause event-handling closures to stop working?

I'll try to be as concise as possible. I have a number of objects in an array, and I'm applying event listeners to each one using closures:
//reduced to the logic in question:
buttons.forEach(function(button:EventDispatcher, i:int, list:Array):void {
button.addEventListener(MouseEvent.MOUSE_OVER, function(e:Event):void {
button.filters = [button_glow_filter];
});
});
//button-specific click handlers:
buttons[0].addEventListener(MouseEvent.MOUSE_CLICK, handle_some_action);
This works perfectly for a while, until I perform an unrelated action on the UI. It's a very complex system, so I'm not really sure what is happening. I can confirm that the unrelated action has no direct effect on the object that contains the buttons or the buttons themselves (at least, it's not changing anything via the public interfaces). The buttons still exist, and the click event listeners still work correctly because those are individually assigned real functions on the class's interface.
My question therefore is: does anyone know what can cause these closures to stop handling the MouseOver events without having any other perceptible effect on the related objects?
There are a number of ways to accomplish this MouseOver behavior, and for now I've switched to one that works, but I'd still like to know the answer to this question for future reference.
I figured out the likely culprit almost immediately after posting: garbage collection. It took just a couple of minutes to confirm. This is exactly what the useWeakReference parameter is for in the addEventListener interface; it defaults to true. By setting it to false, it prevents listeners assigned in this fashion from being garbage collected.
The correct code is:
buttons.forEach(function(button:EventDispatcher, i:int, list:Array):void {
button.addEventListener(MouseEvent.MOUSE_OVER, function(e:Event):void {
button.filters = [button_glow_filter];
}, false, 0, false);
});

Should one remove an anonymous event listener for an HTTPService() object?

I have an httpservice object instantiated and have defined an event listener to handle the result.
e.g.
http.addEventListener(ResultEvent.RESULT,function (event:ResultEvent):void {
// handle result
// ...
//should I remove this anonymous event listener?:
event.currentTarget.removeEventListener(event.type, arguments.callee);
});
I'm only curious from an efficiency/best practice point of view.
Depends if you're going to reuse it, and/or if you need closure variables from the current scope. If there's no reuse, then data-hiding might suggest making it local or at least private. If it's something that's going to be reused, or something that might even be overridden by a subclass, then make it separate and protected.
My 2 cents.
Update:
Whoops, I thought the question was whether the listener should be anonymous or not.
You should definitely remove any listener, anonymous or not, if it's no longer needed. Otherwise, it's useless cpu usage if the event keeps firing.

stack overflow on XMLListCollection collectionEvent

I'm working on a Flex 3 project, and I'm using a pair of XMLListCollection(s) to manage a combobox and a data grid.
The combobox piece is working perfectly. The XMLListCollection for this is static. The user picks an item, and, on "change", it fires off an addItem() to the second collection. The second collection's datagrid then displays the updated list, and all is well.
The datagrid, however, is editable. A further complication is that I have another event handler bound to the second XMLLIstCollection's "change" event, and in that handler, I do make additional changes to the second list. This essentially causes an infinite loop (a stack overflow :D ), of the second lists "change" handler.
I'm not really sure how to handle this. Searching has brought up an idea or two regarding AutoUpdate functionality, but I wasn't able to get much out of them. In particular, the behavior persists, executing the 'updates' as soon as I re-enable, so I imagine I may be doing it wrong. I want the update to run, in general, just not DURING that code block.
Thanks for your help!
Trying to bind the behaviour to a custom event rather than the CHANGE event.
I.e. do what you are doing now, but dispatch and handle a custom event to do the work.
Have you considered using callLater?
Does direct manipulation of XMLListCollection's source XMLList have the same results?
Have you considered something like:
private function changeHandler( event:Event ):void
{
event.target.removeEventListener( event.type, changeHandler );
// your code here.
event.target.addEventListener( event.type, changeHandler );
}

Resources